ActiveX, Javascript, and BSTR

ActiveX, oh where to begin. I can say that ActiveX development is a good nightmare for any programmer. Let me mention that aside from being an older one of Microsoft’s technologies, there in fact very few resources on the topic itself. On CodeProject, you’ll find an example web control. The example shows you how to call your ActiveX functions and access it’s properties from Javascript. This example, although good, does not show you how you can with your ActiveX control interact with Javascript indepth.

One of the problems that I faced was how to return a string to Javascript from an ActiveX control function. Also, the reverse gave me some difficult, about how you send a string from Javascript to an ActiveX control function. It is not as easy as you might think.   Passing a string to an ActiveX control function from Javascript   First you must declare your function, in three different places no less. The first places is your IDL:

[id (01)] int32 PrintString(BSTR String);

Second, declare it in your control’s header.

int32 PrintString(LPCTSTR String);

And thirdly you must declare it in your ActiveX control dispatch map, as follows.

DISP_FUNCTION_ID(AxControl, "PrintString", DISPID_PRINTSTRING, PrintString, VT_I4, VTS_BSTR)

Once you declare your function all over the place, you can define it like so..

 int32 AxControl::PrintString(LPCTSTR String){   printf("Javascript string: %s/n", String);   return 0;} 

Even though Javascript is suppose to return a wide-character BSTR, it sadly does not. If you try and attempt to convert the BSTR into a multi-character string it will only ending up giving you garbage. Perhaps I am wrong, but this was the only way I could get it to work. I found this solution at the bottom of the barrel while look at another person’s code who had implemented their ActiveX control this way.
 
In your Javascript code you can now do the following..

<script type="text/javascript">
 AxControl.PrintString("Hello world");
</script>

Returning a string from an ActiveX control function to Javascript
 
Declare your function..
 IDL:

[id (02)] BSTR GetString(int32 Method);
 
//ActiveX control header..
 
BSTR GetString(int32 Method);
 
//ActiveX dispatch map..
 
DISP_FUNCTION_ID(AxControl, "GetString", DISPID_GETSTRING, GetString, VT_BSTR, VTS_I4)

You can then define your function as follows.

BSTR AxControl::GetString(int32 Method)
{
    uint16 WideString[120];
    char *ReturnString;
    if (Method == 1)
        ReturnString = "Supplied method was 1";
    else
        ReturnString = "Supplied method was not 1";
    if (MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, ReturnString, -1, WideString, 120) == 0)
        return NULL;
    return (BSTR)SysAllocString(WideString);
} 

That is how you would return a string to Javascript from your ActiveX control.
In your Javascript code then you might do something like what I have done below.

<script type="text/javascript">
 alert(AxControl.GetString(1));
 alert(AxControl.GetString(2));
</script>

 

 

posted @ 2012-11-22 14:04  BinSys  阅读(1429)  评论(0编辑  收藏  举报