wxMenu* wxFindMenuFromMacCommand( const HICommand &command , wxMenuItem* &item ) { wxMenu* itemMenu = NULL ; #ifndef __WXUNIVERSAL__ int id = 0 ; // for 'standard' commands which don't have a wx-menu if ( command.commandID == kHICommandPreferences || command.commandID == kHICommandQuit || command.commandID == kHICommandAbout ) { id = wxMacCommandToId( command.commandID ) ; wxMenuBar* mbar = wxMenuBar::MacGetInstalledMenuBar() ; if ( mbar ) item = mbar->FindItem( id , &itemMenu ) ; } else if ( command.commandID != 0 && command.menu.menuRef != 0 && command.menu.menuItemIndex != 0 ) { id = wxMacCommandToId( command.commandID ) ; // make sure it is one of our own menus, or of the 'synthetic' apple and help menus , otherwise don't touch MenuItemIndex firstUserHelpMenuItem ; static MenuHandle helpMenuHandle = NULL ; if ( helpMenuHandle == NULL ) { if ( UMAGetHelpMenuDontCreate( &helpMenuHandle , &firstUserHelpMenuItem) != noErr ) helpMenuHandle = NULL ; } // is it part of the application or the Help menu, then look for the id directly if ( ( GetMenuHandle( kwxMacAppleMenuId ) != NULL && command.menu.menuRef == GetMenuHandle( kwxMacAppleMenuId ) ) || ( helpMenuHandle != NULL && command.menu.menuRef == helpMenuHandle ) || wxMenuBar::MacGetWindowMenuHMenu() != NULL && command.menu.menuRef == wxMenuBar::MacGetWindowMenuHMenu() ) { wxMenuBar* mbar = wxMenuBar::MacGetInstalledMenuBar() ; if ( mbar ) item = mbar->FindItem( id , &itemMenu ) ; } else { URefCon refCon = 0 ; GetMenuItemRefCon( command.menu.menuRef , command.menu.menuItemIndex , &refCon ) ; itemMenu = wxFindMenuFromMacMenu( command.menu.menuRef ) ; if ( itemMenu != NULL && refCon != 0) item = (wxMenuItem*) refCon; } } #endif return itemMenu ; }
static pascal OSStatus wxMacAppCommandEventHandler( EventHandlerCallRef handler , EventRef event , void *data ) { OSStatus result = eventNotHandledErr ; HICommand command ; wxMacCarbonEvent cEvent( event ) ; cEvent.GetParameter<HICommand>(kEventParamDirectObject,typeHICommand,&command) ; wxMenuItem* item = NULL ; wxMenu* itemMenu = wxFindMenuFromMacCommand( command , item ) ; int id = wxMacCommandToId( command.commandID ) ; if ( item ) { wxASSERT( itemMenu != NULL ) ; switch ( cEvent.GetKind() ) { case kEventProcessCommand : result = itemMenu->MacHandleCommandProcess( item, id ); break ; case kEventCommandUpdateStatus: result = itemMenu->MacHandleCommandUpdateStatus( item, id ); break ; default : break ; } } return result ; }
virtual void PopUp( wxWindow *WXUNUSED(win), int x, int y ) { long menuResult = ::PopUpMenuSelect(m_osxMenu, y, x, 0) ; if ( HiWord(menuResult) != 0 ) { MenuCommand macid; GetMenuItemCommandID( GetMenuHandle(HiWord(menuResult)) , LoWord(menuResult) , &macid ); int id = wxMacCommandToId( macid ); wxMenuItem* item = NULL ; wxMenu* realmenu ; item = m_peer->FindItem( id, &realmenu ) ; if ( item ) { m_peer->HandleCommandProcess(item, NULL ); } } }
//----------------------------------------------------------------------------- // wxDockEventHandler // // This is the global Mac/Carbon event handler for the dock. // We need this for two reasons: // 1) To handle wxTaskBarIcon menu events (see below for why) // 2) To handle events from the dock when it requests a menu //----------------------------------------------------------------------------- pascal OSStatus wxDockEventHandler(EventHandlerCallRef WXUNUSED(inHandlerCallRef), EventRef inEvent, void *pData) { // Get the parameters we want from the event wxDockTaskBarIcon* pTB = (wxDockTaskBarIcon*) pData; const UInt32 eventClass = GetEventClass(inEvent); const UInt32 eventKind = GetEventKind(inEvent); OSStatus err = eventNotHandledErr; // Handle wxTaskBar menu events (note that this is a global event handler // so it will actually get called by all commands/menus) if ((eventClass == kEventClassCommand) && (eventKind == kEventCommandProcess || eventKind == kEventCommandUpdateStatus )) { // if we have no taskbar menu quickly pass it back to wxApp if (pTB->m_pMenu != NULL) { // This is the real reason why we need this. Normally menus // get handled in wxMacAppEventHandler // However, in the case of a taskbar menu call // command.menu.menuRef IS NULL! // Which causes the wxApp handler just to skip it. // get the HICommand from the event HICommand command; if (GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand, NULL,sizeof(HICommand), NULL, &command ) == noErr) { // Obtain the REAL menuRef and the menuItemIndex in the real menuRef // // NOTE: menuRef is generally used here for submenus, as // GetMenuItemRefCon could give an incorrect wxMenuItem if we pass // just the top level wxTaskBar menu MenuItemIndex menuItemIndex; MenuRef menuRef; MenuRef taskbarMenuRef = MAC_WXHMENU(pTB->m_pMenu->GetHMenu()); // the next command is only successful if it was a command from the taskbar menu // otherwise we pass it on if (GetIndMenuItemWithCommandID(taskbarMenuRef,command.commandID, 1, &menuRef, &menuItemIndex ) == noErr) { wxMenu* itemMenu = wxFindMenuFromMacMenu( menuRef ) ; int id = wxMacCommandToId( command.commandID ) ; wxMenuItem *item = NULL; if (id != 0) // get the wxMenuItem reference from the MenuRef GetMenuItemRefCon( menuRef, menuItemIndex, (URefCon*) &item ); if (item && itemMenu ) { if ( eventKind == kEventCommandProcess ) { if ( itemMenu->HandleCommandProcess( item ) ) err = noErr; } else if ( eventKind == kEventCommandUpdateStatus ) { if ( itemMenu->HandleCommandUpdateStatus( item ) ) err = noErr; } } } } } //end if noErr on getting HICommand from event } else if ((eventClass == kEventClassApplication) && (eventKind == kEventAppGetDockTileMenu )) { // process the right click events // NB: This may result in double or even triple-creation of the menus // We need to do this for 2.4 compat, however wxTaskBarIconEvent downevt(wxEVT_TASKBAR_RIGHT_DOWN, NULL); pTB->m_parent->ProcessEvent(downevt); wxTaskBarIconEvent upevt(wxEVT_TASKBAR_RIGHT_UP, NULL); pTB->m_parent->ProcessEvent(upevt); // create popup menu wxMenu* menu = pTB->DoCreatePopupMenu(); if (menu != NULL) { // note to self - a MenuRef *is* a MenuHandle MenuRef hMenu = MAC_WXHMENU(menu->GetHMenu()); // When SetEventParameter is called it will decrement // the reference count of the menu - we need to make // sure it stays around in the wxMenu class here CFRetain(hMenu); // set the actual dock menu err = SetEventParameter( inEvent, kEventParamMenuRef, typeMenuRef, sizeof(MenuRef), &hMenu ); verify_noerr( err ); } } return err; }