Chrome HTMLダイアログとJavaScriptの通信

概要

このチュートリアルでは、CEF (Chromium Embedded Framework) HTMLコントロールダイアログを構築して、Java Scriptと非同期的または同期的に通信する方法を示します。

必要なOriginのバージョン: Origin 2024b以降

ダイアログ用CEF HTMLページの作成

  1. コードビルダを開き、新しいHTMLファイルを作成してCefSimpleHtmlDlg.htmlという名前でCefSimpleHtmlDlgフォルダに保存します。
  2. 次のコードをコピーし、CefSimpleHtmlDlg.html内に貼り付けます。
    <!doctype html>
    <html>
    <head>
            <meta charset="utf-8">
            <script src="http://olab/resource/programfolder/JS/jquery.js"></script>
            <script src="http://olab/resource/programfolder/JS/olab.js"></script>
            <script language="JavaScript">
            function setup() {
            }
            
            function alertFromOrigin(msg) {
                    alert(msg)
                    window.O.OnCallbackFromOrigin(msg)
            }
            
            // 非同期で Origin にクエリを送信する。非同期メソッドの使用を推奨
            function sendMessageAsync() {
                    window.O.OnDoSomethingReturnObject(3, document.getElementById("messageAsync").value, function(response) {
                            if(response) {
                                    document.getElementById('resultAsync').value = 'Response: '+JSON.stringify(response);
                            }
                            else {
                                    document.getElementById('resultAsync').value = 'Error';
                            }
                            
                    });
            }
    
            // 同期を使用して Origin にクエリを送信する。同期メソッドの使用は推奨されず、代わりに非同期メソッドが使用される。
            function sendMessageSync() {
                    let response = window.O.OnDoSomethingReturnObject(3, document.getElementById("messageSync").value);
                    if(response) {
                            document.getElementById('resultSync').value = 'Response: '+JSON.stringify(response);
                    }
                    else {
                            document.getElementById('resultSync').value = 'Error';
                    }
            }
            </script>
    </head>
    
    <body bgcolor="white" onload="setup()">
            <form id="form">
                    Asynchronous Message: <input type="text" id="messageAsync" value="This is Asynchronous Message">
                    
                    <br/><input type="button" onclick="sendMessageAsync();" value="Send Message to Origin Asynchronous">
                    <br/>You should see the reverse of your Asynchronous message below:
                    <br/><textarea rows="10" cols="40" id="resultAsync"></textarea>
                    
                    <br/>Synchronous Message: <input type="text" id="messageSync" value="This is Synchronous Message"> <span style="color:red">(not recomment to use Synchronous methods, use Asynchronous methods instead)</span>
                    <br/><input type="button" onclick="sendMessageSync();" value="Send Message to Origin Synchronous">
                    <br/>You should see the reverse of your Synchronous message below:
                    <br/><textarea rows="10" cols="40" id="resultSync"></textarea>
            </form>
    </div>
    </body>
    </html>
    
    Note:
    • JavaScriptはOriginの関数 sendMessageAsync と非同期的に通信し、関数 sendMessageSync では同期的に通信します。CEF HTMLダイアログでは非同期メソッドの使用を推奨します。

この手順が完了したら、WebブラウザでCefSimpleHtmlDlg.htmlを開くと、HTMLページが表示されます。

CEF HTMLダイアログの作成

