Je suis allé un peu plus loin, car j'ai eu le même problème en connectant manuellement les événements lors de l'exposition d'un contrôle .NET en tant qu'ActiveX en utilisant COM interop. Si vous creusez un peu dans la classe UserControl en utilisant Reflector (par exemple Redgate Reflector), vous verrez un membre de classe imbriqué 'ActiveXImpl', qui contient une autre classe statique imbriquée appelée 'AdviseHelper', qui a les membres ComConnectionPointContainer et ComConnectionPoint . Il a également des fonctions auxiliaires pour connecter les points selon vos besoins.
Il y a un problème. Lorsqu'un événement est connecté par COM interop depuis votre contrôle (la source de l'événement) vers le conteneur du point de connexion (qui contient le récepteur d'événements pour les événements de votre contrôle), l'IQuickActivate.La fonction QuickActivate est appelée, qui appelle la fonction AdviseConnectionPoint de la classe AdviseHelper. Un pointeur d'interface IUnknown vers le collecteur d'événements sur votre client (c'est-à-dire pas votre contrôle, l'objet qui le contient) est passé à cette fonction QuickActivate (paramètre 'pUnkEventSink') Dans le réflecteur, cette fonction ressemble à ceci. avons mis en évidence où il fait l'événement réel raccordement:
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);
}
}
la variable « pUnkEventSink » est passée à cette fonction via la structure de tagQACONTROL, mais comme vous pouvez le voir, à la différence du IAdviseSink, conteneur de contrôle, style de police, etc. , cette variable n'est définie sur aucun membre de la classe 'ActiveXImpl' et, par conséquent, vous ne pouvez pas y accéder après que cette fonction a été initialement appelée par le framework
Vous devez obtenir cette variable IUnknown pUnkEventSink pour appeler la fonction AdviseHelper.AdviseConnectionPoint(), qui effectuera le branchement d'événement manuel. Et c'est le problème que j'ai eu - malheureusement, vous ne pouvez tout simplement pas le saisir.
Quelqu'un d'autre a eu d'autres développements avec ce faire le moi savoir!