menu.cpp

来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 750 行 · 第 1/2 页

CPP
750
字号
}

void wxMenuBar::SetLabelTop(size_t pos, const wxString& label)
{
    wxCHECK_RET( pos < GetMenuCount(), wxT("invalid menu index") );

    m_titles[pos]=wxStripMenuCodes(label);

    if ( !IsAttached() )
    {
        return;
    }

       // Regenerate the menu resource
    Refresh();
}

wxString wxMenuBar::GetLabelTop(size_t pos) const
{
    wxCHECK_MSG( pos < GetMenuCount(), wxEmptyString,
                 wxT("invalid menu index in wxMenuBar::GetLabelTop") );

    return wxMenuItem::GetLabelFromText(m_titles[pos]);
}

// ---------------------------------------------------------------------------
// wxMenuBar construction
// ---------------------------------------------------------------------------

wxMenu *wxMenuBar::Replace(size_t pos, wxMenu *menu, const wxString& title)
{
   wxMenu *menuOld = wxMenuBarBase::Replace(pos, menu, title);
    if ( !menuOld )
        return NULL;

    m_titles[pos]=wxStripMenuCodes(title);

    if ( IsAttached() )
    {
        // Regenerate the menu resource
        Refresh();
    }

    return menuOld;
}

bool wxMenuBar::Insert(size_t pos, wxMenu *menu, const wxString& title)
{
    if ( !wxMenuBarBase::Insert(pos, menu, title) )
        return false;

    m_titles.Insert(wxStripMenuCodes(title), pos);

    if ( IsAttached() )
    {
        // Regenerate the menu resource
        Refresh();
    }

    return true;
}

bool wxMenuBar::Append(wxMenu *menu, const wxString& title)
{
    if ( !wxMenuBarBase::Append(menu, title) )
        return false;

    m_titles.Add(wxStripMenuCodes(title));

    if(IsAttached())
    {
        // Regenerate the menu resource
        Refresh();
    }

    return true;
}

wxMenu *wxMenuBar::Remove(size_t pos)
{
    wxMenu *menu = wxMenuBarBase::Remove(pos);
    if ( !menu )
        return NULL;

    m_titles.RemoveAt(pos);

    if (IsAttached())
    {
        // Regenerate the menu resource
        Refresh();
    }

    return menu;
}

#if wxUSE_ACCEL

void wxMenuBar::RebuildAccelTable()
{
}

#endif // wxUSE_ACCEL

int wxMenuBar::ProcessCommand(int ItemID)
{
    if(!IsAttached())
        return -1;

    int MenuNum=(ItemID/1000)-1;
    int ItemNum=(ItemID-(1000*(MenuNum+1)));

    // Should never happen, but it doesn't hurt to check anyway.
    if(MenuNum>GetMenuCount())
        return -1;

    // Get the menu
    wxMenu *ActiveMenu=GetMenu(MenuNum);

    // Make sure this is a valid item.
    if(ItemNum>ActiveMenu->GetMenuItemCount())
        return -1;

    // Get the item
    wxMenuItem *ActiveItem=ActiveMenu->FindItemByPosition(ItemNum);
    int ActiveID=ActiveItem->GetId();

    return ActiveID;
}

/* Palm OS does not have good dynamic menu support.  About all you can do with
 * the standard API calls is to add new items to an existing drop-down menu and
 * hide/show items in a drop-down menu.  It is impossible to add, hide, or
 * change the label on a drop-down menu.
 *
 * The easiest and simplest way around this limitation is to modify the Palm OS
 * MenuBarType structure directly.  This gives limited ability to change the
 * label on a drop-down menu.  I have not been able to find a safe way to add,
 * delete, or resize drop-down menus in OS 6.
 *
 * The following routine attempt to work around these limitations present in the
 * Palm OS API to provide limited dynamic menu support.  This solution is far
 * from perfect, but the only other option is to wait for PalmSource to add full
 * dynamic menu support, or to recreate the Palm OS menu system from scratch.
 *
 * This system is limited in that no more than 4 drop-down menus are allowed per
 * menu bar, and the label for each drop-down menu is limited to 8 characters of
 * text.  However, this menu system should work for most applications.
 *
 * Basically the menu routines select one of four menu bars, depending on
 * whether or not the requested menu bar has one, two, three, or four drop-down
 * menus.
 *
 * These four "template" menu bars contain one, two, three, or four drop-down
 * menus.  Each menu has a dummy menu item attached to it to allow the Palm OS
 * MenuAddItem function to add the real items.
 *
 * The labels on the drop-down menus are then replaced with the labels of the
 * real menus.
 *
 * The menu is then attached to the active window and the MenuAddItem API
 * function is called to add the items to each drop-down menu.  Finally,
 * MenuHideItem is called to remove the dummy items from each drop-down menu.
 */
