0

环境:VS2008 (ATL),Borland Developer Studio 2006。

大家好。我在处理 ActiveX 控件事件时遇到了一些问题。

以下是我的应用架构的简要说明:

有一个包含 STA ActiveX 控件(又名控件)和 MTA COM 对象(又名对象)的 inproc 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;
    };
};

客户端是一个 Delphi 应用程序,窗体上带有 ActiveX 控件,它创建 MTA 对象并调用其 DoWork 方法

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

此方法直接调用 ActiveX 控件类的 Fire_SomeEvent 方法,并将“this”作为参数传递(指向 IObject 接口的指针)。Delphi 代码成功接收事件,但是当它尝试访问任何 IObject 方法或属性(为简单起见未在 idl 中显示)时,在 oleaut32.dll 中发生访问冲突。

一个重要的注意事项 - 我使用 ATLCPImplMT 类来实现从不同线程触发的事件(有关详细信息,请参阅http://support.microsoft.com/kb/280512)。此实现允许在事件触发时切换公寓(从对象的 MTA 公寓到 STA Delphi 形式的公寓)。我建议这个问题与不正确的事件参数封送处理有关,因为当使用标准 ATLCPImpl 类时一切正常。

跨公寓活动是否有任何限制?也许需要一些特殊的 Delphi 环境设置才能正确使用 activex 对象......

4

1 回答 1

1

您是在访问与事件处理程序在同一线程中创建的对象,还是在主线程中创建的 COM 对象?如果您在事件处理程序中与创建对象的线程不在同一个线程上下文中,则当您尝试访问 COM 对象时可能会遇到访问冲突。

一个快速修复解决方法可以是从事件处理程序向主线程发布消息,并让主线程在主线程上下文中访问 COM 对象,而不是直接在 COM 事件处理程序中访问。

线程和 COM 并不比没有 COM 的线程复杂。

于 2008-10-07T19:11:34.943 回答