为了显示微信登录的二维码,引入了整套QtWebEngine,占用非常大的空间。微信登录二维码有自动刷新动作,这些定义在页面脚本中,所以不能直接自绘二维码方式实现,浏览器少不了。
通过COM组件可以调用系统自带的浏览器,当然是IE啦。Qt提供QAxObject和QAxWidget对象帮助访问COM,(与其说帮助,还不如说越帮越忙)
请注意接下来描述的每一步,在完全理解前,不要擅自调整
1. 创建或者基于已有的Qt设计师界面类,就是有.ui文件的那种。但是奇葩来了,完整的设置通过“设计”是搞不出来的。所以随便拉个QAxWidget吧。
2. 通过用文本编辑器的方式打开对应的ui文件
3. 找到
4. 把界面上的QAxWidget找到,改成如下样式,objectName会在每次用"设计"改ui的时候被覆盖掉(悲剧),control里面的guid是对应IWebBrowser2接口的,固定就那么写。
5. 照着模样做一个WebAxWidget.h。注意,集成QAxWidget的类不能声明Q_OBJECT,会导致activeqt机制里面moc无效,表现看这里stackoverflow
#ifndef WEBAXWIDGET_H #define WEBAXWIDGET_H #include |
6. 在你的ui文件对应的界面类里面,声明槽,注意命名形如 on_WebBrowser_ProgressChange. 其中WebBrowser为前面objectName所写,ProgressChange是回调函数的名字,它的出处是MSDN里面IWebBrowser的声明(好吧,我也是蒙的,在第5中所说的错误状态下,可以即时看到QObject::receivers: No such signal mis::WebAxBrowser::DownloadComplete()这样的提示,就是说你的命名对了,槽就会被调用,而不需要手动去连接).稳妥的办法是去qt sample:webbrowser里面抄几个.
7. 让槽函数转调一个专门处理它的类,我创建了一个WebAxWrapper,把回调处理后转成类似QWebEngineView的信号:loadFinished和loadProgress
8.当然还有load()和url()
9. 最后值得一提的是拿页面源码。找了很多帖子,期间想到Javascript法,结果IHTMLWindow2里面的execScript方法不能拿到返回值,网上文章一大堆,还有反汇编C# InvokeScript()方法的.最后找到了流化方案。我做了一个像QWebEnginePage的toPlainText方法
void WebAxWrapper::toPlainText(void (*f)(const QString &)) { char *output = NULL; QAxObject *document = WebBrowser->querySubObject("Document"); if(document) { IHTMLDocument2 *doc2 = nullptr; document->queryInterface(QUuid(IID_IHTMLDocument2), (void**)&doc2); if (doc2) { IPersistStreamInit *pPSI=NULL; IStream *pStream=NULL; HGLOBAL hHTMLText; if (SUCCEEDED(doc2->QueryInterface(&pPSI))) { const int MaxBuffSize =64*1024; hHTMLText = GlobalAlloc(GMEM_FIXED, MaxBuffSize); CreateStreamOnHGlobal(hHTMLText, TRUE, &pStream); pPSI->Save(pStream, FALSE); LARGE_INTEGER li; li.QuadPart = 0; pStream->Seek(li,0,NULL); output = new char[MaxBuffSize]; output[MaxBuffSize-1] = 0; ULONG readed = 0; pStream->Read((void*)output,MaxBuffSize-1,&readed); output[readed] = 0; pStream->Release(); //GlobalFree(hHTMLText); pPSI->Release(); } doc2->Release(); } } if(output) { qDebug()< |
需要windows的头文件
#include
#include
#include
#include
10. 二维码,其实最后这个不是重点了,直接把我们的页面(http://passport.timelink.cn/wechat/show)显示出来,当发生loadFinished的时候,获取一下当前url,如果不同了,分析一下页面源码,我们的项目在这一步服务器返回一段json,解析并处理就可以了。
ie浏览器右键菜单真是又多又杂...
欢迎访问我们的轻录课项目,以及分课网 http://fenke.timelink.cn