#if 1

    #include "project.h"

    CONTYPE MENUBARId = SOB_CONTAINER_NO;

SOBDATA *   MENUBARLastCreated = NULL;

// ---------------------------------

static  myUInt ReSize_MENUBAR(SOBDATA* conData)
{   // conData   = address of the SOBDATA of the MENUBAR CONTAINER

    swprintf_s(txtBuffer, szTxtBuffer, _TEXT("MENUBAR.ReSize method not supported\n"));  ReportError(txtBuffer);
    return SOB_NOK;
}

// ---------------------------------

CONTAINERINFORM Display_MENUBAR;
static  myUInt Display_MENUBAR(SOBDATA* conData)
{   // conData   = & SOBDATA for the CONTAINER   being displayed

    swprintf_s(txtBuffer, szTxtBuffer, _TEXT("MENUBAR.Display method not supported\n"));  ReportError(txtBuffer);
    return SOB_NOK;
}

// ---------------------------------

SOBFNC_GETTEXT MENUBAR_SOB_GetTypeText;
static TCHAR* MENUBAR_SOB_GetTypeText(SOBDATA* thisSob)
{
    static TCHAR objType[] = TEXT("MENUBAR");
    return  objType;
}

CONTAINERGETTEXT GetTypeText_MENUBAR;
static  TCHAR* GetTypeText_MENUBAR(SOBDATA* conData)
{

    if (fnInvalidSobGeneric(conData))
    {
        swprintf_s(txtBuffer, szTxtBuffer, _TEXT("MENUBAR.GetTypeText given an invalid SOBOBJ\n"));  ReportError(txtBuffer);
        return NULL;
    }

    if (conData->subType NEQU MENUBARId)
    {
        swprintf_s(txtBuffer, szTxtBuffer, _TEXT("MENUBAR.GetTypeText given a non MENUBAR object\n"));  ReportError(txtBuffer);
        SOB.Report(conData);
        return NULL;
    }

    //  swprintf_s(txtBuffer, szTxtBuffer, _TEXT("MENUBAR.GetTypeText\n"));  ReportError(txtBuffer);

    return   MENUBAR_SOB_GetTypeText(conData);
}

// ---------------------------------

CONTAINERINFORM  UpDateChildren_MENUBAR;

static  myUInt UpDateChildren_MENUBAR(SOBDATA* conData)
{   // conData   = address of the SOBDATA of the MENUBAR CONTAINER   that is UPDATING it's children

    //   swprintf_s(txtBuffer, szTxtBuffer, _TEXT("MENUBAR.UpDateChildren method not supported\n"));  ReportError(txtBuffer);
    return SOB_OK;
}

// ---------------------------------

CONTAINERINFORM  Open_MENUBAR;
static  myUInt Open_MENUBAR(SOBDATA* conData)
{   // conData   = address of the SOBDATA of the MENUBAR CONTAINER   being Opened
    // i.e. made the parent of container of subsequent children

    // ---------------------------------

    if (fnInvalidSobGeneric(conData))
    {
        swprintf_s(txtBuffer, szTxtBuffer, _TEXT("MENUBAR.Open given an invalid SOBOBJ\n"));  ReportError(txtBuffer);
        return SOB_NOK;
    }

    if (conData->subType NEQU MENUBARId)
    {
        swprintf_s(txtBuffer, szTxtBuffer, _TEXT("MENUBAR.Open given a non MENUBAR object\n"));  ReportError(txtBuffer);
        return SOB_NOK;
    }

    // swprintf_s(txtBuffer, szTxtBuffer, _TEXT("MENUBAR.Open\n"));  ReportError(txtBuffer);

    sob_set_pSobObj(conData);

    return SOB_OK;
}

CONTAINERINFORM  Update_MENUBAR;
static  myUInt Update_MENUBAR(SOBDATA* conData)
{   // conData   = address of the SOBDATA of the MENUBAR CONTAINER   being UPDATED

    //   swprintf_s(txtBuffer, szTxtBuffer, _TEXT("MENUBAR.UpDate method not supported\n"));  ReportError(txtBuffer);
    return SOB_NOK;
}

// ---------------------------------
CONTAINERINFORM   UpDateParent_MENUBAR;

static  myUInt UpDateParent_MENUBAR(SOBDATA* childObject)
{   // childObject   = address of the SOBDATA of the CHILD object   being added

    //   swprintf_s(txtBuffer, szTxtBuffer, _TEXT("MENUBAR.UpDateParent method not supported\n"));  ReportError(txtBuffer);
    return SOB_OK;
}
// ---------------------------------

static myUInt MENUBAR_SOB_Delete(SOBDATA* thisSob)
{
    // we need this function so that when a CONTAINER is deleted
    // it can trigger a delete of any widget related things of it's child
    // SOB OBJECTs here:-

    if (fnInvalidSobGeneric(thisSob))
    {
        swprintf_s(txtBuffer, szTxtBuffer, _TEXT("MENUBAR.Delete given an invalid SOBOBJ\n"));  ReportError(txtBuffer);
        return SOB_NOK;
    }

    if (thisSob->subType NEQU MENUBARId)
    {
        swprintf_s(txtBuffer, szTxtBuffer, _TEXT("MENUBAR.Delete given a non MENUV object\n"));  ReportError(txtBuffer);
        return SOB_NOK;
    }

    SOBDATA* childObject = NULL;

    childObject = sob_get_first_child(thisSob);
    while (childObject)
    {
        childObject->fncCustomDelete(childObject);

        childObject = sob_get_next_child(childObject);
    }

    DestroyMenu((HMENU)thisSob->hMenu);

    sobObj_delete(thisSob);
    return SOB_OK;
}

CONTAINERINFORM   Delete_MENUBAR;

