问题由来是这样的,今天帮一个网友解决问题,说从VC驿站下载了一个源码,程序的功能主要是在对话框上面放置了一个WebBrowser控件,程序启动的时候默认调用这句代码:

m_web.Navigate(_T("https://www.baidu.com/s?wd=400电话"), NULL, NULL, NULL, NULL);

打开这个网址:
https://www.baidu.com/s?wd=400电话,如下图:

点击【获取测试】按钮之后,执行如下函数:

 void CCctryDlg::OnBnClickedButton1()
{
CComQIPtr <IHTMLDocument2, &IID_IHTMLDocument2> spDoc1 = m_web.get_Document();
IHTMLDocument3 *pDoc3 = NULL;
HRESULT hr = spDoc1->QueryInterface(IID_IHTMLDocument3, (void **)&pDoc3);
if (!pDoc3 && FAILED(hr)) return;
CComPtr <IHTMLElement> pUserElement;
CComBSTR idName(CT2OLE(_T("kw"))); //获取编辑框元素ID
hr = pDoc3->getElementById(idName, &pUserElement);
if (FAILED(hr) ||!pUserElement) return;
pUserElement->put_innerText(CComBSTR("新网页")); //写入字符串
CComPtr <IHTMLElement> pBtnElement;
CComBSTR idBtnName(CT2OLE(_T("su")));//获取表单按钮的元素ID
hr = pDoc3->getElementById(idBtnName, &pBtnElement);
if (FAILED(hr) || !pBtnElement) return;
pBtnElement->click(); //模拟点击百度按钮进行搜索
//----------------------------------------------------------------------------------
//获取点击百度按钮之后的所有链接
Sleep(); //加载完毕新打开的网页
//再次重新获取,但是得到的链接还是原来400电话里面的,而不是新网页里的。
CComQIPtr <IHTMLDocument2, &IID_IHTMLDocument2> spDoc2 = m_web.get_Document();
GetAllLinks(spDoc2);
}

简单解释一下:就是获取百度搜索框的接口,之后向里面输入关键字:“新网页”,之后再获取【百度一下】按钮的接口,调用这句话 pBtnElement->click(); 进行点击事件的触发,说白了,就是在当前页面中搜索 “新网页” 这个关键字。
之后,调用 Sleep(5000); 等待一会新页面加载完成,再次调用 m_web.get_Document(); 获取当前网页的 document 文档接口,然后调用 GetAllLinks(spDoc2); 函数分析出当前页面的所有搜索结果的URL链接,显示在软件下面的列表中,如下图:

但是,问题来了,大家仔细看上面的图,列表中显示的URL链接都是上一个网址搜索 “400电话” 关键字的结果,不是之后搜索的关键字 “新网页” 的网址链接,这是怎么回事儿呢?跟我们要的结果不一致啊。。。
我还特意调用了 Sleep(5000),等待了 5 秒钟 呢,怎么结果还是不对?

于是乎。。。东奔西走,谷歌搜索了一大堆,还是没找到结果,到微软官方MSDN也没发现什么猫腻,到底是怎么回事儿呢,正准备要放弃的时候,忽然灵感来了,想一想,WebBrowser 走的是当前的主界面的 UI 线程,所以,他访问网页的过程也是在这个主界面的线程中来执行的,那么我们 Sleep(5000); 就没有意义了,不仅会卡住主界面线程,也同时会卡住 WebBrowser。当程序调用完 GetAllLinks(spDoc2); 这条语句之后可能新页面还没加载完,所以获取子链接的结果肯定是上一个页面的。

于是按照这一思想,我把【获取测试】按钮响应函数中的以下几句话注释掉:

Sleep(); //加载完毕新打开的网页
CComQIPtr <IHTMLDocument2, &IID_IHTMLDocument2> spDoc2 = m_web.get_Document();
GetAllLinks(spDoc2);

即,不让他 Sleep 了,也不让他在当前的这个按钮的响应函数中去获取新页面中所有的子链接,直接触发【百度一下】按钮点击事件之后就完事儿了。
接着,我再界面上再添加一个按钮,命名为【再测试下】,在这个按钮的响应函数中添加如下代码:

CComQIPtr <IHTMLDocument2, &IID_IHTMLDocument2> spDoc2 = m_web.get_Document();
GetAllLinks(spDoc2);

即,在这个【再测试下】按钮的响应函数中进行获取新页面中的所有子链接,看看能否成功!结果呢?哈哈,当然是成功啦,如下图:

看到了吧,这回列表中显示的已经是新页面的网页子链接了。。。

好了,文章就写到这吧,希望其他遇到相同问题的网友看到这篇文章,少走弯路!

相关工程源码下载见:http://www.cctry.com/thread-254314-1-1.html