void wxMenuBar::LoadMenu()
{
    int i=0;
    int j=0;

    // Handle to the currently running application database
    DmOpenRef    AppDB;

    // Get app database reference - needed for some Palm OS Menu API calls.
    SysGetModuleDatabase(SysGetRefNum(), NULL, &AppDB);

    // Get the number of menus
    int NumMenus=GetMenuCount();

    // Set up the pointers and handles
    char *PalmOSMenuBarPtr;
    MemHandle PalmOSMenuBar;

    // Load the menu template and set up the menu pointers
    if(NumMenus==1)
    {
        PalmOSMenuBar=DmGetResource(AppDB,'MBAR',1000);
        PalmOSMenuBarPtr=(char *)MemHandleLock(PalmOSMenuBar);

        PalmOSMenuBarPtr+=74;
    }
    else if(NumMenus==2)
    {
        PalmOSMenuBar=DmGetResource(AppDB,'MBAR',2000);
        PalmOSMenuBarPtr=(char *)MemHandleLock(PalmOSMenuBar);

        PalmOSMenuBarPtr+=116;
    }
    else if(NumMenus==3)
    {
        PalmOSMenuBar=DmGetResource(AppDB,'MBAR',3000);
        PalmOSMenuBarPtr=(char *)MemHandleLock(PalmOSMenuBar);

        PalmOSMenuBarPtr+=158;
    }
    else
    {
        // We support a maximum of 4 menus, so make sure that do not create
        // more than we can handle.
        NumMenus=4;

        PalmOSMenuBar=DmGetResource(AppDB,'MBAR',4000);
        PalmOSMenuBarPtr=(char *)MemHandleLock(PalmOSMenuBar);

        PalmOSMenuBarPtr+=200;
    }

    // Set the proper names for the drop-down triggers.
    for(i=0;i<NumMenus;i++)
    {
        // Clear out the old label
        char buffer[8]={' ',' ',' ',' ',' ',' ',' ',' '};
        MemMove(PalmOSMenuBarPtr,buffer,8);

        wxString MenuTitle=m_titles.Item(i);

        // Make sure we don't copy more than 8 bytes for the label
        int LengthToCopy=MenuTitle.length();
        if(LengthToCopy>8)
            LengthToCopy=8;

        MemMove(PalmOSMenuBarPtr,MenuTitle,LengthToCopy);
        PalmOSMenuBarPtr+=11;
    }

    // We are done with the menu pointer.
    MemHandleUnlock(PalmOSMenuBar);
    DmReleaseResource(PalmOSMenuBar);

    // We must make the menu active before we can add items to the drop-down
    // triggers.
    FrmSetMenu(FrmGetActiveForm(),AppDB,NumMenus*1000);

    /* Add the menu items to the drop-down triggers.  This must be done after
     * setting the triggers, because setting the names of drop-down triggers
     * that have a variable number of items requires carefull calculation of
     * the offsets in the MenuBarType structure.  Setting the triggers first
     * avoids this.
     */
    for(i=0;i<NumMenus;i++)
    {
        wxMenu *CurrentMenu=GetMenu(i);

        for(j=0;j<CurrentMenu->GetMenuItemCount();j++)
        {
            wxMenuItem *CurrentItem=CurrentMenu->FindItemByPosition(j);
            wxString ItemLabel=CurrentItem->GetLabel();

            if(CurrentItem->IsSeparator()==true)
            {
                char Separator=MenuSeparatorChar;
                if(j==0)
                    MenuAddItem(9000+i,((i*1000)+1000)+j,0x00,&Separator);
                else
                    MenuAddItem(((i*1000)+1000)+j-1,((i*1000)+1000)+j,0x00,&Separator);
            }
            else
            {
                if(j==0)
                    MenuAddItem(9000+i,((i*1000)+1000)+j,0x00,ItemLabel);
                else
                    MenuAddItem(((i*1000)+1000)+j-1,((i*1000)+1000)+j,0x00,ItemLabel);
            }
        }

        // Hide the dummy menu item, since we don't need it anymore.
        MenuHideItem(9000+i);
    }
}

void wxMenuBar::Attach(wxFrame *frame)
{
    // before attaching preprocess menus to not include wxID_EXIT item
    // as PalmOS guidelines suggest

    wxMenuItem *item;
    wxMenu *menu;
    int i;

    while( item = FindItem(wxID_EXIT) )
    {
        menu = item->GetMenu();
        if( !menu ) break; // something broken ?

        size_t count = menu->GetMenuItemCount();
        if( count == 0 ) break; // something broken ?

        // if EXIT is last item in menu
        if( menu->FindItemByPosition( count - 1 ) == item )
        {
            menu->Destroy( item );

            // was more than one item?
            // was previous separator ?
            if( count > 2 )
            {
                item = menu->FindItemByPosition( count - 2 );
                if(item && item->IsSeparator())
                    menu->Destroy( item );
            }
        }

        // if EXIT is first item in menu
        else if( menu->FindItemByPosition( 0 ) == item )
        {
            menu->Destroy( item );

            // was more than one item?
            // was previous separator ?
            if( count > 2 )
            {
                item = menu->FindItemByPosition( 0 );
                if(item && item->IsSeparator())
                    menu->Destroy( item );
            }
        }

        // if EXIT is in the middle but before and after are selectors
        else
        {
            i = 1; // 0 case already done
            while ( (i < count) && (menu->FindItemByPosition( 0 ) != item) )
            {
                i++;
            }

            if (i >= count) break;
            if (menu->FindItemByPosition( i ) != item) break;
            menu->Destroy( item );
            item = menu->FindItemByPosition( i );
            if ( item &&
                 item->IsSeparator() &&
                 menu->FindItemByPosition( i-1 )->IsSeparator() )
            {
                // noe need for two neighbouring separators
                menu->Destroy( item );
            }
        }
    }

    // check if we received any empty menu!
    i = 0;
    while(i < GetMenuCount())
    {
        menu = GetMenu(i);

        if( menu && (menu->GetMenuItemCount()==0) )
        {
            menu = Remove( i );
            delete menu;
        }
        else
            i++;
    }

    wxMenuBarBase::Attach(frame);

    LoadMenu();
}

void wxMenuBar::Detach()
{
    wxMenuBarBase::Detach();
}

#endif // wxUSE_MENUS

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?