これで、Origin Cコードを編集してCEF HTMLダイアログを作成する準備が整いました。

  1. コードビルダで、CefSimpleHtmlDlg.cppという名前の新しいcppファイルをCefSimpleHtmlDlgフォルダに作成します。
  2. 次のコードをコピーし、CefSimpleHtmlDlg.cpp内に貼り付けます。
    #include <Origin.h>
    #include <../OriginLab/DialogEx.h>
    #define _USE_CEF_AS_HTML_CTRL
    #include <../OriginLab/HTMLDlg.h>
    
    #define CEFSIMPLE_HTML_FILE "CefSimpleHtmlDlg.html"
    #define CEFSIMPLE_TITLE _L("CefSimpleHtmlDlg")
    
    class CefSimpleHtmlDlg;
    static CefSimpleHtmlDlg *s_pDlg = NULL;
    
    class CefSimpleHtmlDlg: public HTMLDlg
    {
    protected:
            //HTML ファイルへのフルパスとファイル名を返す
            string GetInitURL()
            {
                    string strFile = __FILE__;
                    return GetFilePath(strFile) + CEFSIMPLE_HTML_FILE;
            }
            //ダイアログのタイトルを返す
            string GetDialogTitle() {return CEFSIMPLE_TITLE;}
    
            // ダイアログが作成された後、表示される前に呼び出される
            BOOL OnInitDialog()
            {
                    if( !HTMLDlg::OnInitDialog() ) //ベースクラスを呼び出す
                            return FALSE;
                    
                    ModifyStyle(0, WS_MAXIMIZEBOX|WS_MINIMIZEBOX);
                    ModifyStyleEx(0, WS_EX_DLGMODALFRAME);
    
                    return TRUE;
            }
            void OnHTMLReady() //上書き
            {
                    HTMLDlg::OnHTMLReady();
                    
                    CallJavaScript("alertFromOrigin('Hello!')");
            }
            BOOL OnDestroy()
            {
                    HTMLDlg::OnDestroy();
                    return TRUE;
            }
            void OnMinMaxInfo(MINMAXINFO* lpMMI)
            {
                    lpMMI->ptMinTrackSize.y = CheckConvertDlgSizeWithDPI(450, false);
                    lpMMI->ptMinTrackSize.x = CheckConvertDlgSizeWithDPI(900, true);
            }
            BOOL OnDlgResize(int nType, int cx, int cy) // ダイアログのサイズを変更する場合、ダイアログ内の各コントロールのサイズと位置を再初期化する必要あり
            {
                    if( !IsInitReady() )
                            return false;
    
                    // MoveControlsHelper _temp(this); //ダイアログのサイズを変更したときにちらつく場合は、この行のコメントを解除
                    HTMLDlg::OnDlgResize(nType, cx, cy); //ダイアログに HTML コントロールを配置
    
                    if( !IsHTMLDocumentCompleted() ) //HTMLコントロールの状態を確認
                            return FALSE;
    
                    return TRUE;
            }
    public:
            DECLARE_DISPATCH_MAP
    
            EVENTS_BEGIN_DERIV(HTMLDlg)
                    ON_INIT(OnInitDialog)
                    ON_DESTROY(OnDestroy)
                    ON_SIZE(OnDlgResize)
                    ON_GETMINMAXINFO(OnMinMaxInfo)
            EVENTS_END_DERIV
    
    
            //戻りオブジェクトは関数名を"Object"で終わるよう設定する必要あり
            struct STRetObjs
            {
                    int id;
                    string name;
                    string message;
                    
                    string GetJson()
                    {
                            string strjson;
                            JSON.ToString(*this, strjson);
                            return strjson;
                    }
            };
            string OnDoSomethingReturnObject(int nId, string strMessage)
            {
                    STRetObjs obj;
                    obj.name = "Tom";
                    obj.id = nId;
                    obj.message = strMessage;
                    return obj.GetJson();
            }
                    
            void OnCallbackFromOrigin(string strMessage)
            {
                    //ここで作業を実行して"CallJavaScript("alertFromOrigin('Hello!')");"を呼び出す
                    GetNBoxDisplayInfo displayInfo;
                    displayInfo.lpcszTitle = strMessage;
                    displayInfo.bHideContextHelp = true;
                    GETN_BOX(tr);
                    GETN_STR(message, _L("Message"), strMessage)
                    if(GetNBox(tr, NULL, &displayInfo, GetSafeHwnd()))
                    {
                    }
            }
    
    private:
    };
    
    BEGIN_DISPATCH_MAP(CefSimpleHtmlDlg, HTMLDlg)
            DISP_FUNCTION(NewBookTemplate, OnDoSomethingReturnObject, VTS_BSTRA, VTS_I4 VTS_BSTRA) 
            DISP_FUNCTION(NewBookTemplate, OnCallbackFromOrigin, VTS_VOID, VTS_BSTRA)
    END_DISPATCH_MAP
    
    #pragma labtalk(1) // LT呼び出しのOC関数を有効化
    
    void DoCefSimpleHtmlDlg()
    {
            if(s_pDlg == NULL){CefSimpleHtmlDlg DLG; s_pDlg=&DLG;//dword
            
    
      
                    dwOptions=DLG_no_load_top_left|dlg_no_load_width_height|DLG_hidden;///dlg.doModalEx
                    (GetWindow()
    DoModalEx(GetWindow());s_pDlg
     = NULL;}}
    
    
    
    Note:

    関数OnDoSomethingReturnObjectJSON.ToString で文字列に構造体を作成し、Javaスクリプトに渡します。次に、JavaスクリプトはJSON.stringify を使用して、構造体のJSON準拠の文字列表現に変更します。

ダイアログの起動

すべてのコードを保存してビルドします。DoCefSimpleHtmlDlg を実行してダイアログを表示します。