| 別のスレッドでファイルをダウンロードするフローティングダイアログFloating dialog to download file in another threadHTML Dialog fourth-HTML-dialog 概要このチュートリアルでは、次のようにダイアログを構築します。 
    入力/出力ボックスと2つのボタンを備えたフローティングダイアログ。ユーザがURLを入力した後、ダウンロードするファイルを指定し、Origin別のスレッドでファイルをダウンロードし、Originを使用して他のことを実行できるようにします。ダイアログはダウンロードステータスを更新します。ユーザはダウンロードスレッドを中止できます。 必要なOriginのバージョン: Origin 2024b以降 ダイアログ用HTMLページの作成
    コードビルダを開き、新しいHTMLファイルを作成してDownloadFile.htmlという名前でDownload Exampleフォルダに保存します。次のコードをコピーし、DownloadFile.html内に貼り付けます。
      
<!doctype html>
<html>
        <head>
                <meta charset="utf-8" />
                <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
        </head>
        <body>
                <input id="path" style="width:350px" placeholder="input file url and click Download" onchange="On_Path()"></input>           
                <br>
                <input type="button" id="btnDownload" value="Download" onclick="Invoke_Download()"/>            
                <input type="button" id="btnAbort" value="Abort" onclick="Invoke_Abort()"/>     
                <br>
                <input id="hint" style="width:350px;border:none" disabled="true"></div>
        </body>
        <script>
                function On_Path() {
                        document.getElementById('btnDownload').disabled = false;
                        document.getElementById('hint').value = "";
                }
                function Invoke_Download() {
                        var Result = window.external.ExtCall("DownloadOnlineFile", document.getElementById('path').value);
                        document.getElementById('hint').value = Result;
                        document.getElementById('btnDownload').disabled = true;
                }             
                function Invoke_Abort() {
                        window.external.ExtCall("DownloadAbort");
                        document.getElementById('btnDownload').disabled = false;
                }
                function Update(str) { document.getElementById('hint').value = str; }
        </script>    
</html>
        
          | Note: このコードは、作成したHTMLページに機能を追加します。 
              On_Path():ダウンロードボタンを有効にし、ユーザ入力のファイルURLの後にメッセージを出力Invoke_Download():ユーザがダウンロードボタンを押したイベントに応答Invoke_Abort():ユーザが中止ボタンを押したイベントに応答Update():ダウンロードメッセージの出力 |  この手順が完了したら、WebブラウザでDownloadFile.htmlを開くと、HTMLページが表示されます。 
    
      |  | 関数 Invoke_DownloadとInvoke_Abort、window.external.ExtCallはOrigin Cを呼び出すために使用されます。window.external.ExtCallの詳細については、こちらを参照してください。 |  フローティングHTMLダイアログの作成これで、Origin Cコードを編集してHTMLダイアログを作成する準備が整いました。 
    コードビルダで、DownloadDlg.cppという名前の新しいcppファイルをDownload Exampleフォルダに作成します。必要なヘッダを含めます。
      
#include <Origin.h>
#include <../OriginLab/DialogEx.h>
#include <../OriginLab/HTMLDlg.h>
HTMLダイアログクラスDownloadDialogを宣言し、DownloadDialogのポインタを定義します。このポインタは、HTMLダイアログをフローティングにするためのものです。
      
class DownloadDialog;
static DownloadDialog* s_pDLDlg;
HTMLDlgクラスからDownloadDialogクラスを派生し、メソッドGetInitURL()内のHTMLページをポイントします。
class DownloadDialog: public HTMLDlg
{
protected:
        string GetInitURL(){return GetFilePath(__FILE__) + "DownloadFile.html";}
        string GetDialogTitle(){return "";}
        BOOL GetDlgInitSize(int& width, int& height){ width = 400; height = 150; return true; }
};
モードレスダイアログボックスを呼び出すCreate関数を追加します。
      
public:
        int Create()
        {
                InitMsgMap();
                int nRet = Create(NULL, 0);
                Visible = true;
                return nRet;
        }
クラスDownloadDialog内のダイアログメッセージをマップして、処理するイベントと処理する関数を指定します。イベントに応答するイベントハンドラメソッドを追加します。
protected:
EVENTS_BEGIN_DERIV(HTMLDlg)
        ON_DESTROY(OnDestroy)
        ON_IDLE(OnIdle)
