| 1.18.1.5.4 Floating Dialog to download file in another threadFloating dialog to download file in another threadHTML Dialog
 fourth-HTML-dialog SummaryIn this tutorial, you build a dailog works as follows:
  Floating dialog with input/output box and two buttons. After a user input URL specify a file to download,Origin download the file in another thread so that user can use Origin to do other things. Dialog will update download status.  A user can abort downloading thread.
 Minimum Origin Version Required: Origin 2024b Creating an HTML Page for Dialog
 Open Code Builder,  create a new HTML file and save as DownloadFile.html to the folder Download Example.
 Copy the following code and paste it within the 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: This code adds functionality to the HTML page you created above:  On_Path():Enable Download button and output message after a user input file url Invoke_Download(): Respond to the event of a user hitting the Download button Invoke_Abort(): Respond to the event of a user hitting the Abort button Update(): Output download message
 |  Once you finish this step, you can see the html page by opening the DownloadFile.html with a web browser.
 
	|  | In the functions Invoke_DownloadandInvoke_Abort,window.external.ExtCallis used to call Origin C. You can learn more aboutwindow.external.ExtCallfrom here. | 
 Creating an Floating HTML DialogNow you are ready to edit the Origin C code to create an HTML dialog.
 
 In Code Builder, create a new cpp file named DownloadDlg.cpp under the folder Download Example.
 Include the needed headers.
#include <Origin.h>
#include <../OriginLab/DialogEx.h>
#include <../OriginLab/HTMLDlg.h> Declare HTML dialog class DownloadDialog and define a pointer of DownloadDialog. This pointer is to make the HTML dialog floating.
class DownloadDialog;
static DownloadDialog* s_pDLDlg; Derive the HTML dialog class DownloadDialogfrom the classHTMLDlg, and point to the HTML page inside the methodGetInitURL().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; }
}; Add Create function to invoke the modeless dialog box.
public:
	int Create()
	{
		InitMsgMap();
		int nRet = Create(NULL, 0);
		Visible = true;
		return nRet;
	} Map the dialog message inside the class DownloadDialogto specify which events will be handled and which function will be called to handle. Add event handler methods to respond to the event.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: OnIdle()is triggered when Origin is idle, and it will get download status and call JavaScriptUpdate()by a member functionCallJavaScript()of theDHtmlControlclass. |  Adding JavaScript Callable Prototypes in Origin CIn this section, inside your dialog class DownloadDialogyou add method  DownloadOnlineFile(), which is called in JavaScript functionInvoke_Download()in order to download file when the user hit the Download key; DownloadAbort(), which is called in JavaScript functionInvoke_Abort()in order to abort downloading thread when the user hit the Abort key.
 
 Add the method and DECLARE_DISPATCH_MAP inside your dialog class.
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; // download file in a separate thread, and message log will show message after download complete
		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; Map the method of your OriginC dialog class to this HTML dialog.
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:  More details of DISP_FUNCTION can be found here. More details of okutil_http_download()can be found  here. System variable @OCDL return download status, and @OCDL > 1 to abort the downloading thread.
 |  Launching The DialogYou are ready to launch the dialog.
 
 Add main function:
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);} Save all the code and build it.
 Run open_downloaddlgto lauch the dialog. |