环境: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 对象......