Essential COM

5, , , , . , , , .

, , . , :

 [uuid(75DA6457-DD0F-11d0-8C58-0080C73925BA),object] interface IProgrammer : IUnknown {   HRESULT StartHacking(void);   HRESULT IsProductDone([out, retval] BOOL *pbIsDone); } 

:

 HRESULT ShipSoftware(void) {     IProgrammer *pp = 0;     HRESULT hr = CoGetObject(OLESTR("programmer:Bob"), 0,                              IID_IProgrammer, (void**)&pp);     if (SUCCEEDED(hr)) {         hr = pp->StartHacking();         BOOL bIsDone = FALSE;         while (!bIsDone && SUCCEEDED(hr)) {             Sleep(15000);              // wait 15 seconds              //   15              hr = pp->IsProductDone(&bIsDone);              // check status              //            }         pp->Release();     } } 

, , 15 . : , - (programmer object) , . , , - :

 [uuid(75DA6458-DD9F-11d0-8C58-0080C73925BA),object] interface ISoftwareConsumer : IUnknown {   HRESULT OnProductIsDone(void);   HRESULT OnProductWillBeLate([in] hyper nMonths); } 

- , ISoftwareConsumer, - . IProgrammer , , - (consumer object). Advise:

 interface IProgrammer : IUnknown {   HRESULT Advise ([in] ISoftwareConsumer *psc, [out] DWORD *pdwCookie);   :   :   : 

- , DWORD . DWORD Unadvise:

 interface IProgrammer : IUnknown {   :   :   :   HRESULT Unadvise([in] DWORD dwCookie); } 

, - . DWORD - .

IProgrammer, - Advise

 STDMETHODIMP Programmer::Advise(ISoftwareConsumer *pcs, DWORD *pdwCookie) {     assert(pcs);     if (m_pConsumer != 0) // is there already a consumer?                           //      ?         return E_UNEXPECTED;     (m_pConsumer = pcs)->AddRef();         // hold onto new consumer         //            *pdwCookie = DWORD(pcs);         // make up a reasonable cookie         //          return S_OK; } 

Unadvise :

 STDMETHODIMP Programmer::Unadvise(DWORD dwCookie) {       // does the cookie correspond to the current consumer?       //          ?     if (DWORD(m_pConsumer) != dwCookie)         return E_UNEXPECTED;     (m_pConsumer)->Release();         // release current consumer         //          m_pConsumer = 0;     return S_OK; } 

. 7.7. , , , ISoftwareConsumer.

 . 7.7.

, StartHacking :

 STDMETHODIMP Programmer::StartHacking (void) {     assert(m_pConsumer);       // preemptively notify of lateness       //            HRESULT hr = m_Consumer->OnProductWillBeLate(3);     if (FAILED(hr))         return PROGRAMMER_E_UNREALISTICCONSUMER;       // generate some code       //          extern char *g_rgpszTopFiftyStatements[];     for (int n = 0; n < 100000; n++)         printf(g_rgpszTopFiftyStatements[rand() % 50]);       // inform consumer of done-ness       //            hr = m_pConsumer->OnProductIsDone();     return S_OK; } 

To , ISoftwareConsumer , - , . StartHacking , - , , , , . - , - - . , Unadvise, .

IProgrammer ISoftwareConsumer, , , IProgrammer - . , - , IProgrammer IProgrammer. , , , , . :

 [uuid(75DA645D-DD0F-11d0-8C58-0080C73925BA),object ] interface IShutdownNotify : IUnknown {   HRESULT OnObjectDestroyed([in] IUnknown *pUnk); } 

, IShutdownNotify . , , , , . . 7.8, ( ) , :

 [uuid(75DA645E-DD0F-11d0-8C58-0080C73925BA), object] interface IShutdownSource : IUnknown {   HRESULT Advise([in] IShutdownNotify *psn, [out] DWORD *pdwCookie);   HRESULT Unadvise([in] DWORD dwCookie); } 

 . 7.8.

, , , (observers) IShutdownNotify . , . , : .

, . . . . IConnectionPoint:

 [object, uuid(B196B286-BAB4-101A-B69C-00AA00341D07)] interface IConnectionPoint : IUnknown {     // which type of interface can be connected     //            HRESULT GetConnectionInterface( [out] IID * pIID);     // get a pointer to identity of "real" object     //         " "    HRESULT GetConnectionPointContainer([out] IConnectionPointContainer ** ppCPC);     // hold and use pUnkSink until notified otherwise     //       pUnkSink,          HRESULT Advise([in] IUnknown * pUnkSink, [out] DWORD * pdwCookie);     // stop holding/using the pointer associated with dwCookle     //    /   ,     dwCookie   HRESULT Unadvise([in] DWORD dwCookie);     // get information about currently held pointers     //                  HRESULT EnumConnections([out] IEnumConnections ** ppEnum); } 

. 7.9, , . , IConnectionPoint , QueryInterface. , , IConnectionPoint, :

 [object,uuid(B196B284-BAB4-101A-B69C-00AA00341D07)] interface IConnectionPointContainer : IUnknown {     // get all possible IConnectionPoint implementations     //         IConnectionPoint   HRESULT EnumConnectionPoints([out] IEnumConnectionPoints ** ppEnum);     // get the IConnectionPoint implementation for riid     //     IConnectionPoint   riid   HRESULT FindConnectionPoint([in] REFIID riid, [out] IConnectionPoint ** ppCP); } 

 . 7.9.

. 7.9, IConnectionPoint - .

IShutdownNotify :

 HRESULT HookupShutdownCallback(IUnknown *pUnkObject,                                IShutdownNotify *pShutdownNotify,                                DWORD &rdwCookie) {     IConnectionPointContainer *pcpc = 0;     HRESULT hr = pUnkObject->QueryInterface(IID_IConnectionPointContainer, (void**)&pcpc);     if (SUCCEEDED(hr)) {         IConnectionPoint *pcp = 0;         hr =pcpc->FindConnectionPoint(IID_IShutdownNotify,&pcp);         if (SUCCEEDED(hr)) {             hr = pcp->Advise(pShutdownNotify, &rdwCookie);             pcp->Release();         }         pcpc->Release();     } } 

:

 HRESULT TeardownShutdownCallback(IUnknown *pUnkObject, DWORD dwCookie) {     IConnectionPointContainer *pcpc = 0;     HRESULT hr = pUnkObject->QueryInterface(IID_IConnectionPointContainer, (void**)&pcpc);     if (SUCCEEDED(hr)) {         IConnectionPoint *pcp = 0;         hr =pcpc->FindConnectionPoint(IID_IShutdownNotify,&pcp);         if (SUCCEEDED(hr)) {             hr = pcp->Unadvise(dwCookie);             pcp->Release();         }         pcpc->Release();     } } 

, IConnectionPointContainer::FindConnectionPoint IShutdownNotify- IConnectionPoint. FindConnectionPoint, , IShutdownNotify. .

IUnknown, IConnectionPointContainer IConnectionPoint . C++ , . ConnectionPoint / , :

 class Surfboard : public ISurfboard,                   public IHazardousDevice,                   public ISharkBait,                   public IConnectionPointContainer {     LONG m_cRef;  //  M reference count                   //        // Surfboards don't support multiple outbound interfaces   // of a given type, so it simply declares single pointers   // of each possible type of callback interface   // Surfboard          //      ,        //            //            IShutdownNotify *m_pShutdownNotify;     ISurfboardUser *m_pSurfer;   // to deal with identity relationship of IConnectionPoint,   // define an IShutdownNotify-specific nested class + member   //            // IConnectionPoint,        // IShutdownNotify    +     class XCPShutdownNotify : public IConnectionPoint {         Surfboard *This(void);           // use fixed offset           //                // IUnknown methods...           //   IUnknown...           // IConnectionPoint methods...           //   IConnectionPoint...     } m_xcpShutdownNotify;   // define an ISurfboardUser-specific nested class + member   //       IShutdownNotify    +     class XCPSurfboardUser : public IConnectionPoint {         Surfboard *This(void);           // use fixed offset           //                // IUnknown methods...           //   IUnknown...           // IConnectionPoint methods...           //   IConnectionPoint...     } m_xcpSurfboardUser;   // IUnknown methods...   //   IUnknown...   // ISurfboard methods...   //   ISurfboard...   // IHazardousDevice methods...   //   IHazardousDevice...   // ISharkBait methods...   //   ISharkBait...   // IConnectionPointContainer methods...   //   IConnectionPointContainer... }; 

, Surfboard IConnectionPoint, IShutdownNotify, ISurfboardUser. C++, IConnectionPoint IUnknown IConnectionPoint. , QueryInterface , - .

QueryInterface-pea Surfboard:

 STDMETHODIMP Surfboard::QueryInterface(REFIID riid, void**ppv) {     if (riid == IID_IUnknown || riid == IID_ISurfboard)         *ppv = static_cast<ISurfboard*>(this);     else if (riid == IID_IHazardousDevice)         *ppv = static_cast< IHazardousDevice *>(this);     else if (riid == IID_ISharkBait)         *ppv = static_cast<ISharkBait *>(this);     else if (riid == IID_IConnectionPointContainer)         *ppv = static_cast<IConnectionPointContainer *>(this);     else         return (*ppv = 0), E_NOINTERFACE;     ((IUnknown*)*ppv)->AddRef();     return S_OK; } 

, IConnectionPoint QueryInterface. QueryInterface :

 STDMETHODIMP Surfboard::XCPShutdownNotify::QueryInterface(REFIID riid, void**ppv) {     if (riid == IID_IUnknown || riid == IID_IConnectionPoint)         *ppv = static_cast<IConnectionPoint *>(this);     else         return (*ppv = 0), E_NOINTERFACE;     ((IUnknown*)*ppv)->AddRef();     return S_OK; } 

XCPSurfboardUser. Surfboard , IConnectionPoint .

Surfboard , AddRef Release surfboard:

 STDMETHODIMP_(ULONG) Surfboard::XCPShutdownNotify::AddRef(void) {     return This()->AddRef();       /* AddRef containing object */       /* AddRef  -  */ } STDMETHODIMP_(ULONG) Surfboard::XCPShutdownNotify::Release(void) {     return This()->Release();       /* Release containing object */       /* Release  -  */ } 

, This - Surfboard, .

IConnectionPoint FindConnectionPoint, Surfboard :

 STDMETHODIMP Surfboard::FindConnectionPoint(REFIID riid, IConnectionPoint **ppcp) {     if (riid == IID_IShutdownNotify)         *ppcp = IID_IShutdownNotify;     else if (riid == IID_ISurfboardUser)         *ppcp = &m_xcpSurfboardUser;     else         return (*ppcp = 0), CONNECT_E_NOCONNECTION;     (*ppcp)->AddRef();     return S_OK; } 

, IConnectionPoint , . QueryInterface. , QueryInterface (inbound) , FindConnectionPoint (outbound) .

IConnectionPoint::Advise IUnknown, 1, Advise QueryInterface , :

 STDMETHODIMP Surfboard::XCPShutdownNotify::Advise(IUnknown *pUnk, DWORD *pdwCookie) {     assert (pdwCookie && pUnk);     *pdwCookie = 0;     if (This()->m_pShutdownNotify) // already have one                                        //              return CONNECT_E_ADVISELIMIT;       // QueryInterface for correct callback type       // QueryInterface              HRESULT hr = pUnk->QueryInterface(IID_IShutdownNotify,                   (void**)&(This()->m_pShutdownNotify));     if (hr == E_NOINTERFACE)         hr = CONNECT_E_NOCONNECTION;     if (SUCCEEDED(hr)) // make up a meaningful cookie                        //              *pdwCookie = DWORD(This()->m_pShutdownNotify);     return hr; } 

, QueryInterface AddRef, : Surfboard , Advise. , , HRESULT CONNECT_E_NOCONNECTION. QueryInterface - , HRESULT QueryInterface 2.

Advise Unadvise :

 STDMETHODIMP Surfboard::XCPShutdownNotify::Unadvise(DWORD dwCookie) {       // ensure that the cookie corresponds to a valid connection       //  ,              if (DWORD (This()->m_pShutdownNotify) != dwCookie)         return CONNECT_E_NOCONNECTION;       // release the connection       //        This()->m_pShutdownNotify->Release();     This()->m_pShutdownNotify = 0;     return S_OK; } 

IConnectionPoint , :

 STDMETHODIMP Surfboard::XCPShutdownNotify::GetConnectionInterface( IID *piid) {     assert (piid);       // return IID of the interface managed by this subobject       //   IID  ,          *piid = IID_IShutdownNofify;     return S_OK; } STDMETHODIMP Surfboard::XCPShutdownNotify::GetConnectionPointContainer(                IConnectionPointContainer **ppcpc) {     assert(ppcpc);     (*ppcpc = This())->AddRef();       // return containing object       //    -     return S_OK; } 

, EnumConnections, . , E_NOTIMPL.

, , IDL [source]:

 [uuid(315BC280-DEA7-11d0-8C5E-0080C73925BA) ] coclass Surfboard {   [default] interface ISurfboard;   interface IHazardousDevice;   interface ISharkBait;   [source] interface IShutdownNotify;   [source, default] interface ISurfboardUser; } 

, , (introspectively) :

 [object,uuid(B196B283-BAB4-101A-B69C-00AA00341D07) ] interface IProvideClassInfo : Unknown {       // return description of object's coclass       //          HRESULT GetClassInfo([out] ITypeInfo ** ppTI); } [object, uuid(A6BC3AC0-DBAA-11CE-9DE3-00M004BB851) ] interface IProvideClassInfo2 : IProvideClassInfo {   typedef enum tagGUIDKIND {     GUIDKIND_DEFAULT_SOURCE_DISP_IID = 1   } GUIDKIND;     // return IID of default outbound dispinterface     //   IID            HRESULT GetGUID([in] DWORD dwGuidKind, [out] GUID * pGUID); } 

:

 STDMETHODIMP Surfboard::GetClassInfo(ITypeInfo **ppti) {     assert(ppti != 0);     ITypeLib *ptl = 0;     HRESULT hr = LoadRegTypeLib(LIBID_BeachLib, 1, 0, 0, &ptl);     if (SUCCEEDED(hr)) {         hr = ptl->GetTypeInfoOfGuid(CLSID_Surfboard, ppti);         ptl->Release();     }     return hr; } STDMETHODIMP Surfboard::GetGUID (DWORD dwKind, GUID *pguid) {     if (dwKind != GUIDKIND_DEFAULT_SOURCE_DISP_IID || !pguid)         return E_INVALIDARG;       // ISurfboardUser must be defined as a dispinterface       // ISurfboardUser              *pguid = IID_ISurfboardUser;     return S_OK; } 

( ), , .

, ISurfboardUser :

 [uuid(315BC28A-DEA7-11d0-8C5E-0080C73925BA)] dispinterface ISurfboardUser { methods:   [id(1)] void OnTiltingForward( [in] long nAmount);   [id(2)] void OnTiltingSideways( [in] long nAmount); } 

Visual Basic , , , :

 Dim WithEvents sb as Surfboard 

Visual Basic . , VariableName_EventName. , iltingForward sb Visual Basic :

 Sub sb_OnTiltingForward(ByVal nAmount as Long)   MsgBox "The surfboard just tilted forward" End Sub 

Visual Basic ISurfboardUser, .


1 . , FindConnectionPoint. , . , , .

2 , , , , .



Suschnost' tehnologii SOM
Essential COM
ISBN: 0201634465
EAN: 2147483647
Year: N/A
Pages: 103
Authors: Don Box

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net