Showing posts with label ATL. Show all posts
Showing posts with label ATL. Show all posts

Thursday, September 20, 2007

Developing Hybrid Gadgets for Google Desktop

If you are interested in developing gadgets for Google Desktop you may have heard of so-called hybrid gadget. It is a way to enhance your gadget with functionality that cannot be achieved in pure script and GD's API. Namely, you may write the part of the functionality, natively, as an ActiveX object and use it from the script without a need of having the typelib registered, etc.

If you would like to learn about this technique, I encourage you to read my article I have written for Google Developer Knowledge Base which is called Going Beyond Script: Developing Hybrid Gadgets. I hope you will enjoy it and that the article will prove useful. Feel free to leave here comments regarding the article.

Tuesday, August 21, 2007

JScript arrays and COM objects, part 3

I have promised in my previous post that I will present also how to deal with JScript arrays in C++ code with ATL. Below, there is a code of a function, I have come up with, in C++ that gets the JScript array of integers and calculates the sum:

#include <string>
#include <sstream>
#define _C(oleop) hr = oleop; \
if (!SUCCEEDED(hr)) \
return hr;

STDMETHODIMP CHelloWorld::JSArrSum(VARIANT js_arr, LONG* Sum)
{
HRESULT hr;

/* checking if argument is an object */
if (!(js_arr.vt & VT_DISPATCH))
return E_INVALIDARG;

/* retrieving IDispatch */
IDispatch *disp = js_arr.pdispVal;
if (js_arr.vt & VT_BYREF)
disp = *(js_arr.ppdispVal);

/* getting array's length */
DISPPARAMS params;
FillMemory(¶ms, sizeof(DISPPARAMS), 0);
VARIANT res;

DISPID dl;
LPOLESTR ln = L"length";

_C(disp->GetIDsOfNames(IID_NULL, &ln, 1, LOCALE_USER_DEFAULT, &dl));

_C(disp->Invoke(dl, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET,
¶ms, &res, NULL, NULL));

VARIANT len1;
VariantInit(&len1);

_C(VariantChangeType(&len1, &res, 0, VT_I4));
LONG len = len1.lVal;

/* summing elements */

int total = 0;
for (int i = 0; i < len; i++)
{
std::stringstream ss;
ss << ind =" CComBSTR(ss.str().c_str());">GetIDsOfNames(IID_NULL, &ind, 1, LOCALE_USER_DEFAULT, &id));
_C(disp->Invoke(id, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, ¶ms, &res, NULL, NULL));

VARIANT val1;
VariantInit(&val1);

_C(VariantChangeType(&val1, &res, 0, VT_I4));
total += val1.lVal;
}

*Sum = total;

return S_OK;
}

What it does is simply the following:

  1. It is checked if an argument is some object (hopefully, a JScript array)
  2. IDispatch reference of an array is retrieved from the variant.
  3. The property length is obtained from the array's object as it is for any automation object. We receive some variant value, so we need to convert it to integer.
  4. For each element of an array its DISPID is queried and its value received, converted to integer, and summed up.
  5. It returns the sum of array's values.
It can be called from JScript as following:

var arr = new Array();
arr[0] = 10;
arr[1] = 15;
arr[2] = 2;

var obj = new ActiveXObject("ProgID.OfClass");
alert(obj.JSArrSum(arr));

There were visits to this blog since 20.08.2007.