English

Problem: SetPoints and GetPoints methods are not wrapped properly in C++ development environments

Description

In Microsoft's Visual C++, if you open up the MoPoints header file, the methods are
commented out as such:

// method 'SetPoints' not emitted because of invalid return type or
parameter type
// method 'GetPoints' not emitted because of invalid return type or
parameter type

In C++ Builder, these methods are not wrapped at all.

Cause

SetPoints() and GetPoints() methods are not getting wrapped properly.

Solution or Workaround

To call these methods, you must use the raw dispatch interface. In Visual C++, the code will look something like the following:

  1. Create SafeArrays to hold your x,y,z, and m values:

    Code:
    SAFEARRAYBOUND sab;
    SAFEARRAY* psaX;
    SAFEARRAY* psaY;
    SAFEARRAY* psaZ;
    SAFEARRAY* psaM;

    unsigned int i;
    long idx[1];
    double valX = -100;
    double valY = 50;
    double mz = 0;

    //Set bounds of safearrays.
    sab.cElements = 3;
    sab.lLbound = 0;

    //Allocate and initialize data for array.
    psaX = SafeArrayCreate(VT_R8, 1, &sab);
    psaY = SafeArrayCreate(VT_R8, 1, &sab);
    psaZ = SafeArrayCreate(VT_R8, 1, &sab);
    psaM = SafeArrayCreate(VT_R8, 1, &sab);

    //Fill arrays with your values.
    //We use arbitrary values here.
    for (i=0; i<3; i++)
    {
    idx[0]= i;

    SafeArrayPutElement(psaX,idx,&valX);
    SafeArrayPutElement(psaY,idx,&valY);
    SafeArrayPutElement(psaZ,idx,&mz);
    SafeArrayPutElement(psaM,idx,&mz);
    valX = valX + -10;
    valY = valY + -10;
    }


  2. Map the SetPoints member method:

    Code:
    wchar_t *szSetPoints[] = {L"SetPoints"};
    DISPID dispidSetPoints = NULL;
    LPDISPATCH pDisp = (LPDISPATCH)m_pts;//m_pts is your CMoPoints object
    HRESULT res = pDisp->GetIDsOfNames(IID_NULL, szSetPoints, 1, LOCALE_USER_DEFAULT, &dispidSetPoints);


  3. Set the arguments for the SetPoints method:

    Code:
    DISPID namedargsSetPoints = DISPID_PROPERTYPUT;
    DISPPARAMS putparamsSetPoints;
    putparamsSetPoints.cNamedArgs = 0;


    If you are only setting the x and y coordinates (no z and m values):

    Code:
    putparamsSetPoints.cArgs = 2;
    putparamsSetPoints.rgdispidNamedArgs = &namedargsSetPoints;

    putparamsSetPoints.rgvarg = new VARIANTARG[2];

    putparamsSetPoints.rgvarg[0].vt = VT_ARRAY|VT_R8|VT_BYREF;
    putparamsSetPoints.rgvarg[0].pparray = &psaY;
    putparamsSetPoints.rgvarg[1].vt = VT_ARRAY|VT_R8|VT_BYREF;
    putparamsSetPoints.rgvarg[1].pparray = &psaX;


    If you are setting x,y,z, and m values:

    Code:
    putparamsSetPoints.cArgs = 4;
    putparamsSetPoints.rgvarg = new VARIANTARG[4];
    putparamsSetPoints.rgvarg[0].vt = VT_ARRAY|VT_R8|VT_BYREF;
    putparamsSetPoints.rgvarg[0].pparray = &psaM;
    putparamsSetPoints.rgvarg[1].vt = VT_ARRAY|VT_R8|VT_BYREF;
    putparamsSetPoints.rgvarg[1].pparray = &psaZ;
    putparamsSetPoints.rgvarg[2].vt = VT_ARRAY|VT_R8|VT_BYREF;
    putparamsSetPoints.rgvarg[2].pparray = &psaY;
    putparamsSetPoints.rgvarg[3].vt = VT_ARRAY|VT_R8|VT_BYREF;
    putparamsSetPoints.rgvarg[3].pparray = &psaX;


  4. Invoke the method:

    Code:
    EXCEPINFO excepinfo;
    res = pDisp->Invoke(dispidSetPoints, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &putparamsSetPoints, NULL, &excepinfo, NULL);

    if (SUCCEEDED(res))
    {
    //...
    }

  5. Clean up:

    Code:
    SafeArrayDestroy(psaX);
    SafeArrayDestroy(psaY);
    SafeArrayDestroy(psaZ);
    SafeArrayDestroy(psaM);