轉載請說明出處,謝謝~~
昨天封裝了基於webkit的wke瀏覽器內核,做成了duilib的瀏覽器控件,實現了瀏覽功能,但是單單的瀏覽功能還不滿足需求,在我的仿酷狗項目中樂庫的功能需要與瀏覽器互交。
大家知道在使用酷狗瀏覽器時,右側的樂庫,當我們選中了某個音樂,這時酷狗就會去緩沖並且播放響應的歌曲。本身瀏覽器與c++的窗體是不會互交的。而酷狗使用的IE瀏覽器內核,在c++代碼中對CHtmlView類進行繼承和重寫,並完成IDispatchEx接口的相關工作后,就可以開啟IE內核的互交的功能,可以控制網頁的元素,也可以讓網頁元素去調用c++的代碼。
而我現在是用來wke內核, 而這個wke內核網上使用的人並不多,所以相關文檔也好,我要給它增加與c++互交的功能就需要自己去探索了。
閱讀了好幾遍wke的頭文件后有了些眉目,我看到原作者的WkeBrowser demo中,使用了RunJs函數來隱藏掉網頁的滾動條,然后進行對網頁的截圖工作,這一點給了我啟發,也就是使用js腳本命令去控制wke內核中顯示的網頁,先看看runJs函數的原型:
virtual jsValue runJS(const wchar_t* script) = 0; 函數比較簡單,通過名字可以看到參數script是傳遞js命令的字符串指針,而函數返回一個jsValue類型的值,這是wke內核自定義的類型,這個返回值可以通過wke內核提供的其他函數去解析出相關的值。
我在昨天封裝的瀏覽器控件類CWkeWebkitUI增加了一個RunJs接口,接口原型為wstring RunJS(wstring strValue);接口的函數體為
在接口中我調用wke內核去執行js命令,然后把他的返回值進行處理,最后得到一個字符串再傳回來。然后對這個接口的可用性進行測試。 測試命令為window.scrollTo(0,100)。這條命令的意識讓滾動條向下滾動100單位。

可以看到執行完js命令后瀏覽器的確向下滾動了100單位,證明這樣是可行的,接下來我有執行了幾條命令:
window.scrollTo(0,document.body.scrollHeight)
這幾條命令分別測試隱藏滾動條,修改或者獲取input標簽內的內容等,都測試通過了,到此我完成了一般的互交功能,也就是用c++控制網頁。
接下來是完成網頁控制c++的互交部分,這部分讓我比較頭疼,因為沒有資料去參考,讀wke頭文件后發現了三個可疑的函數,原型為
WKE_API void jsBindSetter(const char* name, jsNativeFunction fn); /*set property*/
從名字上判斷是js綁定函數,這個很有可能是我想要的東西,可以沒有demo做參考,我只能自己琢磨,測試了幾個小時候明白了這個函數的用法。那就是在c++創建wke內核實例前,調用jsBindFunction函數,函數的第一個參數是js中的函數名,第二個參數是對應的c++的函數的地址,第三個參數是傳遞的參數的個數,比如我在c++中申明了一個函數名為js_msgBox,原型為jsValue JS_CALL js_msgBox(jsExecState es),那么我編寫的jsBindFunction的代碼為jsBindFunction("msgBox", js_msgBox, 2); 緊接着在網頁的js代碼中找一個合適的出發互交的地方,寫上代碼,比如這個
注意這個函數的名字要和 jsBindFunction語句的第一個參數保持一直。那么當用wke內核接在了這個網頁,並且出發了我定義的NagivOut函數是,就自動調用msgBoxz這個函數,這個函數會被wke轉發到c++,回調js_msgBox函數,我在js_msgBox函數中彈出對話框顯示了msgBox函數傳進來的參數,結構成功了 ,至此js主動調用c++的功能也實現了。
再比如在我們的代碼中使用RunJs函數執行這條js語句:
- document.getElementById("navig-01_").onclick=test
這樣就動態得讓id為navig_01_的元素的onclick事件綁定到test()函數,而test函數里可以再調用c++的函數,實現了c++綁定到網頁的元素的事件。還有很多功能都可以使用我介紹的這兩種方法來實現,我就不一一介紹了,大家自己使用吧。
通過這篇日志可以看到,wke使用起來很簡單,也很方便,只需要少量代碼就可以實現c++與webkit內核的互交。
貼一張效果圖