|
珞珈山水BBS →
电脑网络 →
程序人生 →
单文区文章阅读
|
| 单文区文章阅读 [返回] |
|---|
|
发信人: fgynew (fgynew), 信区: Programm 标 题: Com Event Step By Step 发信站: BBS 珞珈山水站 (Fri Sep 22 10:15:18 2006) The com event is similar with the delegate event in C#. But it’s more complic ated and more incomprehensible. After I learnt many theories about it and wrot e some projects I found that only following several steps can make it work. No w I wrote it down and you can follow my step to learn com event. If any questi ons or any mistakes, please contact me. First Step ----- Build up the com event source: 1 Create an ATL project. I named it “StepByStep”. Now open the file StepBySt ep.idl in studio.net and you will found the file is like this: import "oaidl.idl"; import "ocidl.idl"; [ uuid(EBA72123-3D41-473C-9A9C-216D73809AA8), version(1.0), helpstring("StepByStep 1.0 Type Library") ] library StepByStepLib { importlib("stdole2.tlb"); }; Now my com library is SteyByStepLib and it has no interfaces nor coclasses. 2 Add an ATL simple class “SourceEvent” to this project and in the “Option” of the “ATL Simple Object Wizard” please choose “Connection points”. Clic k “Finish” of this dialog and several new files will be added to you project . Now open the file StepByStep.idl and it may like this: import "oaidl.idl"; import "ocidl.idl"; [ object, uuid(FE8B032E-E923-4415-A29C-3ECFA0930D59), dual, nonextensible, helpstring("ISourceEvent Interface"), pointer_default(unique) ] interface ISourceEvent : IDispatch{ }; [ uuid(EBA72123-3D41-473C-9A9C-216D73809AA8), version(1.0), helpstring("StepByStep 1.0 Type Library") ] library StepByStepLib { importlib("stdole2.tlb"); [ uuid(41035159-DDE1-4C27-BD15-936628E79763), helpstring("_ISourceEventEvents Interface") ] dispinterface _ISourceEventEvents { properties: methods: }; [ uuid(EEC59666-F958-4731-B3F0-60C7500AF27F), helpstring("SourceEvent Class") ] coclass SourceEvent { [default] interface ISourceEvent; [default, source] dispinterface _ISourceEventEvents; }; }; Now the coclass has the implement the interface ISourceEvent and the event dis pinterface _ISourceEventEvents. But the both interfaces have no method. 3 Add methods to the two interfaces. After that, the idl is like this: … interface ISourceEvent : IDispatch{ [id(1), helpstring("method SubTract")] HRESULT SubTract([in] LONG NumberOn e, LONG NumberTwo, LONG* Value); }; … dispinterface _ISourceEventEvents { properties: methods: [id(1), helpstring("method GetValue")] HRESULT GetValue(LONG value); }; 4 Add connection point to the class CSourceEvent. In class view of visual stud io.net, right click on the class CSourceEvent and choss “Add”, then choose “ Add connection point…”. In the poped out dialog, add _ISourceEventEvents to this class’s impletion. After you do that, the wizard will add a function “F ire_GetValue(LONG value)” to the class CProxy_ISourceEventEvents. 5 In the fuction SubTract call the event method. STDMETHODIMP CSourceEvent::SubTract(LONG NumberOne, LONG NumberTwo, LONG* Valu e) { *Value = NumberOne - NumberTwo; Fire_GetValue(*Value); return S_OK; } Now the source coclass is bulit up and now it has four UIDS. They are IID_ISou rceEvent, LIBID_StepByStepLib, DIID__ISourceEventEvents, CID_SourceEven. Now build the project and then the dll file StepByStep.dll will be generated. It’s the file that client need. Second Step ----- Build up the client. 1 Create a MFC dialog base object and add a button to the resource file. Add f ollowing codes to the end of the file Stdafx.h. #import "..\Debug\StepByStep.dll" raw_interfaces_only no_namespace named_guids #include <atlbase.h> #include <atlcom.h> 2 Add a sink class to this project. The class is just like this. static _ATL_FUNC_INFO infor = { CC_STDCALL, //the call type VT_EMPTY, //the return value 1, //the number of the params. Only have one {VT_I4} //the params' type. The only one is LONG }; class EventHandler : public IDispEventImpl<1, EventHandler, &DIID__ISourceEven tEvents, &LIBID_StepByStepLib> { public: EventHandler(){}; ~EventHandler(){}; HRESULT __stdcall GetSubValue(LONG lValue) { CString str; str.Format(_T("The value is %d"), lValue); AfxMessageBox(str); return S_OK; } BEGIN_SINK_MAP(EventHandler) SINK_ENTRY_INFO(1, DIID__ISourceEventEvents, 1, GetSubValue, &infor) END_SINK_MAP() }; The class EventHandler is just a sink class which realizes the event interface . 3 Connect the sink class instance to the source object. Add hander to the adde d button. void CClientDialogDlg::OnBnClickedButton2() { ISourceEventPtr pSource; pSource.CreateInstance(__uuidof(SourceEvent)); if(NULL != pSource) { EventHandler *pHandler = new EventHandler(); pHandler->DispEventAdvise(pSource, &DIID__ISourceEventEvents); LONG Value; pSource->SubTract(100, 20, &Value); pHandler->DispEventUnadvise(pSource, &DIID__ISourceEventEvents); delete pHandler; } } When the call pSource->SubTract(100, 20, &Value) a dialog will pop out. Which is generated form the client. Now all steps are over and you will find it easy . -- ※ 来源:·珞珈山水BBS站 http://bbs.whu.edu.cn·[FROM: 210.22.79.*] |
| [返回单文区目录] |
|
|