Updating Commands for Properties Palette Synchronization

Adapting command handlers for synchronization involves changes to your command's AutoCAD registration and to its execution code.

To update your command handler for Properties palette synchronization

  1. In your command application, define any synchronized commands with the ACRX_CMD_INTERRUPTIBLE flag.

    Combine ACRX_CMD_INTERRUPTIBLE with any other flags that you pass to the acedRegCmds->addCommand() function's fourth parameter. The following sample code shows how this is done:

acedRegCmds->addCommand("SQUARE_COMMANDS", "ASDKADDSQUARE", 
    "ADDSQ", 
    ACRX_CMD_MODAL | ACRX_CMD_INTERRUPTIBLE,
    addSquare);

In the handler code for your registered AutoCAD command, call the acedSetIUnknownForCurrentCommand() global function. This call should occur before your command prompts the user for input.

Where the prompts occur, poll all input functions for an RTMODELESS return value.

If RTMODELESS is returned, abandon the current input request and proceed to the next command step. This call is made in your synchronized command handler.

Before you can call the acedSetIUnknownForCurrentCommand() function, you must create instances of both your COM object wrapper and your COM command wrapper, and then associate the two through connection points. If you intend to add your object to an AcDbDatabase, you create the underlying AcDbEntity object by calling the COM object wrapper's implementation of the IAcadBaseObject2Impl::CreateObject() function. With the returned pointer, you can call your COM wrapper's implementation of the IAcadBaseObject2::AddToDb() function.

Here is the addSquare() command handler function from com\AsdkSquareWrapper_dg\Square\squareui.cpp:

void addSquare()
{
    CComPtr<IAsdkSquareWrapper> pSquare;
    CComQIPtr<IAcadBaseObject2> pSquareBase;
    CComQIPtr<IConnectionPointContainer> pConnectionPts;
    CComPtr<IConnectionPoint> pConnection;
    CComObject<CAsdkSquareCmd> *pSquareCmdObj;
    CComPtr<IUnknown> pSquareCmd;
    DWORD connectionId = 0;
    HRESULT hr = S_OK;
    try {
        // Create the wrapper object which we will place into OPM
        // to display the square's properties
        if (FAILED(hr =
               pSquare.CoCreateInstance(CLSID_AsdkSquareWrapper)))
            throw hr;
        pSquareBase = pSquare;
        // Create the underlying square object
        if (FAILED(hr = pSquareBase->CreateObject()))
            throw hr;
        // Create the square modification listener which we use to
        // synchronize changes in OPM and the command line
        if (FAILED(hr =  CComObject<CAsdkSquareCmd>::CreateInstance(
	&pSquareCmdObj)))
            throw hr;
        pSquareCmdObj->QueryInterface(IID_IUnknown,
       (void **)&pSquareCmd);
        // Attach the square modification listener to the wrapper
        pConnectionPts = pSquare;
        if (!pConnectionPts)
            throw E_POINTER;
        if (FAILED(hr = pConnectionPts->FindConnectionPoint
            (IID_IPropertyNotifySink, &pConnection)))
            throw hr;
        if (FAILED(hr = pConnection->Advise(pSquareCmd,
            &connectionId)))
            throw hr;
    }
    catch (HRESULT) {
        acutPrintf("\n Error initializing command.");
        return;
    }
    // Set the square object up for OPM
    acedSetIUnknownForCurrentCommand(pSquare);
    // Now process the command line input by 
    // looping for all required parameters
   	ads_point pt0, pt1;
    ads_real size = 0.0;
	struct resbuf UCS, WCS;
    int retval;
	WCS.restype = RTSHORT;
	WCS.resval.rint = 0;
	UCS.restype = RTSHORT;
	UCS.resval.rint = 1;
    while (true) {
        if (!pSquareCmdObj->GotCenterPoint())
        {
            retval = acedGetPoint(NULL, "\nPick a point for the
                center: ", pt0);
            if (retval == RTCAN)
                break;
            else if (retval != RTNORM)
                continue;
            acedTrans(pt0, &UCS, &WCS, 0, pt1);
            AcAxPoint3d pnt3d(pt1[X], pt1[Y], pt1[Z]);
            pSquare->put_CenterPoint(*(pnt3d.asVariantPtr()));
        }
        if (!pSquareCmdObj->GotSquareSize())
        {
	retval = acedGetDist(pt0, "\nPick the square size : ",
                &size);
            if (retval == RTCAN)
                break;
            else if (retval != RTNORM)
                continue;
        		pSquare->put_SquareSize(size);
        }
        AcDbObjectId squareId;
        if (FAILED(hr = pSquareBase->AddToDb(squareId, 
               curDoc()->database()->currentSpaceId()))) 
        {
            acutPrintf("\n Error appending object to database.");
            break;
        }
        break;
    }
    // Unadvise the square modified listener
    pConnection->Unadvise(connectionId);
    return;
}