Call javascript method on instance with MSHTML in C++

Let’s say you want to call a method or property on a javascript instance from C++ using MSHTML, you can do it using IDispatch interface and invoking method (DISPATCH_METHOD) or property (DISPATCH_PROPERTYGET). In example, something like

 
GS.player.getCurentSong().getTitle();

can be done by calling sequentially and acquiring one interface at a time, GS (needs to be a global instance or method), then the property player, then calling the method getCurrentSong() etc. Here’s an example to execute the statement above and return the string in a VARIANT variable.

const LCID lcid = LOCALE_SYSTEM_DEFAULT;
const WORD kPropCall = DISPATCH_PROPERTYGET;
const WORD kMethodCall = DISPATCH_METHOD;
DISPID idProp = 0;
DISPID idMethod = 0;
CComQIPtr<IDispatch> script;
htmlDocument->get_Script(&script);
 
// Get GrooveShark instance
OLECHAR FAR* sMethod = L"GS"; //ok
HRESULT hr = script->GetIDsOfNames(IID_NULL, &sMethod, 1, lcid, &idProp);
if (SUCCEEDED(hr)) 
{
  // Get GS property
  CComVariant retVal;
  DISPPARAMS dpNoArgs = {NULL, NULL, 0, 0};
  hr = script->Invoke(idProp, IID_NULL, lcid, kPropCall, &dpNoArgs, 
    &retVal, NULL, NULL);
 
  // Get GS player instance
  sMethod = L"player";
  hr = retVal.pdispVal->GetIDsOfNames(IID_NULL, &sMethod, 1, lcid, &idProp);
  if (SUCCEEDED(hr)) 
  {
    hr = retVal.pdispVal->Invoke(idProp, IID_NULL, lcid, kPropCall, &dpNoArgs, 
      &retVal, 0, 0);
 
    // Get getCurrentSong method
    sMethod = L"getCurrentSong";
    hr = retVal.pdispVal->GetIDsOfNames(IID_NULL, &sMethod, 1, lcid, &idMethod);
    if (SUCCEEDED(hr)) 
    {
      hr = retVal.pdispVal->Invoke(idMethod, IID_NULL, lcid, kMethodCall, &dpNoArgs, 
        &retVal, 0, 0);
 
      // Check if we have a current song
      if ( retVal.vt != VT_EMPTY && retVal.vt != VT_NULL )
      {
        sMethod = L"getTitle";
        hr = retVal.pdispVal->GetIDsOfNames(IID_NULL, &sMethod, 1, lcid, &idMethod);
        if (SUCCEEDED(hr)) 
        {
          // Get the title
          hr = retVal.pdispVal->Invoke(idMethod, IID_NULL, lcid, kMethodCall, 
            &dpNoArgs, &retVal, NULL, NULL);
 
          // Read the title string if any.
          if ( SUCCEEDED(hr) && retVal.vt == VT_BSTR )
          {
            songTitle = retVal.bstrVal;
          }
        }
      }
    }
  }
}
This entry was posted in C++, Coding and tagged , , , . Bookmark the permalink.

One Response to Call javascript method on instance with MSHTML in C++

  1. This is a great example of how chain pairs of GetIDsOfNames/Invoke calls.

Leave a Reply

Your email address will not be published. Required fields are marked *