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 + -
显示快捷键?