删除文章

确定要删除这篇文章吗?

取消
确定

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

     阅读(643)  2017-04-15 12:33:58

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

添加IWebBrowser2控件

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

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

  • CComPtr m_pWb2;
  • 在OnInitDialog中, return上面

    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);
    }
    

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

  • 让CMainDlg继承自public IDispEventImpl 给控件添加一个事件,这个事件是在打开一个新窗口的时候触发

    BEGIN_SINK_MAP(CMainDlg)
    SINK_ENTRY(IDC_IE, DISPID_NEWWINDOW2, NewWindow2Ie)
    END_SINK_MAP()
    
  • 关键是响应函数

    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 就可以了。 问题还没完, 运行后点击网页上的链接窗口并没有响应上面的事件,解决方法:

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()

2011-06-19

文章评论

Keep it simple,stupid
文章数
292
总访问量
350274
今日访问
288
最近评论

xuehaoyun : 很不错,来围观一下
tujiaw : 抱歉csdn code服务关闭了,这个代码我也找不到了
于淞 : 你好,这个文章的源码能分享一下吗,songsong9181@163.com,谢谢了 上面的写错了
于淞 : 你好,这个文章的源码能分享一下吗,838106303@163.com,谢谢了 上面的链接不能用了
tujiaw : 多谢多谢
essaypinglun college-paper.org : 很好的博客,赞赞
Folly : 这个实现有点奇怪,Qt为什么没有统一的比对方法。
过多s : alert("hello, world!")
tujiaw : 还不错哦
回到顶部