APIPaletteControlCallBackProc

User supplied callback function for handling special messages for modeless palettes.

    typedef GSErrCode  APIPaletteControlCallBackProc (
        Int32                    referenceID,
        API_PaletteMessageID     messageID,
        GS::IntPtr               param
    );

 

Parameters

referenceID
[in] The unique ID that identifies the modeless palette.
messageID
[in] Event to be handled in the palette control callback procedure.
param API 16
[out] Return parameter, used for APIPalMsg_IsPaletteVisible.

 

Return Values

NoError
The function has completed with success.

For other common API errors see the API Errors document.

 

Remarks

You can register this function with ACAPI_RegisterModelessWindow. From now on, it will be your responsibility to adjust the behavior of your palette to the other palettes.

The following types of events will come for your custom window:

Message type Description
APIPalMsg_ClosePalette The API asks the add-on to close its palette.
APIPalMsg_HidePalette_Begin Your palette should be hidden for some reason, e.g. the user chose Hide All Palettes from the menu.
APIPalMsg_HidePalette_End The palette can be shown again if needed.
APIPalMsg_DisableItems_Begin Certain palette items should be disabled, because the user is performing an input. This is necessary because you shouldn’t make any modifications to the database during input.
APIPalMsg_DisableItems_End The reason behind APIPalMsg_DisableItems_Begin is gone; you can enable the items on the palette.
APIPalMsg_OpenPalette Featuring API 15 Sent when the palette should be opened automatically as set in the Work Environment. Your palette should pass a GUID when created: DG::Palette (resourceId, paletteGuid) to make this work.
APIPalMsg_IsPaletteVisible Featuring API 16 The Work Environment queries the palette for its visibility status on closing the current document/quitting the application. If you return true in param (really a bool*), then Archicad will send a APIPalMsg_OpenPalette to your add-on on next launch, so that you can re-open your add-on’s palette.

 

Example


const GS::Guid paletteGuid ("{A20B280D-928B-4258-9A4A-8617B57124F8}");

void        MainPaletteDestroyed (void);

// --- MainPalette -----------------------------------------------------------

class MainPalette: public DG::Palette,
                   public GS::DisposableObject
{
friend class    MainObserver;

public:

    MainPalette (short resId);
    ~MainPalette ();
};


// --- MainObserver ---------------------------------------------------------

class MainObserver: private DG::PanelObserver,
                    public  DG::CompoundItemObserver,
                    public  GS::DisposableObject,
                    public  GS::DisposeHandler
{
private:
    MainPalette*    paletteQL;

public:
    MainObserver (MainPalette* mainPalette);
    ~MainObserver ();

    virtual void    PanelOpened (const DG::PanelOpenEvent& ev);
    virtual void    PanelClosed (const DG::PanelCloseEvent& ev);
    virtual void    PanelCloseRequested (const DG::PanelCloseRequestEvent& ev, bool* accept);
    virtual void    DisposeRequested (GS::DisposableObject& source);
};


// --- MainPalette --------------------------------------------------------------

MainPalette::MainPalette (short resId):
    DG::Palette (resId, paletteGuid)
{
    SetDefaultGarbageCollector ();
}


MainPalette::~MainPalette ()
{
}


// --- MainObserver ---------------------------------------------------------

MainObserver::MainObserver (MainPalette* mainPalette):
    paletteQL (mainPalette)
{
    paletteQL->Attach (*this);
    AttachToAllItems (*paletteQL);
    paletteQL->BeginEventProcessing ();

    SetDefaultGarbageCollector ();
    paletteQL->SetDisposeHandler (*this);
}


MainObserver::~MainObserver ()
{
}


void    MainObserver::PanelOpened (const DG::PanelOpenEvent& /*ev*/)
{
}


void    MainObserver::PanelClosed (const DG::PanelCloseEvent& /*ev*/)
{
}


void    MainObserver::PanelCloseRequested (const DG::PanelCloseRequestEvent& /*ev*/, bool* /*accept*/)
{
    paletteQL->EndEventProcessing ();
    paletteQL->MarkAsDisposable ();
}

// -----------------------------------------------------------------------------
// Handles palette destroy
// -----------------------------------------------------------------------------

