Parameter Passing Between Javascript and ActiveX DLL

More than a year ago, while I am still working at the company, I came across one task of the system conversion project.

The goal of this project is to convert the existing application which is already developed using Visual Basic to web-based application. The client for this web-based application is decided to be Internet Explorer.

One of the facility in the existing application to be converted consists of a module that has the capability to print to Epson’s dot matrix printer. It’s using the printer’s native printing code that prints directly from the application to the printer itself.

In order to accomplished that capability, the application is using Visual Basic’s Printer object. The previous application developer that originally developed this solutions already resigned, so the question of why he is using this solution is unknown.

But perhaps it is because printing through existing print dialog provided by IE (Internet Explorer) that’s using window’s GDI capability is rather slow and the printed characters is not as good as when utilized the printer’s native text mode capability.

So, now, when this application is ported to web-based using IE (Internet Explorer) client, there should be an equivalent solution for this function.

After performing analysis and the study regarding this matter, I decided to use VB’s (Visual Basic) ActiveX DLL that will be embedded as an object in IE client to receive text to be printed from Javascript in IE.

There is one method in this DLL called PrintForm that accepts text to be printed as a parameter from Javascript Script Object, and then the task of actually printing the text is copied from existing VB application developed earlier.

In the course of developing and testing this DLL, there’s a phenomena that I’ve noticed, i.e. the ActiveX DLL’s PrintForm method can only receive the string value. It failed when I try to pass the array of string from Javascript to the DLL’s method, given the show-stopper message as follows :

“Wrong number of arguments or invalid property assignment”

Since there’s little time left for this task, and also there’s workaround for this problem, I do not pursue further to the question of why the generated ActiveX DLL (actually .ocx control) can not receive a more desirable array of strings as the parameter.

The workaround for that issue at that time is just to create a very long string concatenated by unique separator character, and later on is separated again in the DLL’s method.

The causes of the above issue will not be found had I not facing another more or less identical task for one of my client, i.e. to print their receipt into 3 ply form using Epson’s dot matrix printer.

This time I am using the MFC’s ActiveX DLL framework generated VS 2005. It is because, using VC++ it will provide more room for me to change any aspects of configuration related to ActiveX DLL.

Because it seems that there are no array type for parameter in OLE automation dispatch map in VC++, I am using VTS_VARIANT as my parameter type for the form printing method.

By using this type of parameter, I achieve one step further because now I can pass the array of string object from Javascript to my method without generating the above show-stopper error message.

By examining the vt property of the passed parameter on ActiveX DLL side, it is found that the type is of VT_DISPATCH.

The question is what kind of the interface provided by this object so that I can access the strings properly ?

At first, I thought it should be IENumVARIANT interface, but upon querying to the object, it came empty handed, in other words, the result is E_NOINTERFACE (0x80004002).

Rather than beating over the bushes try to guess the supplied interface, it would be nice if I can locate the function that gets called when I invoke the QueryInterface method into the object.

Using WinDBG, it turns out that server side method that is responsible for QueryInterface method resides in JScript.DLL, precisely in jscript!ArrayObj::QueryInterface.

This method supplied the IDispatch, IUnknown and another interface id called IID_IDispatchEx. From the documentation, clearly this interface is an extended version of IDispatch interface. There’s no other interface besides this three interface supplied by JScript’s ArrayObj object.

Clearly there should be some methods within either IDispatch or IDispatchEx object that can be used to access the property of passed array. Searching through the net prove that indeed it is possible to access the property via GetIDsOfNames, Invoke or InvokeEx method.

So, for example, to access the number of array’s element, I can use sample IDispatchEx interface object code snippet as follows, assuming the QueryInterface provided the correct object pointer for IDispatchEx (I am using IDispatchEx, it is more or less the same for IDispatch Interface) and there are no errors for each method calls :

DISPID dispid;
DISPPARAMS param = {0,0,0,0};
CComVariant result;
OLECHAR* sLength= L”length”;

hr=pdispEx->GetIDsOfNames(IID_NULL, &sLength , 1, LOCALE_USER_DEFAULT, &dispid);
hr=pdispEx->InvokeEx(dispid, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &param, &result, NULL, NULL)

After the call to InvokeEx, the task to retrieve array length is :

VariantChangeType(&result, &result, 0, VT_I4);
long length = result.lVal;

Next, based on given array length, by looping through supplied object, I can get the string value for each array element. I’ll leave to the reader of this article for the task of retrieving passed strings 🙂


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: