深入解析C++程序中激发事件和COM中的事件处理
本机 C++ 中的事件处理 // evh_native.cpp #include <stdio.h> [event_source(native)] class CSource { public: __event void MyEvent(int nValue); }; [event_receiver(native)] class CReceiver { public: void MyHandler1(int nValue) { printf_s("MyHandler1 was called with value %d.n",nValue); } void MyHandler2(int nValue) { printf_s("MyHandler2 was called with value %d.n",nValue); } void hookEvent(CSource* pSource) { __hook(&CSource::MyEvent,pSource,&CReceiver::MyHandler1); __hook(&CSource::MyEvent,&CReceiver::MyHandler2); } void unhookEvent(CSource* pSource) { __unhook(&CSource::MyEvent,&CReceiver::MyHandler1); __unhook(&CSource::MyEvent,&CReceiver::MyHandler2); } }; int main() { CSource source; CReceiver receiver; receiver.hookEvent(&source); __raise source.MyEvent(123); receiver.unhookEvent(&source); } 输出: MyHandler2 was called with value 123. MyHandler1 was called with value 123. COM 中的事件处理 // evh_server.h #pragma once [ dual,uuid("00000000-0000-0000-0000-000000000001") ] __interface IEvents { [id(1)] HRESULT MyEvent([in] int value); }; [ dual,uuid("00000000-0000-0000-0000-000000000002") ] __interface IEventSource { [id(1)] HRESULT FireEvent(); }; class DECLSPEC_UUID("530DF3AD-6936-3214-A83B-27B63C7997C4") CSource; 接着是服务器: // evh_server.cpp // compile with: /LD // post-build command: Regsvr32.exe /s evh_server.dll #define _ATL_ATTRIBUTES 1 #include <atlbase.h> #include <atlcom.h> #include "evh_server.h" [ module(dll,name="EventSource",uuid="6E46B59E-89C3-4c15-A6D8-B8A1CEC98830") ]; [coclass,event_source(com),uuid("530DF3AD-6936-3214-A83B-27B63C7997C4")] class CSource : public IEventSource { public: __event __interface IEvents; HRESULT FireEvent() { __raise MyEvent(123); return S_OK; } }; 再然后是客户端: // evh_client.cpp // compile with: /link /OPT:NOREF #define _ATL_ATTRIBUTES 1 #include <atlbase.h> #include <atlcom.h> #include <stdio.h> #include "evh_server.h" [ module(name="EventReceiver") ]; [ event_receiver(com) ] class CReceiver { public: HRESULT MyHandler1(int nValue) { printf_s("MyHandler1 was called with value %d.n",nValue); return S_OK; } HRESULT MyHandler2(int nValue) { printf_s("MyHandler2 was called with value %d.n",nValue); return S_OK; } void HookEvent(IEventSource* pSource) { __hook(&IEvents::MyEvent,&CReceiver::MyHandler1); __hook(&IEvents::MyEvent,&CReceiver::MyHandler2); } void UnhookEvent(IEventSource* pSource) { __unhook(&IEvents::MyEvent,&CReceiver::MyHandler1); __unhook(&IEvents::MyEvent,&CReceiver::MyHandler2); } }; int main() { // Create COM object CoInitialize(NULL); { IEventSource* pSource = 0; HRESULT hr = CoCreateInstance(__uuidof(CSource),NULL,CLSCTX_ALL,__uuidof(IEventSource),(void **) &pSource); if (FAILED(hr)) { return -1; } // Create receiver and fire event CReceiver receiver; receiver.HookEvent(pSource); pSource->FireEvent(); receiver.UnhookEvent(pSource); } CoUninitialize(); return 0; } 输出 MyHandler1 was called with value 123. MyHandler2 was called with value 123. 依赖于布局的 COM 事件 [id(1)] HRESULT MyEvent1([in] int value); [id(2)] HRESULT MyEvent2([in] int value); 假定事件源具有以下形式: [coclass,event_source(com)] class CSource : public IEventSource { public: __event __interface IEvents; HRESULT FireEvent() { MyEvent1(123); MyEvent2(123); return S_OK; } }; 则在事件接收器中,挂钩到 IEventSource 中的方法的任何处理程序必须与其名称和签名匹配,如下所示: [coclass,event_receiver(com,true)] class CReceiver { public: HRESULT MyEvent1(int nValue) { // name and signature matches MyEvent1 ... } HRESULT MyEvent2(E c,char* pc) { // signature doesn't match MyEvent2 ... } HRESULT MyHandler1(int nValue) { // name doesn't match MyEvent1 (or 2) ... } void HookEvent(IEventSource* pSource) { __hook(IFace,pSource); // Hooks up all name-matched events // under layout_dependent = true __hook(&IFace::MyEvent1,&CReceive::MyEvent1); // valid __hook(&IFace::MyEvent2,&CSink::MyEvent2); // not valid __hook(&IFace::MyEvent1,&CSink:: MyHandler1); // not valid } }; (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |