別のスレッドでファイルをダウンロードするフローティングダイアログ
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 を実行してダイアログを表示します。
|