天天看點

讓CEF架構支援 COM/ActiveX控件

通常各種浏覽器都支援某種插件機制,以友善擴充頁面腳本的能力,豐富頁面内容。

比如:對于 Trident 核心(IE浏覽器),可以使用 ActiveX控件。

對于Gecko核心(火狐浏覽器)和Webkit/Blink核心(Safari,Chrome系列浏覽器),可以使用NPAPI插件,以及PPAPI插件。

遺憾的是,各種浏覽器的插件機制不僅不能夠相容統一,而且高版本的Chrome系列浏覽器非但不再支援傳統的NPAPI插件,

甚至PPAPI插件(Flash除外)亦難以部署釋出,通常僅能用作本機調試之用,實為無奈。╮(╯﹏╰)╭

這裡筆者不打算讨論如何統一各類浏覽器插件機制的問題,貌似有現成的廠商做這個,比如 某廠的 "牛插件"

就是通過WebSocket實作的插件與浏覽器的通信調用。

 隻簡要介紹下在CEF架構中支援 COM/ActiveX控件,以相容傳統IE核心ActiveX插件的方法。

項目位址:

             https://github.com/tankaishuai/Win32exts_for_CEF3

為了讓CEF架構支援 COM/ActiveX控件,隻需要 在渲染程序的 OnContextCreated()回調中添加如下代碼:

virtual void OnContextCreated(...) {

    CefRefPtr<CefV8Value> windowObject = context->GetGlobal();

    //

    // 僅僅隻需要調用 RegisterActiveXObject_CEF() API 即可.

    //

    typedef bool (* RegisterActiveXObject_CEF_T)(CefV8Value *windowObject, HWND hWnd, LPVOID lpReserved);

    typedef void (* SetRemoteBrowser_CEF_T)(HWND hWnd);

    WCHAR szPath[MAX_PATH] = { 0 };

    GetModuleFileNameW(NULL, szPath, MAX_PATH);

    PathRemoveFileSpecW(szPath);

    PathAppendW(szPath, L"win32exts_web.dll");

    HMODULE hDll = LoadLibraryW(szPath);

    if (hDll){

        RegisterActiveXObject_CEF_T pfnRegisterActiveXObject_CEF =

            (RegisterActiveXObject_CEF_T)GetProcAddress(hDll, "RegisterActiveXObject_CEF");

        if (pfnRegisterActiveXObject_CEF){

            pfnRegisterActiveXObject_CEF(windowObject, g_hRemoteBrowser, NULL);

        }

          //

          // Set the browser window handle for ActiveX Control.

          //

          SetRemoteBrowser_CEF_T pfnSetRemoteBrowser_CEF =

                (SetRemoteBrowser_CEF_T)GetProcAddress(hDll, "SetRemoteBrowser_CEF");

          if (pfnSetRemoteBrowser_CEF) {

                pfnSetRemoteBrowser_CEF(g_hRemoteBrowser);

          }

    }

}

然後,該CEF浏覽器即支援了在js腳本 中加載ActiveX控件的能力,

讓CEF架構支援 COM/ActiveX控件

建立控件示例代碼:

讓CEF架構支援 COM/ActiveX控件
讓CEF架構支援 COM/ActiveX控件
讓CEF架構支援 COM/ActiveX控件

示例用法如下:

    //建立遊戲控件

    bbb = new ActiveXControl("Tank90Control.Tank90", -2)

    bbb.Ax_MoveWindow(50, 50, 600, 600)

    bbb.Ax_ShowWindow(1)

    //external.Log(bbb.Ax_ListSym())

    //自動開始遊戲

    bbb.StartGame()

加載普通COM組建示例:

var active_x = new ActiveXObject("prog_appid");     //建立COM

ret = active_x.func1(1, 2);                                         //調用方法

ret = active_x.func2( "test", false, 0 ); 

與IE中的用法基本一緻。實作了不改動 ActiveX控件 情況下的完美支援。可喜可賀可喜可賀。。