ATL/WTL DLL and the CMessageLoop* pLoop
-
Hi All, After reading Michael Dunns WTL articles I want to convert my ATL/MFC COM Dlls to ATL/WTL ones. Building the DLL from base setting I have built a standard ATL project and then added the required WTL #includes as per the examples in Michaels articles. I have changes the CComModule to CAppModule and compiled. Everything works a treat! I am little bit confused though an where to exactly define/create my CMessageLoop object. Should I do this in the DLLMain function?
extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) { if (dwReason == DLL_PROCESS_ATTACH) { _Module.Init(ObjectMap, hInstance, &LIBID_WTLHISTORYLib); DisableThreadLibraryCalls(hInstance); **// register object for message filtering and idle updates CMessageLoop* pLoop = _Module.GetMessageLoop(); ATLASSERT(pLoop != NULL); pLoop->AddMessageFilter(this); pLoop->AddIdleHandler(this);** } else if (dwReason == DLL_PROCESS_DETACH) _Module.Term(); return TRUE; // ok }
What the DLL is to do is: Have however many classes required, each implementing whatever COM interfaces that they need too Do there thing and return back to Calling Application. Am I in the right ballpark or because it is a DLL each COM implemented class has its own map... like below// CMyReport class ATL_NO_VTABLE CMyReport: public CComObjectRootEx, public CComCoClass, public ISupportErrorInfo, public IHistoryReport, public ICommand { public: CMyReport(); ~CMyReport(); DECLARE_REGISTRY_RESOURCEID(IDR_MYREPORT) DECLARE_PROTECT_FINAL_CONSTRUCT() BEGIN_COM_MAP(CMyReport) COM_INTERFACE_ENTRY(IMyReport) COM_INTERFACE_ENTRY(ISupportErrorInfo) COM_INTERFACE_ENTRY(ICommand) END_COM_MAP() BEGIN_CATEGORY_MAP(CMyReport) IMPLEMENTED_CATEGORY( __uuidof(CATID_MxCommands)) END_CATEGORY_MAP() // IMakeHistory public: // ICommand STDMETHOD(get_Enabled)(VARIANT_BOOL * Enabled); STDMETHOD(get_Checked)(VARIANT_BOOL * Checked); STDMETHOD(get_Name)(BSTR * Name); STDMETHOD(get_Caption)(BSTR * Caption); STDMETHOD(get_Tooltip)(BSTR * Tooltip); STDMETHOD(get_Message)(BSTR * Message); STDMETHOD(get_HelpFile)(BSTR * HelpFile); STDMETHOD(get_HelpContextID)(LONG * helpID); STDMETHOD(get_Bitmap)(OLE_HANDLE * Bitmap); STDMETHOD(get_Category)(BSTR * categoryName); STDMETHOD(OnCreate)(IDispatch * hook); STDME
-
Hi All, After reading Michael Dunns WTL articles I want to convert my ATL/MFC COM Dlls to ATL/WTL ones. Building the DLL from base setting I have built a standard ATL project and then added the required WTL #includes as per the examples in Michaels articles. I have changes the CComModule to CAppModule and compiled. Everything works a treat! I am little bit confused though an where to exactly define/create my CMessageLoop object. Should I do this in the DLLMain function?
extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) { if (dwReason == DLL_PROCESS_ATTACH) { _Module.Init(ObjectMap, hInstance, &LIBID_WTLHISTORYLib); DisableThreadLibraryCalls(hInstance); **// register object for message filtering and idle updates CMessageLoop* pLoop = _Module.GetMessageLoop(); ATLASSERT(pLoop != NULL); pLoop->AddMessageFilter(this); pLoop->AddIdleHandler(this);** } else if (dwReason == DLL_PROCESS_DETACH) _Module.Term(); return TRUE; // ok }
What the DLL is to do is: Have however many classes required, each implementing whatever COM interfaces that they need too Do there thing and return back to Calling Application. Am I in the right ballpark or because it is a DLL each COM implemented class has its own map... like below// CMyReport class ATL_NO_VTABLE CMyReport: public CComObjectRootEx, public CComCoClass, public ISupportErrorInfo, public IHistoryReport, public ICommand { public: CMyReport(); ~CMyReport(); DECLARE_REGISTRY_RESOURCEID(IDR_MYREPORT) DECLARE_PROTECT_FINAL_CONSTRUCT() BEGIN_COM_MAP(CMyReport) COM_INTERFACE_ENTRY(IMyReport) COM_INTERFACE_ENTRY(ISupportErrorInfo) COM_INTERFACE_ENTRY(ICommand) END_COM_MAP() BEGIN_CATEGORY_MAP(CMyReport) IMPLEMENTED_CATEGORY( __uuidof(CATID_MxCommands)) END_CATEGORY_MAP() // IMakeHistory public: // ICommand STDMETHOD(get_Enabled)(VARIANT_BOOL * Enabled); STDMETHOD(get_Checked)(VARIANT_BOOL * Checked); STDMETHOD(get_Name)(BSTR * Name); STDMETHOD(get_Caption)(BSTR * Caption); STDMETHOD(get_Tooltip)(BSTR * Tooltip); STDMETHOD(get_Message)(BSTR * Message); STDMETHOD(get_HelpFile)(BSTR * HelpFile); STDMETHOD(get_HelpContextID)(LONG * helpID); STDMETHOD(get_Bitmap)(OLE_HANDLE * Bitmap); STDMETHOD(get_Category)(BSTR * categoryName); STDMETHOD(OnCreate)(IDispatch * hook); STDME
CMessageLoop
is a WTL class, and_Module
has to have message loops added to it explicitly. IOW there is no API or method that says "give me some object representing the EXE's message loop" Also,_Module
is per-module (thus the name), unlike MFC DLLs where several DLLs can share the sameCWinApp
object. So unless you control the EXE as well, the DLL has no access to the EXE's message loop. If you do control the EXE too, I guess you could pass a pointer to the DLL, although it wouldn't be possible to get to it inDllMain()
; you'd need some other exported initialize function that the EXE would call. Now, if you create your own UI threads in the DLL, then you control the message loop and you can set up theCMessageLoop
object like you want. --Mike-- Ericahist [updated Oct 26] | CP SearchBar v2.0.2 | Homepage | RightClick-Encrypt | 1ClickPicGrabber If my rhyme was a drug, I'd sell it by the gram.