WTL SDK sample中有个例子工程TabBrowser实现了MultiTab WebBrowser的功能,但是只是表面上实现了该功能,当页面链接或者按钮不是在本窗口打开的时候,会弹出IE浏览器窗口打开链接,如何才能实现在一个新的tab页打开呢?我们只要响应下browser控件的NewWindow2事件就可以了,下面介绍如何在该例子程序上修改代码:
1、定义NewWindow2事件的参数结构
修改文件:CBrowserView.h
声明定义静态变量的代码处:
// IDispatch events function info
static _ATL_FUNC_INFO DocumentComplete2_Info;
static _ATL_FUNC_INFO TitleChange_Info;
static _ATL_FUNC_INFO StatusTextChange_Info;
static _ATL_FUNC_INFO CommandStateChange_Info;
static _ATL_FUNC_INFO NewWindow2_Info; //该行代码为新加
初始化静态变量的代码处:
__declspec(selectany) _ATL_FUNC_INFO CBrowserView::DocumentComplete2_Info = { CC_STDCALL, VT_EMPTY, 2, { VT_DISPATCH, VT_BYREF | VT_VARIANT } };
__declspec(selectany) _ATL_FUNC_INFO CBrowserView::TitleChange_Info = { CC_STDCALL, VT_EMPTY, 1, { VT_BSTR } };
__declspec(selectany) _ATL_FUNC_INFO CBrowserView::StatusTextChange_Info = { CC_STDCALL, VT_EMPTY, 1, { VT_BSTR } };
__declspec(selectany) _ATL_FUNC_INFO CBrowserView::CommandStateChange_Info = { CC_STDCALL, VT_EMPTY, 2, { VT_I4, VT_BOOL } };
__declspec(selectany) _ATL_FUNC_INFO CBrowserView::NewWindow2_Info = { CC_STDCALL, VT_EMPTY, 2, { VT_DISPATCH, VT_BOOL | VT_BYREF} }; //该行代码为新加
2、声明一个事件的处理函数
修改文件:CBrowserView.h
void __stdcall OnEventNewWindows2(IDispatch **ppDisp, BOOL* pCancel);
3、绑定事件
修改文件:CBrowserView.h
BEGIN_SINK_MAP(CBrowserView)
SINK_ENTRY_INFO(_nDispatchID, DIID_DWebBrowserEvents2, DISPID_DOCUMENTCOMPLETE, OnEventDocumentComplete, &DocumentComplete2_Info)
SINK_ENTRY_INFO(_nDispatchID, DIID_DWebBrowserEvents2, DISPID_TITLECHANGE, OnEventTitleChange, &TitleChange_Info)
SINK_ENTRY_INFO(_nDispatchID, DIID_DWebBrowserEvents2, DISPID_STATUSTEXTCHANGE, OnEventStatusTextChange, &StatusTextChange_Info)
SINK_ENTRY_INFO(_nDispatchID, DIID_DWebBrowserEvents2, DISPID_COMMANDSTATECHANGE, OnEventCommandStateChange, &CommandStateChange_Info)
SINK_ENTRY_INFO(_nDispatchID, DIID_DWebBrowserEvents2, DISPID_NEWWINDOW2, OnEventNewWindows2, &NewWindow2_Info) //该行代码为新加
END_SINK_MAP()
4、实现函数
为了方便,较少的修改代码,我们首先把MainFrm.h里面的变量m_view修改为静态变量:static CCustomTabView m_view;,加一句初始化该变量的代码:CCustomTabView CMainFrame::m_view;
然后我们实现先前声明的OnEventNewWindows2函数,实现我们放在TabBrowser.cpp里面,
void __stdcall CBrowserView::OnEventNewWindows2(IDispatch **ppDisp, BOOL* pCancel)
{
*pCancel = FALSE; //这一句比较重要,如果为TRUE,该事件就是终止了,不会打开任何网页
CString strURL;
CString strLoading;
strLoading.LoadString(IDS_LOADING);
strURL.LoadString(IDS_BLANK_URL);
CBrowserView* pView = new CBrowserView;
pView->Create(CMainFrame::m_view, rcDefault, strURL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VSCROLL | WS_HSCROLL);
CComPtr<IWebBrowser2> spWebBrowser;
HRESULT hRet = pView->QueryControl(IID_IWebBrowser2, (void**)&spWebBrowser);
if(SUCCEEDED(hRet)){
spWebBrowser->put_RegisterAsBrowser(VARIANT_TRUE);
spWebBrowser->get_Application(ppDisp); //这一句是关键,关联我们新建的窗口的browser控件到点击的目标链接
}
if(pView->IsWindow()){
CMainFrame::m_view.AddPage(pView->m_hWnd, strLoading, 0, pView);
}else{
pView->DestroyWindow();
}
}
OK了,赶快编译一下运行看看效果吧!~~~