EVENTS_END_DERIV
        BOOL OnDestroy()
        {
                BOOL bRet = HTMLDlg::OnDestroy();
                
                delete this;
                s_pDLDlg = NULL;
                return bRet;
        }
        BOOL OnIdle()
        {
                string strMsg, strJS;
                double err;
                LT_get_var("@OCDL", &err); 
                if( err < 0 ) 
                {
                        if( !m_strFile.IsEmpty() )
                        {
                                switch(err)
                                {
                                case OHTTP_E_INVALID_URL:
                                        strMsg = "Invalid URL"; 
                                        break;
                                case OHTTP_E_USER_CANCEL: 
                                        strMsg = "Abort";
                                        break;
                                default:
                                        strMsg.Format("err = %g", err);
                                }
                                m_strFile.Empty();
                        }
                }
                else if( err == 0 ) 
                {
                        if( m_strFile.IsFile() )
                        {
                                strMsg.Format("download complete: %s", m_strFile);
                                m_strFile.Empty();
                        }                     
                }
                else
                        strMsg.Format("downloading %.2f%%", err);
                
                
                if( !strMsg.IsEmpty() )
                {
                        strJS.Format("Update(\'%s\')", strMsg);//call Update() in html code                   
                        CallJavaScript(strJS);
                }
                return TRUE;
        }
        
          | Note: Originがアイドル状態のときに OnIdle()がトリガーされ、ダウンロードステータスを取得し、DHtmlControlクラスのメンバ関数CallJavaScript()によってJavaScriptUpdate()を呼び出します。 |  Origin CにJavaScript呼び出し可能なプロトタイプの追加このセクションでは、ダイアログクラスDownloadDialog内でメソッドを追加します。 
    DownloadOnlineFile()はユーザがDownloadキーを押したときにファイルをダウンロードするために、JavaScript関数Invoke_Download()で呼び出されます。DownloadAbort()は、ユーザがAbortキーを押したときにダウンロードスレッドを中止するためにJavaScript関数Invoke_Abort()で呼び出されます。 
    ダイアログクラス内にメソッドと DECLARE_DISPATCH_MAP を追加します。
      
public:      
        DECLARE_DISPATCH_MAP
        string DownloadOnlineFile(string strURL) 
        {
                string strMsg, strName = GetFileName(strURL);
                m_strFile = GetOriginPath(ORIGIN_PATH_USER) + strName;
                BOOL bWait = FALSE, bShowMsg = TRUE; // ファイルを別のスレッドでダウンロードするとダウンロード完了後にメッセージログにメッセージが表示
                double err;
                if( okutil_http_download(strURL, m_strFile, 0, 0, FALSE, bWait, bShowMsg) )
                {
                        LT_get_var("@OCDL", &err); 
                        strMsg.Format("previous download not completed %.2f%%", err);
                }
                else
                        strMsg = "downloading...";
                return strMsg;
        }     
        void DownloadAbort(){ LT_set_var("@OCDL", 2); }
private:
        string m_strFile;
OriginCダイアログクラスのメソッドをこのHTMLダイアログにマッピングします。
      
BEGIN_DISPATCH_MAP(DownloadDialog, HTMLDlg)
    DISP_FUNCTION(DownloadDialog, DownloadOnlineFile, VTS_STR, VTS_STR)
    DISP_FUNCTION(DownloadDialog, DownloadAbort, VTS_VOID, VTS_VOID)
END_DISPATCH_MAP
        
          | Note: 
              DISP_FUNCTIONの詳細はこちらをご覧ください。okutil_http_download()の詳細はこちらを参照してください。システム変数 @OCDL はダウンロードステータスを返し、@OCDL> 1はダウンロードスレッドを中止します。 |  ダイアログの起動これで、ダイアログを起動する準備ができました。 
    メイン機能の追加
      
int DownloadDlg(int nMsg, DWORD dwCntrl = 0, LPVOID lpData = NULL)
{
        bool bClose = OMSG_CLOSE==nMsg? true:false;
        if(bClose)
        {
                if(s_pDLDlg)
                {
                        Window winDlg = s_pDLDlg->GetWindow();
                        if(winDlg)
                                winDlg.SendMessage(WM_CLOSE);
                        delete s_pDLDlg;
                        s_pDLDlg = NULL;
                }
                return 0;
        }
        
        if(!s_pDLDlg)
        {
                s_pDLDlg = new DownloadDialog();
                s_pDLDlg->Create();
        }
        return 0;
}
void open_downloaddlg(){DownloadDlg(OMSG_OPEN);}
すべてのコードを保存してビルドします。open_downloaddlgを実行してダイアログを表示します。 |