WTL 通过IWebBrowser2接口使WebBrowser控件在自己的窗口打开网页

http://blog.csdn.net/tujiaw/article/details/6554994


   遇到的问题是这样的, 在WTL中我用了一个WebBrowser控件来显示网页,但是在点击网页中的链接的时候经常跳到其他浏览器上去打开这个链接。我希望的是总是在我的这个控件上显示网页, 不要跳到其他浏览器上去打开。

 

1.添加IWebBrowser2控件

        在创建的时候Select project options下要勾选Enable ActiveX Control Hosting, 让其继承自CAxDialogImpl, 然后在对话框上点右键Insert ActiveX Control..., 找到Microsoft Web Browser确定, 将属性ID号改为IDC_IE。

 

2.让程序运行后打开一个默认网页

1>CComPtr<IWebBrowser2> m_pWb2;

2>在OnInitDialog中, return上面

[c-sharp]  view plain copy
  1. CAxWindow wndIE = GetDlgItem(IDC_IE);  
  2. HRESULT hr;  
  3. hr = wndIE.QueryControl(&m_pWb2);  
  4. if (m_pWb2)  
  5. {  
  6.     CComVariant v;  
  7.     m_pWb2->Navigate(CComBSTR(_T("http://www.baidu.com")), &v, &v, &v, &v);  
  8. }  

3.解决在同一个窗口打开网页的问题

1>让CMainDlg继承自public IDispEventImpl<IDC_IE, CMainDlg>,

给控件添加一个事件,这个事件是在打开一个新窗口的时候触发

[c-sharp]  view plain copy
  1. BEGIN_SINK_MAP(CMainDlg)  
  2.     SINK_ENTRY(IDC_IE, DISPID_NEWWINDOW2, NewWindow2Ie)  
  3. END_SINK_MAP()  

2>关键是响应函数

[c-sharp]  view plain copy
  1. void __stdcall NewWindow2Ie(IDispatch **ppDisp, VARIANT_BOOL* Cancel)  
  2.     {  
  3.         HRESULT hr;  
  4.         CComPtr<IDispatch> spdispDoc;  
  5.         hr = m_pWb2->get_Document(&spdispDoc);  
  6.         if (FAILED(hr))  
  7.         {  
  8.             return;  
  9.         }  
  10.         CComQIPtr<IHTMLDocument2> spDoc = spdispDoc;  
  11.         if (!spDoc)  
  12.         {  
  13.             return;  
  14.         }  
  15.         IHTMLElement *htmlElement;  
  16.         spDoc->get_activeElement(&htmlElement);  
  17.         IHTMLAnchorElement *spAnchorElement;  
  18.         htmlElement->QueryInterface(IID_IHTMLAnchorElement, (void**)&spAnchorElement);  
  19.         if (spAnchorElement)  
  20.         {  
  21.             BSTR bstrElementHref;  
  22.             VARIANT vtUrl, vtNull;  
  23.             hr = spAnchorElement->get_href(&bstrElementHref); // 获取当前点击的链接地址  
  24.             vtUrl.vt = VT_BSTR;  
  25.             vtUrl.bstrVal = bstrElementHref;  
  26.             m_pWb2->Navigate2(&vtUrl, &vtNull, &vtNull, &vtNull, &vtNull);  
  27.         }  
  28.         *Cancel = TRUE; // FALSE:打开新窗口, TRUE:不打开新窗口  
  29.     }  

具体函数的作用可以查下msdn, 按理说这样应该就完了, 但是当我编译的时候有个错误说DISPID_NEWWINDOW2没定义

包含#include <ExDispid.h>就可以了。

问题还没完, 运行后点击网页上的链接窗口并没有响应上面的事件,解决方法:

[c-sharp]  view plain copy
  1. BEGIN_MSG_MAP(CMainDlg)  
  2. #if _ATL_VER >= 0x0700           // 请注意这里  
  3.         CHAIN_MSG_MAP(CAxDialogImpl<CMainDlg>)  
  4. #endif  
  5.         MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)  
  6.         MESSAGE_HANDLER(WM_DESTROY, OnDestroy)  
  7.         COMMAND_ID_HANDLER(ID_APP_ABOUT, OnAppAbout)  
  8.         COMMAND_ID_HANDLER(IDOK, OnOK)  
  9.         COMMAND_ID_HANDLER(IDCANCEL, OnCancel)  
  10.     END_MSG_MAP()  

HRESULT _stdcall WebBrowser::Invoke(
	DISPID dispIdMember,
	REFIID riid,
	LCID lcid,
	WORD wFlags,
	DISPPARAMS* pDispParams,
	VARIANT* pVarResult,
	EXCEPINFO* pExcepInfo,
	unsigned int* puArgErr)
{
	if (dispIdMember == DISPID_BEFORENAVIGATE2)
	{
		BeforeNavigate2(pDispParams->rgvarg[6].pdispVal,
			pDispParams->rgvarg[5].pvarVal,
			pDispParams->rgvarg[4].pvarVal,
			pDispParams->rgvarg[3].pvarVal,
			pDispParams->rgvarg[2].pvarVal,
			pDispParams->rgvarg[1].pvarVal,
			pDispParams->rgvarg[0].pboolVal);
		return S_OK;
	}
	if (dispIdMember == DISPID_NEWWINDOW2)
	{
		HRESULT hr;
		CComPtr<IDispatch> spdispDoc;
		hr = _pWB2->get_Document(&spdispDoc);
		if (FAILED(hr))
		{
			return E_FAIL;
		}
		CComQIPtr<IHTMLDocument2> spDoc = spdispDoc;
		if (!spDoc)
		{
			return E_FAIL;
		}
		IHTMLElement *htmlElement;
		spDoc->get_activeElement(&htmlElement);
		IHTMLAnchorElement *spAnchorElement;
		htmlElement->QueryInterface(IID_IHTMLAnchorElement, (void**)&spAnchorElement);
		if (spAnchorElement)
		{
			BSTR bstrElementHref;
			VARIANT vtUrl, vtNull;
			hr = spAnchorElement->get_href(&bstrElementHref); // 获取当前点击的链接地址  
			vtUrl.vt = VT_BSTR;
			vtUrl.bstrVal = bstrElementHref;
			_pWB2->Navigate2(&vtUrl, &vtNull, &vtNull, &vtNull, &vtNull);
		}
		*pDispParams->rgvarg[0].pboolVal = VARIANT_TRUE; // FALSE:打开新窗口, TRUE:不打开新窗口  
		return S_OK;
	}
	
	return E_NOTIMPL;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值