0

環境: VS2008 (ATL)、Borland Developer Studio 2006。

皆さんこんにちは。ActiveX コントロール イベントに問題があります。

私のアプリのアーキテクチャの簡単な説明は次のとおりです。

STA ActiveX コントロール (別名コントロール) と MTA COM オブジェクト (別名オブジェクト) を含むインプロセス COM サーバーがあります。

以下は、コントロールおよびオブジェクト インターフェイスの IDL 定義です。

[
    object,
    uuid(2338CCAF-BBAF-4E29-929B-A67285B1E772),
    dual,
    nonextensible,
    pointer_default(unique)
]
interface IObject : IDispatch{
    [id(1)] HRESULT DoWork(void);
};

[
    object,
    uuid(1A0A1DA2-E33B-4DF4-99A9-9EAEF2281E7D),
    dual,
    nonextensible,
    pointer_default(unique)
]
interface IControl : IDispatch{
};


[
    uuid(BC27FABD-2794-4F9C-B3BD-C0C0628741FA),
    version(1.0),
    helpstring("AVRep 1.0 Type Library")
]

library ActiveXLib
{
    importlib("stdole2.tlb");
    [
        uuid(4B5575A7-E0FF-49B5-AE10-0D980CF49EB3)
    ]
    dispinterface _IControlEvents
    {
        properties:
        methods:
            [id(1)] HRESULT SomeEvent([in] IObject* obj);
        };
    [
        uuid(7C44F19E-6B71-434B-96F6-E29A3C66C794),
        control
    ]
    coclass Control
    {
        [default] interface IControl;
        [default, source] dispinterface _IControlEvents;
    };
    [
        uuid(17BDFAC0-DF21-4474-BCFF-846FE0075D68)
    ]
    coclass Object
    {
        [default] interface IObject;
    };
};

クライアントは、MTA オブジェクトを作成し、その DoWork メソッドを呼び出すフォーム上に ActiveX コントロールを備えた Delphi アプリケーションです。

var
  mta : IObject;
begin
  mta := CreateOleObject('ActiveXLib.Object.1') as IObject;
  mta.DoWork();
end;

このメソッドは、ActiveX コントロール コクラスの Fire_SomeEvent メソッドを直接呼び出し、「this」をパラメーター (IObject インターフェイスへのポインター) として渡します。Delphi コードはイベントを正常に受信しますが、IObject のメソッドまたはプロパティ(わかりやすくするために idl には示されていません)にアクセスしようとすると、oleaut32.dll でアクセス違反が発生します。

1 つの重要な注意事項 - ATLCPImplMT クラスを使用して、さまざまなスレッドから発生するイベントを実装します (詳細については、 http://support.microsoft.com/kb/280512を参照してください)。この実装により、イベントが発生したときにアパートメントを切り替えることができます (オブジェクトの MTA アパートメントから STA Delphi フォーム アパートメントへ)。標準の ATLCPImpl クラスを使用するとすべて正常に動作するため、この問題は不適切なイベント パラメータのマーシャリングに関連していると考えられます。

マンションをまたぐイベントに制限はありますか?おそらく、activex オブジェクトを正しく操作するには、特別な Delphi 環境のセットアップが必要です...

4

1 に答える 1

1

イベント ハンドラーと同じスレッドで作成されたオブジェクトにアクセスしていますか、それともメイン スレッドで作成された COM オブジェクトですか? オブジェクトを作成したスレッドと同じイベント ハンドラーのスレッド コンテキストにいない場合、COM オブジェクトにアクセスしようとすると、アクセス違反が発生することがあります。

簡単な回避策として、イベント ハンドラーからメイン スレッドにメッセージをポストし、メイン スレッドが COM イベント ハンドラーで直接ではなく、メイン スレッド コンテキストで COM オブジェクトにアクセスするようにすることができます。

スレッドと COM は、COM を使用しないスレッドほど複雑ではありません。

于 2008-10-07T19:11:34.943 に答える