使用CHtmlView製作瀏覽器的簡單記錄
這幾天做了一個簡易瀏覽器,其中碰到了一些問題,在這裡記錄下來,以供之後查閱。
1、簡單的瀏覽器一些基本功能,例如回到主頁、向前、後退、重新整理、停止,都可以直接使用CHtmlView中的操作。
例如GoBack、GoForward、GoHome、Refresh、Stop等
CHtmlView成員:http://msdn.microsoft.com/zh-cn/library/be4ak306(v=vs.80).aspx
2、點選連結彈出IE視窗開啟,需要過載OnNewWindow2
這一部分程式碼,網上流傳的很廣
3、提示指令碼錯誤,可以在OnInitialUpdate中新增SetSilent(TRUE);
4、在檢視上遮蔽右鍵,過載PreTranslateMessage
BOOL CMyWebBrowserView::PreTranslateMessage(MSG* pMsg)
{
// TODO: 在此新增專用程式碼和/或呼叫基類
if ((pMsg->message == WM_RBUTTONDOWN) ||(pMsg->message == WM_RBUTTONDBLCLK))
return TRUE;
return CHtmlView::PreTranslateMessage(pMsg);
}
5、位址列可以用彈出帶輸入控制元件的對話方塊實現,我選擇使用DialogBar上的combobox作為位址列,並將其他功能按鍵也放在DialogBar上
CdialogBar的使用,參考:http://www.cnblogs.com/cylee025/archive/2011/05/04/2036201.html
子控制元件嘗試了一下,總是繫結不上,不知道哪裡出問題了,只好把對控制元件操作改成CdialogBar派生類的成員函式...
7、從combobox中選擇地址,響應CBN_SELCHANGE事件
6、在位址列中輸入地址後,按回車鍵確認,同時將這個地址與combobox已有資料比較,如果存在,選中這一項
如果不存在,將新輸入的地址新增到combobox中。同時選中這一項並開啟這個地址
同樣過載PreTranslateMessage,攔截回車鍵
BOOL CMyDlgBar::PreTranslateMessage(MSG* pMsg) { // TODO: 在此新增專用程式碼和/或呼叫基類 //捕獲回車鍵 if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN){ //MessageBox(L"huiche"); CString strTemp; m_comAddr.GetWindowText(strTemp);//從combobox獲得輸入的地址 //與已有資料比較 int iCnt = m_comAddr.GetCount(); for(int i = 0;i < iCnt;i++){ //如果找到則選中,沒有找到則新增並選中 if(CB_ERR == m_comAddr.SelectString(-1,strTemp)){ m_comAddr.AddString(strTemp); m_comAddr.SetCurSel(iCnt); break; } } //呼叫combobox響應CBN_SELCHANGE事件 OnCbnSelchangeDlgAddrcom(); } return CDialogBar::PreTranslateMessage(pMsg); }
9、仿照現在大多數瀏覽器,重新整理和停止使用同一個按鈕,因此需要獲得何時開始和結束導航
過載OnBeforeNavigate2,導航發生之前呼叫
OnDocumentComplete響應文件就緒狀態
10、當文件就緒後,獲取html中的title,將其顯示在視窗標題欄
//獲得新開啟的網頁title
CComPtr<IHTMLDocument2> pHTMLDocument2;
m_pBrowserApp->get_Document((IDispatch **)&pHTMLDocument2);
BSTR htmlTitle;
pHTMLDocument2->get_title(&htmlTitle);
顯示在視窗標題欄可以使用SetWindowText
11、儲存html檔案
ExecWB(OLECMDID_SAVEAS, OLECMDEXECOPT_DODEFAULT, NULL, NULL);
12、縮放功能利用SliderCtrl,比例在50%-200%之間變化,響應SliderCtrl的NM_ONCUSTOMDARW事件,將getpos得到的位置傳送給view
使用ExecWB實現
CComVariant varZoom(m_nPos); // nZoom是要設定的縮放比例,m_nPos為SliderCtrl滑標的位置
ExecWB(OLECMDID_OPTICAL_ZOOM, OLECMDEXECOPT_DODEFAULT, &varZoom, NULL);
13、還原預設大小
CComVariant varZoom(100);
ExecWB(OLECMDID_OPTICAL_ZOOM, OLECMDEXECOPT_DODEFAULT, &varZoom, NULL);
同時一定要將SliderCtrl的位置還原
14、在狀態列中新增網頁開啟的進度條(Progress Bar),進度條在開始載入網頁(OnBeforeNavigate2)時建立,在載入完成(OnDocumentComplete)後銷燬(或延時銷燬)。
網頁開啟的進度可以在view中使用OnProgressChange獲得,可以將它得到的兩個引數設計為結構體,將其指標傳遞給進度條。
進度條應該設計為(0,100)的範圍,收到訊息後將當前位置改為(nProgress / nProgressMax)*100,此處需對直接獲得的long進行型別轉換
問題:OnDocumentComplete會多次響應
15、控制視窗可調整的的大小,在CMainFrame中響應WM_GETMINMAXINFO
void CMainFrame::OnGetMinMaxInfo(MINMAXINFO* lpMMI)
{
// TODO: 在此新增訊息處理程式程式碼和/或呼叫預設值
lpMMI->ptMinTrackSize.x = 400;//設定最小視窗為400*300
lpMMI->ptMinTrackSize.y = 300;
CFrameWnd::OnGetMinMaxInfo(lpMMI);
}
16、視窗大小改變後,控制元件的位置需要調整
響應WM_SIZE,使用GetClientRect和SetWindowPos
這一步最好還是先設計好介面
17、vs2012預設生成的檔案無法再xp上執行
有人說更改平臺工具集為xp,嘗試後不行
改成靜態庫後可以,exe檔案大小會增加
工程檔案:(vs2012)
http://download.csdn.net/detail/hrxd1270/7031567
其他問題:1、比較懶,沒有隨時記錄的習慣,很多小問題現在已經記不得了
2、事先沒有計劃好,很多東西都是邊做邊想,結構比較亂