ATL implementation of a simple way for Connection Point

zhaozj2021-02-17  49

Hello everyone! A few days ago, I just arrived at a new company. I am involved in the system based on the development of COM components. Among them, a large number of Connection Point methods are used, which is forced to have helpless. I have to hold a Buddha's foot. After a period of study, I finally have it. Some experiences come to share with you, you are knew.

Let us use example to explain:

COM server:

1. Create a COM object CA implementation IA interface, using the wizard to implement this step.

2. Add the definition of the IEvent interface and declare it as an external interface of COM object A (Outgoing Interface)

// 9cbs.idl: idl source for 9cbs.dll //

// this file will be processed by the mid o t / p d t e l..

import "oaidl.idl"; import "ocidl.idl"; [object, uuid (2EE8F461-7200-4C13-A2FC-2552F8773089), dual, helpstring ( "IA Interface"), pointer_default (unique)] interface IA: IDispatch {

[ID (1), Helpstring ("Method Init")] HRESULT INIT ();

[Object, UUID (C5C88155-7CAB-4109-9610-234A6AD529DC), Dual, Helpstring ("Ievent Interface"), Pointer_Default (unique)]

Interface Ievent: IUNKNOWN {[ID (1), Helpstring ("Method OnDataChanged")] HRESULT ONDATACHANGED ();

[UUID (477B6435-238C-43AF-95DA-2F890256DF43), Version (1.0), Helpstring ("9CBS 1.0 Type Library"] library 9cbslib {importlib ("stdole32.tlb"); importlib ("stdole2.tlb");

[UUID (1FB2F1E-E12E-4CE6-88EA-704E1CAE1091), Helpstring ("a class")] coclass a {[default] interface IA; [Source] interface ievent;};}; // end

Among them, red code is manually added. IEVENT UUID generates. Ievent Add method onDatachanged. Add function code when the client calls, we will call its method in the IEvent's init method. Here is the essence of Connection Point. The implementation method of events in ActiveX is also based on this technology.

3. After the compiler, click COM object IMPLEMENT Connection Point ... option, select IEvent. The ATL Wizard will generate a new COM object CA for our new implementation.

class ATL_NO_VTABLE CA:. public CComObjectRootEx , public CComCoClass , public IDispatchImpl , public CProxyIEvent , public IConnectionPointContainerImpl 4 implemented Init method IA interface

STDMETHODIMP CA :: Init () {AFX_Manage_State (AFXGetStaticModuleState ())

Fire_ondatachanged ();

Return S_OK;

After the compiler, the COM server is written.

COM client implementation:

1. Realize the receiver class

File: //event.h

class CEvent: public IEvent {public: // IUnknown ULONG __stdcall AddRef (); ULONG __stdcall Release (); HRESULT __stdcall QueryInterface (REFIID iid, void ** ppv); // IEventpublic: STDMETHOD (OnDataChanged) (); public: CEvent (): m_cref (0) {} Virtual ~ CEVENT () {} private: long m_cref;}; // end

//Event.cpp

Ulong CEVENT :: AddRef ()

{Return InterlockedIncrement (& M_CREF);

Ulong cevent :: release () {if (IF (& M_CREF)! = 0) Return M_Cref; delete this; return 0;

HRESULT CEVENTERFACE (RIID RIID, VOID ** PPV) {if (riid == IID_IUNKNOWN) {* ppv = (iUnknown *) THIS;} else if (riid == iid_ievent) {* ppv = (ievent *) this } Else {* ppv = null; returnif (); return s_ok;}

STDMETHODIMP CEVENT :: ONDATACHANGED () {AFXMESSAGEBOX (_T ("OnDatachanged!")); Return S_OK;

// end

The implementation added to CEVENT :: ONDATACHANGED () will call up the init method of the interface IA.

2. Client implementation code

Void c9cbsclientdlg :: Onbutton1 ()

{

Coinitialize (NULL);

IA * PIA = NULL; CEVENT * PEVENT = NULL; HRESULT HR = CoCreateInstance (CLSID_A, NULL, CLSCTX_INPROC_SERVER, IID_IA, (Void **) & PIA);

IF (FAILED (HR)) {AFXMessageBox ("Initalize COM FAILED!"); Return;} // IF

IConnectionPointContainer * PConnectionPointContainer = null; iconnectionPoint * PConnectionPoint = NULL; pevent = new cevent (); pevent-> addref ();

DWORD DWCOOKIE;

HR = PIA-> queryinterface (IID_ICONNECTIONPOINTCONTAINER, (Void **) & pConnectionPointContainer); // IRecord-> release (); assert (ac));

HR = PConnectionPointContainer-> FindConnectionPoint (IID_IEVENT, & PCONNECTIONPOINT);

Assert (ac)); connectionpoint-> advise ((iUnknown *); PConnectionPoint-> Release ();

HR = PIA-> init (); // will stimulate the event onDataChanged () here

Assert (ac));

HR = PConnectionPointContainer-> FindConnectionPoint (IID_IEVENT, & PCONNECTIONPOINT);

Assert (aconneded (hr)); pConnectionPoint-> Unadvise (dwcookie); PConnectionPoint-> Release ();

PCONNECTIONPOINTCONTAINER-> Release (); PIA-> Release ();

PEVENT-> Release (); // delete pevent;

Couninitialize ();

// end

Writing is not good, forgive me!

The above code is debugged in VC 6.0.

2001.8.23

转载请注明原文地址:https://www.9cbs.com/read-28842.html

New Post(0)