WTL 通过IWebBrowser2接口使WebBrowser控件在自己的窗口打开网页
2015-06-03 16:20
597 查看
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
plaincopy
CAxWindow wndIE = GetDlgItem(IDC_IE);
HRESULT hr;
hr = wndIE.QueryControl(&m_pWb2);
if (m_pWb2)
{
CComVariant v;
m_pWb2->Navigate(CComBSTR(_T("http://www.baidu.com")), &v, &v, &v, &v);
}
3.解决在同一个窗口打开网页的问题
1>让CMainDlg继承自public IDispEventImpl<IDC_IE, CMainDlg>,
给控件添加一个事件,这个事件是在打开一个新窗口的时候触发
[c-sharp] view
plaincopy
BEGIN_SINK_MAP(CMainDlg)
SINK_ENTRY(IDC_IE, DISPID_NEWWINDOW2, NewWindow2Ie)
END_SINK_MAP()
2>关键是响应函数
[c-sharp] view
plaincopy
void __stdcall NewWindow2Ie(IDispatch **ppDisp, VARIANT_BOOL* Cancel)
{
HRESULT hr;
CComPtr<IDispatch> spdispDoc;
hr = m_pWb2->get_Document(&spdispDoc);
if (FAILED(hr))
{
return;
}
CComQIPtr<IHTMLDocument2> spDoc = spdispDoc;
if (!spDoc)
{
return;
}
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;
m_pWb2->Navigate2(&vtUrl, &vtNull, &vtNull, &vtNull, &vtNull);
}
*Cancel = TRUE; // FALSE:打开新窗口, TRUE:不打开新窗口
}
具体函数的作用可以查下msdn, 按理说这样应该就完了, 但是当我编译的时候有个错误说DISPID_NEWWINDOW2没定义
包含#include <ExDispid.h>就可以了。
问题还没完, 运行后点击网页上的链接窗口并没有响应上面的事件,解决方法:
[c-sharp] view
plaincopy
BEGIN_MSG_MAP(CMainDlg)
#if _ATL_VER >= 0x0700 // 请注意这里
CHAIN_MSG_MAP(CAxDialogImpl<CMainDlg>)
#endif
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
COMMAND_ID_HANDLER(ID_APP_ABOUT, OnAppAbout)
COMMAND_ID_HANDLER(IDOK, OnOK)
COMMAND_ID_HANDLER(IDCANCEL, OnCancel)
END_MSG_MAP()
遇到的问题是这样的, 在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
plaincopy
CAxWindow wndIE = GetDlgItem(IDC_IE);
HRESULT hr;
hr = wndIE.QueryControl(&m_pWb2);
if (m_pWb2)
{
CComVariant v;
m_pWb2->Navigate(CComBSTR(_T("http://www.baidu.com")), &v, &v, &v, &v);
}
3.解决在同一个窗口打开网页的问题
1>让CMainDlg继承自public IDispEventImpl<IDC_IE, CMainDlg>,
给控件添加一个事件,这个事件是在打开一个新窗口的时候触发
[c-sharp] view
plaincopy
BEGIN_SINK_MAP(CMainDlg)
SINK_ENTRY(IDC_IE, DISPID_NEWWINDOW2, NewWindow2Ie)
END_SINK_MAP()
2>关键是响应函数
[c-sharp] view
plaincopy
void __stdcall NewWindow2Ie(IDispatch **ppDisp, VARIANT_BOOL* Cancel)
{
HRESULT hr;
CComPtr<IDispatch> spdispDoc;
hr = m_pWb2->get_Document(&spdispDoc);
if (FAILED(hr))
{
return;
}
CComQIPtr<IHTMLDocument2> spDoc = spdispDoc;
if (!spDoc)
{
return;
}
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;
m_pWb2->Navigate2(&vtUrl, &vtNull, &vtNull, &vtNull, &vtNull);
}
*Cancel = TRUE; // FALSE:打开新窗口, TRUE:不打开新窗口
}
具体函数的作用可以查下msdn, 按理说这样应该就完了, 但是当我编译的时候有个错误说DISPID_NEWWINDOW2没定义
包含#include <ExDispid.h>就可以了。
问题还没完, 运行后点击网页上的链接窗口并没有响应上面的事件,解决方法:
[c-sharp] view
plaincopy
BEGIN_MSG_MAP(CMainDlg)
#if _ATL_VER >= 0x0700 // 请注意这里
CHAIN_MSG_MAP(CAxDialogImpl<CMainDlg>)
#endif
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
COMMAND_ID_HANDLER(ID_APP_ABOUT, OnAppAbout)
COMMAND_ID_HANDLER(IDOK, OnOK)
COMMAND_ID_HANDLER(IDCANCEL, OnCancel)
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; }
相关文章推荐
- <转帖>GCD 深入理解:第二部分
- 【Android笔记】EditText密码框中字体和普通输入框不同
- JAX-WS WebService发布
- eclipse设置文件默认打开方式
- Android DrawerLayout 抽屉
- PowerDesigner使用教程
- (转)UIWebView的基本用法
- JFinal调用Mysql存储过程方法
- oracle数据泵的备份与恢复
- Android 基于google Zxing实现二维码、条形码扫描,仿微信二维码扫描效果 (转载)
- 微博转发的内容如何实现点击人名跳转到个人主页
- 什么是数据库引擎
- <转帖>GCD 深入理解:第一部分
- python中的enumerate学习
- iOS错误堆栈查找崩溃原因的方法
- opencv源码解读读书笔记:负样本的有关源代码
- robotium常用API
- 设计模式之原型模式
- kafka HighLevelConsumer API 使用案例
- 拉筋的正确方法