Chrome HTMLダイアログとJavaScriptの通信
概要
このチュートリアルでは、CEF (Chromium Embedded Framework) HTMLコントロールダイアログを構築して、Java Scriptと非同期的または同期的に通信する方法を示します。
必要なOriginのバージョン: Origin 2024b以降
ダイアログ用CEF HTMLページの作成
- コードビルダを開き、新しいHTMLファイルを作成してCefSimpleHtmlDlg.htmlという名前でCefSimpleHtmlDlgフォルダに保存します。
- 次のコードをコピーし、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ダイアログでは非同期メソッドの使用を推奨します。
- JavaScriptはOriginの関数
この手順が完了したら、WebブラウザでCefSimpleHtmlDlg.htmlを開くと、HTMLページが表示されます。
CEF HTMLダイアログの作成
これで、Origin Cコードを編集してCEF HTMLダイアログを作成する準備が整いました。
- コードビルダで、CefSimpleHtmlDlg.cppという名前の新しいcppファイルをCefSimpleHtmlDlgフォルダに作成します。
- 次のコードをコピーし、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: 関数
OnDoSomethingReturnObjectはJSON.ToStringで文字列に構造体を作成し、Javaスクリプトに渡します。次に、JavaスクリプトはJSON.stringifyを使用して、構造体のJSON準拠の文字列表現に変更します。
ダイアログの起動
すべてのコードを保存してビルドします。DoCefSimpleHtmlDlg を実行してダイアログを表示します。