2008-10-04 7 views
0

Environnement: VS2008 (ATL), Borland Developer Studio 2006.Événements ActiveX entre appartements

Bonjour à tous. Je rencontre des problèmes avec les événements de contrôle ActiveX.

Voici une brève description de mon architecture app:

Il y a un serveur COM inproc qui contient le contrôle ActiveX STA (aka contrôle) et de l'objet COM MTA (alias objet).

Voici la définition IDL des interfaces de contrôle et objet:

[ 
    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; 
    }; 
}; 

client est une application Delphi avec un contrôle ActiveX sur la forme qui crée un objet MTA et appelle sa méthode DoWork

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

Cette méthode appelle directement la méthode Fire_SomeEvent du contrôle ActiveX coclass et transmet 'this' comme paramètre (pointeur vers l'interface IObject). Le code Delphi reçoit avec succès l'événement mais quand il essaie d'accéder à n'importe quelle méthode ou propriété IObject (non montré dans idl pour la simplicité) alors la violation d'accès s'est produite dans oleaut32.dll.

Une remarque importante - J'utilise la classe ATLCPImplMT pour implémenter le déclenchement d'événement à partir de différents threads (voir http://support.microsoft.com/kb/280512 pour plus de détails). Cette implémentation permet de basculer des appartements lorsque l'événement se déclenche (de l'appartement MTA de l'objet à l'appartement STA Delphi). Je suggère que ce problème est lié au marshaling de paramètre d'événement incorrect parce que lorsque la classe ATLCPImpl standard est utilisée, tout fonctionne correctement.

Existe-t-il des restrictions pour les événements inter-appartements? Peut-être qu'une configuration spéciale de l'environnement Delphi est nécessaire pour travailler correctement avec les objets ActiveX ...

Répondre

1

Accédez-vous aux objets créés dans le même thread que le gestionnaire d'événements ou bien l'objet COM a-t-il été créé dans le thread principal? Si vous n'êtes pas dans le même contexte de thread dans le gestionnaire d'événement que le thread qui a créé l'objet, vous pouvez obtenir des violations d'accès lorsque vous essayez d'accéder à l'objet COM. Une solution de contournement rapide peut consister à envoyer un message au thread principal à partir du gestionnaire d'événements, et le thread principal accéder à l'objet COM dans le contexte de thread principal, au lieu de directement dans le gestionnaire d'événements COM.

Threads et COM n'est pas moins compliqué que les threads sans COM.

Questions connexes