工作需要同時內嵌Chrome、IE,相較於IE,CEF開源簡單多了,調用IE費了點功夫研究。
重點記述 在 qt 中,實現 js 與 客戶端之前互動相互調用,代碼資料根據網站整理並測試
內嵌調用IE 需要引入 QT += axcontainer (具體調用 IE 略過)
1、qt 調用 js,該調用方法比較簡單
QAxObject *document = ui->axWidget->querySubObject("Document");
if(!document)
return ;
QAxObject *parentWindow = document->querySubObject("parentWindow");
{
QAxObject obj(&m_call, this);
parentWindow->dynamicCall("SaveCppObject (QAxObject*)", obj.asVariant());// 見 qt 幫助文檔, 詳細介紹了支持的類型
}
2、js 調用 qt,目前整理並測試的有三種方式
- 先通過 qt 調用 js 方法,將 IDispatch 指針對象,傳入 js 中,js保存並可以在後續引用(問題:當頁面刷新,需要在刷新方法內再次 傳入 IDispatch 指針對象)
- js 主動調用 qt,通過 window.external.GetProcessID() 方式調用
- 寫 activeX ,js 中 通過<object>對象調用(經測試後發現,稍微複雜,需要實現註冊該activeX,或者 qt 主動調用該activeX)
2.1 qt 調用 js 方法,以實現調用 qt
2.1.1 qt 部分寫法
- 繼承 IDispatch,主要是爲了實現其內QueryInterface、GetIDsOfNames、Invoke三個方法
- 調用(1),實現將 該指針傳遞給 js
2.1.2 js 部分寫法
var cpp_obj = null;
// 該方法右 qt 主動調用
function SaveCppObject(val) {
cpp_obj = val;
alert(val);
val.ShowMessageBox("你好,我是Javascript,你是誰?");
}
function test_method2() {
if (cpp_obj && typeof(cpp_obj) != "undefined") {
var processId = cpp_obj.GetProcessID();
alert(processId);
}
else {
alert("cpp_obj對象不存在,需要qt先調用註冊IDispatch纔可以");
}
}
2.2 js 主動調用 qt,通過 window.external.xx 方式調用
2.2.1 qt 部分寫法
- 繼承 IDispatch,主要是爲了實現其內QueryInterface、GetIDsOfNames、Invoke三個方法
- 繼承IDocHostUIHandler,主要是爲了實現 GetExternal 方法(目的:通過繼承該js,可以捕獲 js 調用 qt)
- 繼承public QAxAggregated,public IObjectSafety 網上說法是繞過安全認證
2.2.2 js 部分寫法
function test_method1() {
try {
alert(window.external.GetProcessID());
}
catch (e) {
alert(e.message);
}
}
示例代碼:https://download.csdn.net/download/beyond0851/10872345
參考文檔:
QAxWidget 調用ocx控件之 js雙向通信
https://blog.csdn.net/tianweibooo/article/details/81003188
繼承CAxHostWindow, IDocHostUIHandler 控制瀏覽器界面
https://www.xuebuyuan.com/1285504.html
CEF3開發者系列之外篇——IE中JS與C++交互
https://www.cnblogs.com/guolixiucai/p/4957521.html
瀏覽器編程之二IE控件與JS交互篇
https://blog.csdn.net/river_mumu/article/details/8692666
(******) VC與JavaScript交互(三) ———— JS調用C++
https://blog.csdn.net/charlessimonyi/article/details/50984903