static  myUInt Delete_MENUBAR(SOBDATA* conData)
{   // conData   = address of the SOBDATA of the MENUBAR CONTAINER   being DELETED

    swprintf_s(txtBuffer, szTxtBuffer, _TEXT("MENUBAR.Delete method not supported\n"));  ReportError(txtBuffer);
    return SOB_NOK;
}

// ---------------------------------

CONTAINERSETVALUE Stretch_MENUBAR;
static myUInt Stretch_MENUBAR(SOBDATA* conData, myUInt value)
{   // conData   = address of the SOBDATA of the MENUBAR CONTAINER

    swprintf_s(txtBuffer, szTxtBuffer, _TEXT("MENUBAR.Stretch method not supported\n"));  ReportError(txtBuffer);
    return SOB_NOK;
}

// ---------------------------------

CONTAINERCREATE  LastWidget_MENUBAR;
static  SOBDATA* LastWidget_MENUBAR()
{
    return MENUBARLastCreated;
}

static  SOBDATA* FirstChild_MENUBAR(SOBDATA* conData)
{
    if (fnInvalidSobGeneric(conData))
    {
        swprintf_s(txtBuffer, szTxtBuffer, _TEXT("MENUBAR.FirstChild given an invalid SOBOBJ\n"));  ReportError(txtBuffer);
        return NULL;
    }

    if (conData->subType NEQU MENUBARId)
    {
        swprintf_s(txtBuffer, szTxtBuffer, _TEXT("MENUBAR.FirstChild given a non ROWHEIGHTFRAME object\n"));  ReportError(txtBuffer);
        SOB.Report(conData);
        return NULL;
    }

    return  conData->headLink;
}

static  myUInt DeleteChildren_MENUBAR(SOBDATA* conData)
{   // conData   = address of the SOBDATA of the MENUV CONTAINER   being DELETED

    return CONTAINER.DeleteChildren(conData);
}

// ---------------------------------
CONTAINERCREATE Create_MENUBAR;
static  PVTBL* MENUBAR_get_container_vtbl()
{
    static PVTBL conTable;
    static int  conTableFlag = 0;

    if (!conTableFlag)
    {
        // only need to initialise this table once since it is common to all containers of type   MENUBAR

        conTable.AddChild = UpDateParent_MENUBAR;
        conTable.Update = Update_MENUBAR;
        conTable.Delete = Delete_MENUBAR;
        conTable.Display = Display_MENUBAR;
        conTable.TypeText = GetTypeText_MENUBAR;
        conTable.Stretch = Stretch_MENUBAR;
        conTable.Create = Create_MENUBAR;
        conTable.UpDateChildren = UpDateChildren_MENUBAR;
        conTable.ReSize = ReSize_MENUBAR;
        conTable.Open = Open_MENUBAR;

        conTableFlag = 1;
    }
    return &conTable;
}

// ----------------------------------------------------------------
// the MENUBAR "constructor" function
// ----------------------------------------------------------------
// some   containers do not need any parameters
// Modify this to suit your needs

static SOBDATA* internalCreate_MENUBAR()
{
    if (MENUBARId EQU SOB_CONTAINER_NO)
    {
        MENUBARId = SOB_CONTAINER_MENU_BAR;
    }

    // the current PARENT MUST BE a SOB_CONTAINER_WINDOW
    // Can only add a MENU BAR to a WINDOW

    SOBID pSobId = sob_get_pSobIndex();

    CONTYPE conType = sob_get_subtype(pSobId);

    if (conType NEQU SOB_CONTAINER_WINDOW)
    {
        swprintf_s(txtBuffer, szTxtBuffer, L"Parent id %x not a WINDOW, but a %ws.\n", pSobId, sob_container_to_text(conType));
        ReportError(txtBuffer);
        return NULL;
    }
    MAINTYPE type = sob_get_type(pSobId);

    HWND pHWND = sob_get_HWND(pSobId);

    // -----------------------------

    SOBDATA* sData = sob_new_new(SOB_TYPE_CONTAINER, MENUBARId, 0, 0);

    // ---------------------------------
    // overwrite some of the default SOB  handlers with  custom ones for a MENUV
    sData->fncCustomDelete = MENUBAR_SOB_Delete;

    sData->fncCustomGetTypeText = MENUBAR_SOB_GetTypeText;

    sData->pVtbl = (MNGR_METHOD_TABLE_GENERIC*)MENUBAR_get_container_vtbl();
    // -----------------------------

    // if parent WINDOW has a MENUBAR then destroy it
    HMENU childHMENU;

    if ((childHMENU = GetMenu(pHWND)))
    DestroyMenu(childHMENU);

    childHMENU = CreateMenu();
    SetMenu(pHWND, childHMENU);
    sData->hMenu = childHMENU;
    //    sob_set_HMENU(sData->sIndex, childHMENU);

    MENUBARLastCreated =     sData;

    return sData;
    // -----------------------------
}

static  SOBDATA* Create_MENUBAR()
{
    return internalCreate_MENUBAR();
}

// ---------------------------------

PVTBL_MENUBAR   MENUBAR =
{
    UpDateParent_MENUBAR
    , Update_MENUBAR
    , Delete_MENUBAR
    , Display_MENUBAR
    , GetTypeText_MENUBAR
    , Stretch_MENUBAR

    , ReSize_MENUBAR
    , UpDateChildren_MENUBAR
    , Open_MENUBAR

    , LastWidget_MENUBAR

    , FirstChild_MENUBAR

    , DeleteChildren_MENUBAR

    , Create_MENUBAR
};
// ----------------------------------------------------------------
// the MENUBAR
// ----------------------------------------------------------------

union
{
    SOBDATA* thisSob;
    MENUBAROBJECT* thisObject;
} MENUBAR_cast = {0};

#endif
