自從去年年底一次棘手的界面,開始研究用web做界面到現在大約1年,這一年間不是局限在實現層面,也並非一直研究這一個問題,有很多問題其實不是問題,只是自己沒有想清楚或者思想沒放開。對於一個界面開發人員,想必拉的對話框不少於100個,膩味不必說,光是對話框大小改變導致控件跟着變化都需要一番功夫,加上界面美觀,界面的風格統一,界面的靈活多變......,頭痛。在對話框里面加載位圖,加載gif,超鏈接......,啊,沒法控制了吧!在考慮遠點,現在.net3.0技術已經完全打破應用和桌面的界限,我們的界面html資源完全可以放在一個web站點上,這樣界面是完全動態的。
其間寫過2篇這方面的文章,基於vc6實現,繞彎很大。在vc7.1、vc8里面要簡單很多,主要是把幾個以前為公開的類公開了,最重要的是在CWnd里面加入了一個虛函數CreateControlSite使得有機會改變控件站點以修改控件行為。在mfc類層次上,CHTMLView和CDHtmlDialog為開發者提供了創建webgui的一系列基礎設施,包括事件機制、窗口行為、以及對html文檔操縱接口。我們在此基礎上實現webgui很簡單,然而仍然困惑我很久,經理也催過我幾次我一直未肯決定最終方案。在我腦袋里一直琢磨是要應用程序完全操縱html文檔,還是html訪問應用獲取信息,其實就是它們之間的通信模式。一直到昨天我才定下方案,應用通過IWebBrowser2接口操縱html元素,html通過vbscript、javascript腳本響應本身事件,訪問應用。主要是考慮通信自然暢通,而以前我一味想通過應用指令完全控制html元素,導致去解析html文檔,費力不討好。下面開始我的想法:
寫一個dll,封裝CDHtmlDialog,提供一個類似html容器的對話框,功能就是加載html網頁,以及創建與html呼應的com組件。它本身不包含與應用功能有關代碼,應用有關的部分是html頁面和對於的com功能組件。這里需要對CDHtmlDialog進行了適當的改造以適合自己的目標:
首先從CDHtmlDialog派生一個類CHTMLContainerDlg,默認情況下會生成一個網頁資源,這個網頁是這個對話框創建時加載的,我們需要的其實是一個容器而不是一個具體的對話框,所以刪除網頁資源,修改對話框頭文件:

這里把IDH修改為0,因為我們刪除了網頁資源。然而在對話框創建后會加載該資源,在CDHtmlDialog的OnInitDialog函數里面我們可以看到:






結果就是對話框一出現就會出現加載一個無效地址的頁面,出現無法打開鏈接的頁面,為了避免這個問題,需要重載OnInitDialog函數。其實就是拷貝mfc代碼然后去掉上面那段代碼就ok,強制不加載頁面。那么為了加載指定頁面,需要一個函數:












指定html的url和對應功能組件的progid,這樣在網頁里面可以通過腳本window.external訪問該com組件。
這樣就可以加載html網頁,但是html頁面里面的元素風格卻是2k風格(至少在ie7以下版本是如此),這個怕是沒起到一點美觀作用,為之我考慮了半天,問過做web的人是否有辦法,最終還是靈感光臨,誤撞上了。重載GetHostInfo函數:





這個多得不說,^_^。
下面就可以演示了,在vs2005里面找個向導來show一下:








對話框標題其實可以通過解析html文檔獲取title標題設置,目前還未處理。下面看看html與應用交互的組件。
生成一個atl工程,TestWebCom,添加一個com組件WebComCtrl,添加方法處理上面那個帶...的按鈕(文件夾瀏覽按鈕):








這里不作具體處理,只是象征性彈出一個對話框。好了,上面我們在對話框里面已經設置了com組件的progid,這里可以把html和組件關聯上了,通過腳本可以訪問com組件方法:


腳本如下:




下面運行試一試,按下選擇文件夾按鈕會出現如下詢問組件是否安全的對話框:
這個很惱人,用戶可沒有耐心忍受每次多彈出這個對話框詢問組件是否安全。我開始打算將組件實現安全接口解決掉此問題,不過不知道緣何,沒有成功,網上搜索一下好像說在ie7里面無效,沒辦法還是看mfc源碼來解決問題。
CDHtmlDialog類獲取external代碼如下:














看到CanAccessExternal函數,肯定就是驗證安全性的代碼,找到函數聲明,幸好是虛函數,重載直接返回TRUE:





有興趣的朋友可以看下內部實現。
這下就好了,按下網頁選擇文件夾按鈕,彈出對話框:
一套流程完備,方案個人覺得不錯,各司其職,通信自然暢通,一個html配對一個com功能組件,功能組件化不僅使代碼封裝性好,而且可以用於多種語言。
由於此技術不用於公司開發,今整理提供下載
from:http://www.cppblog.com/wlwlxj/archive/2006/12/15/16495.aspx