CDHtmlDialog : JavaScript calling C++ Functions
Hello there,
I am developing an app with CDHtmlDialog that will have a user interface developed in HTML and JavaScript (JS) and CSS.
I am able to make calls from my C++ code to JS. But not sure how i can make calls from JS to C++ code.
Can anyone tell me how to do that?
Any sample code will help.
Thanks in advance.
Re: CDHtmlDialog : JavaScript calling C++ Functions
Re: CDHtmlDialog : JavaScript calling C++ Functions
The simple solution:
Create a single IDispatch interface for all your C++ stuff the JS needs to interact with, the attach that IDispatch to the external object . Override OnGetExternal() and return your IDispatch (don't forget to AddRef it).
JS code can then use stuff like:
Code:
// call a function
window.external.myfunction(param1,param2).
// Get set a variable
window.external.myvariableint = 14;
var somestring = window.external.myvariablestring;
Re: CDHtmlDialog : JavaScript calling C++ Functions
Hey oReubens,
Do you have some sample code to share?
Thanks
Re: CDHtmlDialog : JavaScript calling C++ Functions
Unfortunately, no. While I have used the above technique, copyright/legal issues prevent me from sharing that code.
You can use ATL to help you create an IDispatch interface. You can do it without ATL (I did, and it's horrible), but you'll have to do a lot of searching to get it all tied together.
note: you don't need to register your IDispatch with anything, just pass it into the OnGetExternal()
1 Attachment(s)
Re: CDHtmlDialog : JavaScript calling C++ Functions
HtmlDlgTest.htm
Code:
. . .
<BODY ID=CHtmlDlgTestDlg BGCOLOR=LIGHTGREY style="font-family:MS Shell Dlg;font-size:8" onload="window.external.Test()">
. . .
Code:
// CHtmlDlgTestDlg dialog
class CHtmlDlgTestDlg : public CDHtmlDialog
{
public:
. . .
void Test();
. . .
DECLARE_DISPATCH_MAP()
};
Code:
// HtmlDlgTestDlg.cpp : implementation file
. . .
BEGIN_DISPATCH_MAP(CHtmlDlgTestDlg, CDHtmlDialog)
DISP_FUNCTION(CHtmlDlgTestDlg, "Test", Test, VT_EMPTY, VTS_NONE)
END_DISPATCH_MAP()
. . .
BOOL CHtmlDlgTestDlg::OnInitDialog()
{
CDHtmlDialog::OnInitDialog();
. . .
EnableAutomation();
LPDISPATCH pDisp = GetIDispatch(FALSE);
SetExternalDispatch(pDisp);
return TRUE; // return TRUE unless you set the focus to a control
}
. . .
void CHtmlDlgTestDlg::Test()
{
AfxMessageBox(TEXT("Test"));
}
Re: CDHtmlDialog : JavaScript calling C++ Functions
Re: CDHtmlDialog : JavaScript calling C++ Functions
When the JavaScript(JS) function is being loaded the first time, it will pop up a message box asking "An ActiveX control on this page might be unsafe to interact with other parts of the page. Do you want to allow this interaction?"
I have to click YES for the JS to run successfully.
Is there a way to permanently disable this message?
1 Attachment(s)
Re: CDHtmlDialog : JavaScript calling C++ Functions
Code:
// HtmlDlgTestDlg.h : header file
//
#pragma once
// CHtmlDlgTestDlg dialog
class CHtmlDlgTestDlg : public CDHtmlDialog
{
// Construction
public:
CHtmlDlgTestDlg(CWnd* pParent = NULL); // standard constructor
// Dialog Data
. . .
void Test();
BOOL IsExternalDispatchSafe() { return TRUE; }
// Implementation
. . .
};
Re: CDHtmlDialog : JavaScript calling C++ Functions
Hello Igor,
I am trying to pass a string to a C++ function from the JS function, the code is shown below.
JavaScript:
function ClickEvents () {
window.external.ProcessEvents("user_entry");
}
C++:
DISP_FUNCTION(CHtmlClientUIDlg, "ProcessEvents", ProcessEvents, VT_EMPTY, VTS_BSTR)
void CHTMLTest::ProcessEvents(LPCSTR args)
{
CString str(args); // str = "u", it skips rest of the string.
-----------------
-----------------
}
Inside my C++ function am able to get only the first character of the string that's passed. i.e., "u" only. The rest of the string is not getting in.
How can i get the full string?
Thanks in advance.
Re: CDHtmlDialog : JavaScript calling C++ Functions
Please see updated code below:
JavaScript:
function ClickEvents () {
window.external.ProcessEvents("user_entry");
}
C++:
DISP_FUNCTION(CHtmlClientUIDlg, "ProcessEvents", ProcessEvents, VT_EMPTY, VTS_BSTR)
void CHtmlClientUIDlg::ProcessEvents(LPCSTR args)
{
CString str(args); // str = "u", it skips rest of the string.
-----------------
-----------------
}
Re: CDHtmlDialog : JavaScript calling C++ Functions
Quote:
Originally Posted by
Don Guy
DISP_FUNCTION(CHtmlClientUIDlg, "ProcessEvents", ProcessEvents, VT_EMPTY, VTS_BSTR)
void CHtmlClientUIDlg::ProcessEvents(LPCSTR args)
{
CString str(args); // str = "u", it skips rest of the string.
-----------------
-----------------
}
You just cannot ignore COM rules. Once you claim that be BSTR, it must be one, but nothing else.
Re: CDHtmlDialog : JavaScript calling C++ Functions
So how to pass a string from JS to C++ function? What changes i need to make?
Thanks
Re: CDHtmlDialog : JavaScript calling C++ Functions
Quote:
Originally Posted by
Don Guy
JavaScript:
function ClickEvents () {
window.external.ProcessEvents("user_entry");
}
What type of string does JavaScript pass? That is the first question you need to answer. Is it UTF16? UTF8? UTF32? 8-bit ASCII?
Once you find out, then you tailor the C++ code to handle such strings. As to your code, it is an instant non-starter as Igor pointed out. One major reason is that a BSTR consist of 16-bit character strings, and LPCSTR is a pointer to an 8-bit character string.
Secondly, is your C++ code UNICODE? If so, then CString knows UNICODE (16-bit) character strings, so again, LPCSTR is a non-starter. More than likely, the string you received in the C++ code consists of 8-bit characters interleaved with NULL bytes. Check out the string in the debugger and you may see that the "u" is followed by a NULL byte, followed by the "s" and then a NULL byte, etc.
But still, you need to know what JavaScripts sends, and that is a JavaScript question, not a C++ one.
Regards,
Paul McKenzie
Re: CDHtmlDialog : JavaScript calling C++ Functions
The C++ code is UNICODE.
Regarding JavaScript, i am pretty new to that don't know how strings work in that. So all am doing is hard coding a string like "user_entry".
While looking to MSDN the 2 ways a string can be passed in COM is via BSTR or LPCSTR. That's the reason i am using LPCSTR in this case. When i use BSTR it gives an error in JavaScript.
Any ideas?
Thanks