我更进一步,因为在使用 COM 互操作将 .NET 控件公开为 ActiveX 时,手动连接事件时遇到了同样的问题。
如果您使用 Reflector(例如 Redgate Reflector)深入了解 UserControl 类,您会看到一个“ActiveXImpl”嵌套类成员,其中包含另一个名为“AdviseHelper”的嵌套静态类,它具有成员 ComConnectionPointContainer 和 ComConnectionPoint。它还具有根据需要连接点的辅助功能。
有问题。当 COM 互操作将事件从控件(事件源)连接到连接点容器(其中包含控件事件的事件接收器)时,将调用 IQuickActivate.QuickActivate 函数,然后调用 AdviseHelper 类''AdviseConnectionPoint ' 功能。
一个指向事件接收器的 IUnknown 接口指针,在您的客户端(即不是您的控件,包含它的东西)被传递给这个 QuickActivate 函数(参数'pUnkEventSink'。在反射器中,这个函数看起来像这样,我已经突出显示它的位置做实际的事件连接:
internal void QuickActivate(UnsafeNativeMethods.tagQACONTAINER pQaContainer, UnsafeNativeMethods.tagQACONTROL pQaControl)
{
int num;
this.LookupAmbient(-701).Value = ColorTranslator.FromOle((int) pQaContainer.colorBack);
this.LookupAmbient(-704).Value = ColorTranslator.FromOle((int) pQaContainer.colorFore);
if (pQaContainer.pFont != null)
{
Control.AmbientProperty ambient = this.LookupAmbient(-703);
IntSecurity.UnmanagedCode.Assert();
try
{
Font font2 = Font.FromHfont(((UnsafeNativeMethods.IFont) pQaContainer.pFont).GetHFont());
ambient.Value = font2;
}
catch (Exception exception)
{
if (ClientUtils.IsSecurityOrCriticalException(exception))
{
throw;
}
ambient.Value = null;
}
finally
{
CodeAccessPermission.RevertAssert();
}
}
pQaControl.cbSize = UnsafeNativeMethods.SizeOf(typeof(UnsafeNativeMethods.tagQACONTROL));
this.SetClientSite(pQaContainer.pClientSite);
if (pQaContainer.pAdviseSink != null)
{
this.SetAdvise(1, 0, (IAdviseSink) pQaContainer.pAdviseSink);
}
IntSecurity.UnmanagedCode.Assert();
try
{
((UnsafeNativeMethods.IOleObject) this.control).GetMiscStatus(1, out num);
}
finally
{
CodeAccessPermission.RevertAssert();
}
pQaControl.dwMiscStatus = num;
if ((pQaContainer.pUnkEventSink != null) && (this.control is UserControl))
{
Type defaultEventsInterface = GetDefaultEventsInterface(this.control.GetType());
if (defaultEventsInterface != null)
{
IntSecurity.UnmanagedCode.Assert();
try
{
**AdviseHelper.AdviseConnectionPoint(this.control, pQaContainer.pUnkEventSink, defaultEventsInterface, out pQaControl.dwEventCookie);**
}
catch (Exception exception2)
{
if (ClientUtils.IsSecurityOrCriticalException(exception2))
{
throw;
}
}
finally
{
CodeAccessPermission.RevertAssert();
}
}
}
if ((pQaContainer.pPropertyNotifySink != null) && UnsafeNativeMethods.IsComObject(pQaContainer.pPropertyNotifySink))
{
UnsafeNativeMethods.ReleaseComObject(pQaContainer.pPropertyNotifySink);
}
if ((pQaContainer.pUnkEventSink != null) && UnsafeNativeMethods.IsComObject(pQaContainer.pUnkEventSink))
{
UnsafeNativeMethods.ReleaseComObject(pQaContainer.pUnkEventSink);
}
}
'pUnkEventSink' 变量通过 tagQACONTROL 结构传递给此函数,但正如您所见,与 IAdviseSink、控件容器、字体样式等不同,此变量未设置为 'ActiveXImpl' 类的任何成员,并且因此,在框架最初调用此函数后,您将无法访问它。
您需要获取此 IUnknown pUnkEventSink 变量来调用 AdviseHelper.AdviseConnectionPoint() 函数,该函数将执行手动事件连接。这就是我遇到的问题 - 遗憾的是,您似乎根本无法掌握它。
任何其他人对此有任何进一步的发展,请告诉我!