WebBrowser之获取跳转页面的Document接口源码的更多相关文章

  1. 一个页面通过iframe,获取另一个页面的form

    document.getElementsByTagName("iframe")[0].contentWindow.document.forms[0].submit(); var z ...

  2. [源码]一键获取windows系统登陆密码vc6版源码

    [源码]一键获取windows系统登陆密码vc6版源码支持:XP/2000/2003/WIN7/2008等 此版本编译出来的程序体积较小几十KB... 而vs版则1点几M,体积整整大了2-30倍对某些 ...

  3. PHP 获取上一个页面的url

    php $_SERVER["HTTP_REFERER"]变量可以获取上一个或前一个页面的URL地址. 比如有一个a.php页面,这个页面上有一个链接指向b.php页面,如果我们在a ...

  4. 获取上一个页面的data

    let pages = getCurrentPages();// 获取页面栈 let current = pages[pages.length - 1]; // 当前页面 let url = curr ...

  5. iOS新手引导页的实现,源码。

    /*.在Main.storyboard中找到,ScrollView和PageControl并添加到ViewController中. .在ScrollView中添加ImageView,新手引导页有几个图 ...

  6. Unity上一页下一页切换功能实现源码(仅供参考)

    在做项目时我们有时需要实现切换上一页下一页图片,切换上一首下一首歌曲等等类似的功能.这里写了个简单的实现源码(仅供参考),要是有更好的方法欢迎提出来,共同进步~ 以切换上一页下一页图片为例: usin ...

  7. 反编译获取线上任何微信小程序源码(转)

    看到人家上线的小程序的效果,纯靠推测,部分效果在绞尽脑汁后能做出大致的实现,但是有些细节,费劲全力都没能做出来.很想一窥源码?查看究竟?看看大厂的前端大神们是如何规避了小程序的各种奇葩的坑?那么赶紧来 ...

  8. java_爬虫_获取经过js渲染后的网页源码

    md 弄了一天了……(这个月不会在摸爬虫了,浪费生命) 进入正题: 起初是想写一个爬虫来爬一个网站的视频,但是怎么爬取都爬取不到,分析了下源代码之后,发现源代码中并没有视频的dom 但是在浏览器检查元 ...

  9. 手指向上滑动跳转页面的JQ方法

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

随机推荐

  1. srcset

    <div id="pg-334-2" class="panel-grid panel-has-style"> <div style=" ...

  2. Xubuntu 计划从 19.04 版本开始停止提供 32 位安装镜像(XDE/LXQt的 Lubuntu 成为了目前唯一仍然提供 32 位安装镜像的 Ubuntu 桌面发行版)

    Ubuntu 17.10 以及其他许多 *buntu 衍生品都已在今年早些时候停止提供 32 位安装镜像.但其中有一个依然坚持提供适用于 i386 架构的镜像,它就是 Xubuntu,但现在 Xubu ...

  3. android studio 使用

    java5-7适用android,java8对安卓支持不好. mac osx 需要安装jdk8, google Nexus模拟器, Intellij是JetBrains发布的. Intellij有2个 ...

  4. luogu 3951 小凯的疑惑

    noip2017 D1T1 小凯的疑惑 某zz选手没有看出这道结论题,同时写出了exgcd却不会用,只能打一个哈希表骗了30分 题目大意: 两个互质的正整数a和b,求一个最小的正整数使这个数无法表示为 ...

  5. 【Beijing 2010】 次小生成树

    [题目链接] 点击打开链接 [算法] 首先,有一个结论 : 一定有一棵严格次小生成树是在最小生成树的基础上去掉一条边,再加上一条边 这个结论的正确性是显然的 我们先用kruskal算法求出最小生成树, ...

  6. WPF获取原始控件样式

    要获取WPF控件的原始样式,需要我们安装Blend for Visual Studio. 然后,我们打开Blend for Visual Studio,创建一个WPF项目. 然后,我们向页面拖动一个B ...

  7. POJ2127 Greatest Common Increasing Subsequence

    POJ2127 给定两个 整数序列,求LCIS(最长公共上升子序列) dp[i][j]表示A的A[1.....i]与B[1.....j]的以B[j]为结尾的LCIS. 转移方程很简单 当A[i]!=B ...

  8. 【废弃】【WIP】JavaScript Object

    创建: 2017/11/03 废弃: 2019/02/19 重构此篇.原文归入废弃  增加[废弃中]标签与总体任务 结束: 2019/03/03 完成废弃, 删除[废弃中]标签, 添加[废弃]标签 T ...

  9. [Qt Creator 快速入门] 第2章 Qt程序编译和源码详解

    一.编写 Hello World Gui程序 Hello World程序就是让应用程序显示"Hello World"字符串.这是最简单的应用,但却包含了一个应用程序的基本要素,所以 ...

  10. Hdu 4612 Warm up (双连通分支+树的直径)

    题目链接: Hdu 4612 Warm up 题目描述: 给一个无向连通图,问加上一条边后,桥的数目最少会有几个? 解题思路: 题目描述很清楚,题目也很裸,就是一眼看穿怎么做的,先求出来双连通分量,然 ...