void    MainObserver::DisposeRequested (GS::DisposableObject& source)
{
    if (&source == paletteQL) {
        paletteQL = nullptr;
        MainPaletteDestroyed ();
        MarkAsDisposable ();    // mark as the garbage collector could delete later
    }
}


MainPalette* mainPalette = nullptr;
MainObserver* mainObserver = nullptr;


void        MainPaletteDestroyed (void);
{
    mainPalette = nullptr;
}

// -----------------------------------------------------------------------------
// Special palette messages
// -----------------------------------------------------------------------------
static GSErrCode __ACENV_CALL PaletteAPIControlCallBack (Int32 referenceID, API_PaletteMessageID messageID, GS::IntPtr param)

{
    if (referenceID == paletteRefId) {
        switch (messageID) {
            case APIPalMsg_OpenPalette:
                if (mainPalette != nullptr) {
                    mainPalette->Show ();
                } else {
                    UseOwnResClass resClass;
                    mainPalette  = new MainPalette (32400);
                    mainObserver = new MainObserver (mainPalette);
                    mainPalette->Show ();
                }
                break;

            case APIPalMsg_ClosePalette:
                if (mainPalette != nullptr) {
                    mainPalette->Hide ();
                    mainPalette->SendCloseRequest ();
                }
                break;

            case APIPalMsg_HidePalette_Begin:
                if (mainPalette != nullptr) {
                    mainPalette->Hide ();
                    SetMenuItemTextState (false);
                }
                break;

            case APIPalMsg_HidePalette_End:
                if (mainPalette != nullptr) {
                    mainPalette->Show ();
                }
                break;

            case APIPalMsg_DisableItems_Begin:
                if (mainPalette != nullptr) {
                    mainPalette->DisableItems ();
                }
                break;

            case APIPalMsg_DisableItems_End:
                if (mainPalette != nullptr) {
                    mainPalette->EnableItems ();
                }
                break;

            case APIPalMsg_IsPaletteVisible:
                * reinterpret_cast<bool*> (param) = (mainObserver != nullptr);
                break;

            default:
                break;
        }
    }

    return NoError;
}

// -----------------------------------------------------------------------------
// Handle notifications from Archicad
// -----------------------------------------------------------------------------

GSErrCode __ACENV_CALL APIEventHandler (API_NotifyEventID notifID, Int32 /*param*/)
{
    switch (notifID) {
        case APINotify_NewAndReset:
        case APINotify_Quit:
            if (mainPalette != nullptr) {
                mainPalette->Hide ();
                mainPalette->SendCloseRequest ();
            }
            break;
    }

    return NoError;
}


//------------------------------------------------------
// Dependency definitions
//------------------------------------------------------
API_AddonType   __ACENV_CALL    CheckEnvironment (API_EnvirParams* /*envir*/)
{
    return APIAddon_Preload;
}       // RegisterAddOn


//------------------------------------------------------
// Add-On initialization
//------------------------------------------------------
GSErrCode   __ACENV_CALL    Initialize (void)

{
    GSErrCode err = ACAPI_RegisterModelessWindow (paletteRefId, PaletteAPIControlCallBack,
                                                  API_PalEnabled_FloorPlan + API_PalEnabled_Section + API_PalEnabled_Elevation +
                                                  API_PalEnabled_InteriorElevation + API_PalEnabled_3D +
                                                  API_PalEnabled_Detail + API_PalEnabled_Worksheet + API_PalEnabled_Layout +
                                                  API_PalEnabled_DocumentFrom3D, GSGuid2APIGuid (paletteGuid));

    if (err == NoError)
        err = ACAPI_Notify_CatchProjectEvent (APINotify_NewAndReset | APINotify_Quit, APIEventHandler);

    return err;
}


//------------------------------------------------------
// Final call...
//------------------------------------------------------
GSErrCode   __ACENV_CALL    FreeData (void)

{
    ACAPI_Notify_CatchProjectEvent (APINotify_NewAndReset | APINotify_Quit, nullptr);
    if (mainPalette != nullptr) {
        mainPalette->Hide ();
        mainPalette->SendCloseRequest ();
    }

    ACAPI_UnregisterModelessWindow (paletteRefId);

    return NoError;
}

 

Requirements

Version: API 4.1 or later
Header: APIdefs_Callback.h

 

See Also

ACAPI_RegisterModelessWindow, API Functions