[ 原始碼下載:http://download.csdn.net/source/3526786 ] Introduction
這裡,我將介紹在對話方塊中使用ActiveX控制項的ATL支援。由於ATL專業處理ActiveX控制項,因此WTL不涉及其他輔助類。不過,使用ActiveX控制項的ATL方法與MFC有很大的不同,所以需要重點介紹。我將介紹如何使用一個ActiveX控制項並處理事件,開發一個程式(與MFC類嚮導產生的程式相比不丟失功能)。
本章的例子示範如何使用IE瀏覽器控制項,選擇瀏覽器控制項有兩個好處:
1)每台電腦上都有這個控制項
2)它有很多方法和事件處理,是個做示範的好例子
我當然無法與那些花了大量的時間編寫基於瀏覽器控制項的定製瀏覽器的人相比,但是,通過本篇文章,你就知道如何開始自己編寫定製的瀏覽器。 Starting with the AppWizard Creating the project
WTL程式建立嚮導可以建立一個包含ActiveX控制項的程式。我們建立一個IEHoster的新工程,並使用非模態對話方塊形式。
The generated code
這節,我們將見到有嚮導產生的沒見過的新代碼。下一節將介紹ActiveX包容類的細節。
首先檢查的是stdafx.h檔案, [cpp] view plain copy #include <atlbase.h> #include <atlapp.h> extern CAppModule _Module; #include <atlcom.h> #include <atlhost.h> #include <atlwin.h> #include <atlctl.h> // .. other WTL headers ...
atlcom.h 和 atlhost.h是很重要的。它們含有一些COM相關類的定義(比如智能指標CComPtr),還有用來包容控制項的視窗類別。
下面,查看maindlg.h中的CMainDlg類: [cpp] view plain copy class CMainDlg : public CAxDialogImpl<CMainDlg>, public CUpdateUI<CMainDlg>, public CMessageFilter, public CIdleHandler
現在,CMainDlg派生於CAxDialogImpl,這是使對話方塊支援包容ActiveX控制項的第一步。
最後在程式入口函數WinMain()中添加一行新代碼: [cpp] view plain copy int WINAPI _tWinMain(...) { //... _Module.Init(NULL, hInstance); <strong>AtlAxWinInit();</strong> int nRet = Run(lpstrCmdLine, nCmdShow); _Module.Term(); return nRet; }
AtlAxWinInit()註冊了一個類名為AtlAxWin的視窗類別,ATL用它建立ActiveX控制項的包容視窗。
由於ATL7的一些改變,需要在_Module.Init()的參數中添加LIBID,論壇中的一些人建議使用下面的代碼: [cpp] view plain copy _Module.Init(NULL, hInstance, &LIBID_ATLLib); Adding Controls with the Resource Editor
和MFC的程式一樣,ATL也可以使用資源編輯器向對話方塊添加控制項。首先,在對話方塊編輯器上點擊滑鼠右鍵,在彈出的菜單中選擇“Insert ActiveX control”:
VC將會顯示系統中安裝的控制項類表,滾動列表選擇“Microsoft Web Browser”,查看控制項的屬性,將ID設為IDC_IE。資源編輯器中對話方塊中的控制項顯示應該是這個樣子的:
如果現在編譯運行程式,你會看到對話方塊中的瀏覽器控制項,它將顯示一個空白頁,因為我們還沒有告訴它開啟哪個網頁。
在下一節,我將介紹與建立和包容ActiveX控制項有關的ATL類,同時我們也會明白這些類是如何與瀏覽器交換資訊的。 ATL Classes for Control Hosting
當在對話方塊中包容ActiveX控制項,需要CAxDialogImpl 和 CAxWindow這兩個類協同工作。它們提供了所有控制項容器必須實現的介面方法,提供通用的功能函數,例如查詢控制項的某個特殊的COM介面。 CAxDialogImpl
第一個類是CAxDialogImpl,要使你的對話方塊能夠包容ActiveX控制項就必須從CAxDialogImpl派生。CAxDialogImpl類重載了Create()和DoModal()函數,這兩個函數分別被全域函數AtlAxCreateDialog()和AtlAxDialogBox()調用。既然IEHoster對話方塊是由Create()建立的,我們看看AtlAxCreateDialog()到底做了什麼工作。
AtlAxCreateDialog()裝載對話方塊資源,並使用輔助類_DialogSplitHelper遍曆對話方塊的所有控制項,尋找由資源編輯器建立的特殊條目,這些特殊條目就表示這是一個ActiveX控制項。例如,下面是IEHoster.rc檔案中瀏覽器控制項的入口: [cpp] view plain copy CONTROL "",IDC_IE,"{8856F961-340A-11D0-A96B-00C04FD705A2}", WS_TABSTOP,7,7,116,85
第一個參數是視窗文字(Null 字元串),第二個是控制項的ID,第三個是視窗的類名。_DialogSplitHelper::SplitDialogTemplate()函數找到以'{'開始的視窗類別名時就知道這是一個表示ActiveX控制項的條目。它在記憶體中建立了一個臨時對話方塊模板,在這個新模板中這些特殊的控制列目被建立的AtlAxWin視窗對應項代替,新的入口是在記憶體中的等價體: [cpp] view plain copy CONTROL