What is the best way to extract data from a JavaScript object in C++?

I have integrated an IE ActiveX control within my C++ (MFC) application. This embedded IE contains a JavaScript method that sends data back to my C++ application using the following simplified JavaScript code:

function passDataTocpp()

{   
    return {key1: 134, key2:'value2'};

}

Upon receiving this data in my C++ code, I retrieve a VARIANT of type VT_DISPATCH. While I managed to refer to this example that converts an array for C++ usage, it does not seem to work for an associative array or object.

Do you have any suggestions on how to access this data?

Answer №1

When working with objects where you are unsure of the properties they possess, consider using IDispatch::GetIdsOfNames and

IDispatch::Invoke(DISPID_PROPGET)
. If the object's properties are not known, utilizing IDispatchEx and GetNextDispID for enumeration is recommended.

If you are utilizing ATL, leveraging CComDispatchDriver as a wrapper around IDispatch can be helpful (although directly calling IDispatchEx is necessary). Though oddly missing from MSDN documentation, examining the specialization of CComPtr<IDispatch> in atlcomcli.h should provide clarity. Note that CComDispatchDriver serves as a typedef for this specialization.

Answer №2

When looking at the C++ side, the code may resemble the following (as described in Igor's response):

STDMETHOD(Bar)(VARIANT vData)
{
    ATLASSERT(vData.vt == VT_DISPATCH);
    CComPtr<IDispatch>& pData = reinterpret_cast<CComPtr<IDispatch>&>
        (vData.pdispVal);
    CComVariant vElementValue;
    const HRESULT nOutcome = pData.GetPropertyByName(L"key2", &vElementValue);
    // vElementValue holds the value VT_I4 52 in this scenario

Answer №3

After taking advice from @IgorTandetnik, I developed a method that appears to fulfill the required task (although it's in pseudo-code):

BOOL ConvertVariantToProperties(CComVariant& var)
{
    HRESULT hr;

    if (var.vt != VT_DISPATCH)
        return FALSE;

    CComPtr<IDispatch> pDispatch = var.pdispVal;

    CComQIPtr<IDispatchEx> pDispatchEx;
    if(FAILED(hr = pDispatch->QueryInterface(IID_IDispatchEx, (void **)&pDispatchEx)))
        return FALSE;

    BSTR bstrName;
    DISPID dispid;

    // Assume success
    BOOL success = TRUE;

    // Enumerate object names
    hr = pDispatchEx->GetNextDispID(fdexEnumAll, DISPID_STARTENUM, &dispid);
    while (hr == NOERROR)
    {
        if(SUCCEEDED(hr = pDispatchEx->GetMemberName(dispid, &bstrName)))
        {
            // Get DISPID of item
            DISPID dispidIndex = 0;
            LPOLESTR pIndex = reinterpret_cast<LPOLESTR>(const_cast<WCHAR *>(bstrName));
            if(SUCCEEDED(hr = pDispatch->GetIDsOfNames(IID_NULL, &pIndex, 1, LOCALE_USER_DEFAULT, &dispidIndex)))
            {
                CComVariant varItem;
                DISPPARAMS dispParams = {0};
                if(SUCCEEDED(hr = pDispatch->Invoke(dispidIndex, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispParams, &varItem, NULL, NULL)))
                {
                    // Object's property name is stored in 'bstrName'
                    // Object's property value is stored in 'varItem'
                }
                else
                {
                    ASSERT(NULL);
                    success = FALSE;
                }
            }
            else
            {
                ASSERT(NULL);
                success = FALSE;
            }
        }

        SysFreeString(bstrName);
        hr = pDispatchEx->GetNextDispID(fdexEnumAll, dispid, &dispid);
    }

    return success && hr == S_FALSE;
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The execution of jQuery was hindered due to the implementation of PHP include

Having an issue with jQuery not working in index.php when including the file header.php. The nav sidebar is included, but clicking the chevron does not trigger anything. It only works when I directly include header_user.php without checking the UserType in ...

Error: HTML code being displayed instead of form value in Ajax request output

For the past couple of days, I've been struggling with an Ajax issue that I just can't seem to figure out. Despite looking for a solution online, nothing seems to work. Below is the code snippet that's causing me trouble: <!DOCTYPE html& ...

The Problem of Memory Leakage in AngularJS While Navigating Pages

I am currently working on an AngularJs App with 3 screens. The app is set up to route between these 3 screens every X seconds using the ui-router component. $stateProvider .state("page", { url: "/:pageId/:pageType", template: pageTempl ...

The overlay button is designed to start the video only when clicked on the center of the screen. However, if clicked on any other part of the video, it will stop

$(".video") .parent() .click(function () { if ($(this).children(".video").get(0).paused) { $(this).children(".video").get(0).play(); $(this).children(".playpause").fadeOut(); $("video").attr("controls", true); } else { $ ...

Waiting for Angular's For loop to complete

Recently, I encountered a situation where I needed to format the parameters and submit them to an API using some code. The code involved iterating through performance criteria, performance indicators, and target details to create new objects and push them ...

No changes occur within this JavaScript code

I am currently working on a piece of Java Script code: document.onreadystateChange = function() { if (document.readystate === "complete") { var menu = document.getElementsByClassName('menu'); var b0 = menu[0]; b0.addE ...

Function for triggering character or camera movement upon the pressing of a button

Just starting out here with web coding and I'm trying to create a function that moves my game character when a button is pressed. The idea is to change a boolean value to "true" when the button is pressed down so that the character moves. I've at ...

What is the general consensus on combining SWR with Redux - is it considered a best practice?

I am currently incorporating both SWR and Redux into my code. Here is how I'm using them together: const vehiclesStates = useSelector(({ vehiclesStates: state }) => state); // REDUX const response = useFetch("/vehicles/states") // SWR con ...

What would be the best approach to convert this jQuery code into a more structured object-oriented programming format

Recently, I began working on my first major front-end heavy website. My goal was to create a unique content management system-driven single-page website with over 100 internal pages. The URL would remain constant, but whenever a user clicked on any link b ...

Creating hierarchical TreeNode structure in TypeScript

As I work with a flat one-dimensional array of type TreeNode (view interface definition below), my goal is to recursively traverse the array and add subsequent array elements as children. While attempting a non-recursive approach using a buffer, I encount ...

Session data in ExpressJS is not being stored in the cookie

There are plenty of questions on this topic, but unfortunately, I haven't found any answers that solve my issue. I'm using Chrome with ExpressJS and VueJs 3 to build a simple application where users can "login" and access another page. All I wan ...

What is the reason for placing a ReactJS component, defined as a function, within tags when using the ReactDom.render() method?

As someone who is brand new to ReactJS and JavaScript, I am struggling to grasp the syntax. The component I have created is very basic: import React from 'react' import ReactDom from 'react-dom' function Greetings() { return <h1&g ...

I'm experiencing difficulties with updating my model while utilizing the ngResource module

Encountering a minor issue with Angular at the moment. Employing the $ngResource module to fetch "comments" from my server: var app = angular.module('app', ['ngResource']); app.factory('comment', function($resource) { r ...

Even though the model value is set to true, the material check box remains unchecked

My mat-table contains data and checkboxes. The checkboxes should only be checked when the element.select property is true. However, when I use [(ngModel)]="element.select", all the checkboxes end up getting checked. Below you can find the code snippet: &l ...

Utilize Flexbox to arrange elements in a grid layout based on specified number of columns and rows

My div is currently empty. <div id="container"></div> I have applied the following styling with CSS: #container{ display: flex; position: relative; flex-flow: row wrap; width: 100%; } The goal is to add more divs to the cont ...

The value from select2 dropdown does not get populated in my article in Angular

I am attempting to link the selected value in a dropdown menu to an article, with a property that matches the type of the dropdown's data source. However, despite logging my article object, the property intended to hold the selected dropdown value app ...

How can a loading indicator be displayed while retrieving data from the database using a prop in a tabulator?

Incorporating a tabulator component into my vue app, I have set up the Tabulator options data and columns to be passed via props like this: // parent component <template> <div> <Tabulator :table-data="materialsData" :ta ...

break up text area input efficiently utilizing jQuery regex

I'm encountering difficulties in properly splitting the value of a textarea. My current code snippet is splitting each line that begins with "-" and displaying it as the value of a span element. However, it fails to collect the next line's value ...

Accessing data from an API using Node.js

I'm currently working with Node.js and trying to retrieve the city name from an API. However, I keep encountering an error message that reads "Cannot read property city_name of undefined." The issue seems to be arising from this specific line of code ...

Leveraging partials on their own

I am currently exploring the possibility of loading a partial in linkedin-dustjs without having to load its parent along with it. For instance, consider this partial (login.dust): {>layout/} {<content} <!-- Login Screen --> {/content} Th ...