X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/ad18ae6252122b80ffc3c8f16c4ee3a710126d8b..1b499eb38ee3f706c9881674b020d1980794d74a:/src/msw/menu.cpp diff --git a/src/msw/menu.cpp b/src/msw/menu.cpp index 38a7dfadd9..478048e703 100644 --- a/src/msw/menu.cpp +++ b/src/msw/menu.cpp @@ -36,7 +36,6 @@ #include "wx/utils.h" #include "wx/intl.h" #include "wx/log.h" - #include "wx/mdi.h" #endif #if wxUSE_OWNER_DRAWN @@ -52,12 +51,12 @@ #include #include #include +#if _WIN32_WCE < 400 #include - -#ifndef TBSTYLE_NO_DROPDOWN_ARROW -#define TBSTYLE_NO_DROPDOWN_ARROW 0x0080 #endif +#include "wx/msw/wince/missing.h" + #endif // other standard headers @@ -674,8 +673,14 @@ void wxMenuBar::Init() { m_eventHandler = this; m_hMenu = 0; -#ifdef __WXWINCE__ +#if wxUSE_TOOLBAR && defined(__WXWINCE__) && (_WIN32_WCE < 400 || wxUSE_POCKETPC_UI) m_toolBar = NULL; +#endif + // Not using a combined wxToolBar/wxMenuBar? then use + // a commandbar in WinCE .NET just to implement the + // menubar. +#if defined(__WXWINCE__) && (_WIN32_WCE >= 400 && !wxUSE_POCKETPC_UI) + m_commandBar = NULL; #endif } @@ -706,9 +711,9 @@ wxMenuBar::wxMenuBar(int count, wxMenu *menus[], const wxString titles[]) wxMenuBar::~wxMenuBar() { - // In Windows CE, the menubar is always associated + // In Windows CE (not .NET), the menubar is always associated // with a toolbar, which destroys the menu implicitly. -#ifdef __WXWINCE__ +#if defined(__WXWINCE__) && (_WIN32_WCE < 400 || wxUSE_POCKETPC_UI) if (GetToolBar()) GetToolBar()->SetMenuBar(NULL); #else @@ -716,7 +721,12 @@ wxMenuBar::~wxMenuBar() // which happens if we're attached to a frame if (m_hMenu && !IsAttached()) { +#if defined(__WXWINCE__) && (_WIN32_WCE >= 400 && !wxUSE_POCKETPC_UI) + ::DestroyWindow((HWND) m_commandBar); + m_commandBar = (WXHWND) NULL; +#else ::DestroyMenu((HMENU)m_hMenu); +#endif m_hMenu = (WXHMENU)NULL; } #endif @@ -730,11 +740,14 @@ void wxMenuBar::Refresh() { wxCHECK_RET( IsAttached(), wxT("can't refresh unattached menubar") ); -#ifdef __WXWINCE__ +#if defined(__WXWINCE__) && (_WIN32_WCE < 400 || wxUSE_POCKETPC_UI) if (GetToolBar()) { CommandBar_DrawMenuBar((HWND) GetToolBar()->GetHWND(), 0); } +#elif defined(__WXWINCE__) && (_WIN32_WCE >= 400 && !wxUSE_POCKETPC_UI) + if (m_commandBar) + DrawMenuBar((HWND) m_commandBar); #else DrawMenuBar(GetHwndOf(GetFrame())); #endif @@ -746,7 +759,7 @@ WXHMENU wxMenuBar::Create() // since you have to use resources. // We'll have to find another way to add a menu // by changing/adding menu items to an existing menu. -#ifdef __WXWINCE__ +#if defined(__WXWINCE__) && _WIN32_WCE < 400 if ( m_hMenu != 0 ) return m_hMenu; @@ -811,6 +824,27 @@ WXHMENU wxMenuBar::Create() #endif } +int wxMenuBar::MSWPositionForWxMenu(wxMenu *menu, int wxpos) +{ + wxASSERT(menu); + wxASSERT(menu->GetHMenu()); + wxASSERT(m_hMenu); + int totalMSWItems = GetMenuItemCount((HMENU)m_hMenu); + int i; // For old C++ compatibility + for(i=wxpos; iGetHMenu()) + return i; + } + for(i=0; iGetHMenu()) + return i; + } + wxFAIL; + return -1; +} + // --------------------------------------------------------------------------- // wxMenuBar functions to work with the top level submenus // --------------------------------------------------------------------------- @@ -821,10 +855,11 @@ WXHMENU wxMenuBar::Create() void wxMenuBar::EnableTop(size_t pos, bool enable) { wxCHECK_RET( IsAttached(), wxT("doesn't work with unattached menubars") ); + wxCHECK_RET( pos < GetMenuCount(), wxT("invalid menu index") ); int flag = enable ? MF_ENABLED : MF_GRAYED; - EnableMenuItem((HMENU)m_hMenu, pos, MF_BYPOSITION | flag); + EnableMenuItem((HMENU)m_hMenu, MSWPositionForWxMenu(GetMenu(pos),pos), MF_BYPOSITION | flag); Refresh(); } @@ -841,8 +876,10 @@ void wxMenuBar::SetLabelTop(size_t pos, const wxString& label) } //else: have to modify the existing menu + int mswpos = MSWPositionForWxMenu(GetMenu(pos),pos); + UINT id; - UINT flagsOld = ::GetMenuState((HMENU)m_hMenu, pos, MF_BYPOSITION); + UINT flagsOld = ::GetMenuState((HMENU)m_hMenu, mswpos, MF_BYPOSITION); if ( flagsOld == 0xFFFFFFFF ) { wxLogLastError(wxT("GetMenuState")); @@ -854,7 +891,7 @@ void wxMenuBar::SetLabelTop(size_t pos, const wxString& label) { // HIBYTE contains the number of items in the submenu in this case flagsOld &= 0xff; - id = (UINT)::GetSubMenu((HMENU)m_hMenu, pos); + id = (UINT)::GetSubMenu((HMENU)m_hMenu, mswpos); } else { @@ -875,7 +912,7 @@ void wxMenuBar::SetLabelTop(size_t pos, const wxString& label) } #else - if ( ::ModifyMenu(GetHmenu(), pos, MF_BYPOSITION | MF_STRING | flagsOld, + if ( ::ModifyMenu(GetHmenu(), mswpos, MF_BYPOSITION | MF_STRING | flagsOld, id, label) == (int)0xFFFFFFFF ) { wxLogLastError(wxT("ModifyMenu")); @@ -907,13 +944,15 @@ wxMenu *wxMenuBar::Replace(size_t pos, wxMenu *menu, const wxString& title) if ( IsAttached() ) { + int mswpos = MSWPositionForWxMenu(menuOld,pos); + // can't use ModifyMenu() because it deletes the submenu it replaces - if ( !::RemoveMenu(GetHmenu(), (UINT)pos, MF_BYPOSITION) ) + if ( !::RemoveMenu(GetHmenu(), (UINT)mswpos, MF_BYPOSITION) ) { wxLogLastError(wxT("RemoveMenu")); } - if ( !::InsertMenu(GetHmenu(), (UINT)pos, + if ( !::InsertMenu(GetHmenu(), (UINT)mswpos, MF_BYPOSITION | MF_POPUP | MF_STRING, (UINT)GetHmenuOf(menu), title) ) { @@ -936,6 +975,13 @@ wxMenu *wxMenuBar::Replace(size_t pos, wxMenu *menu, const wxString& title) bool wxMenuBar::Insert(size_t pos, wxMenu *menu, const wxString& title) { + // Find out which MSW item before which we'll be inserting before + // wxMenuBarBase::Insert is called and GetMenu(pos) is the new menu. + // If IsAttached() is false this won't be used anyway + int mswpos = (!IsAttached() || (pos == m_menus.GetCount())) + ? -1 // append the menu + : MSWPositionForWxMenu(GetMenu(pos),pos); + if ( !wxMenuBarBase::Insert(pos, menu, title) ) return FALSE; @@ -943,7 +989,7 @@ bool wxMenuBar::Insert(size_t pos, wxMenu *menu, const wxString& title) if ( IsAttached() ) { -#ifdef __WXWINCE__ +#if defined(__WXWINCE__) && (_WIN32_WCE < 400 || wxUSE_POCKETPC_UI) if (!GetToolBar()) return FALSE; TBBUTTON tbButton; @@ -964,7 +1010,7 @@ bool wxMenuBar::Insert(size_t pos, wxMenu *menu, const wxString& title) return FALSE; } #else - if ( !::InsertMenu(GetHmenu(), pos, + if ( !::InsertMenu(GetHmenu(), mswpos, MF_BYPOSITION | MF_POPUP | MF_STRING, (UINT)GetHmenuOf(menu), title) ) { @@ -997,7 +1043,7 @@ bool wxMenuBar::Append(wxMenu *menu, const wxString& title) if ( IsAttached() ) { -#ifdef __WXWINCE__ +#if defined(__WXWINCE__) && (_WIN32_WCE < 400 || wxUSE_POCKETPC_UI) if (!GetToolBar()) return FALSE; TBBUTTON tbButton; @@ -1046,12 +1092,9 @@ wxMenu *wxMenuBar::Remove(size_t pos) if ( !menu ) return NULL; - size_t arraypos = pos; - if ( IsAttached() ) { - -#ifdef __WXWINCE__ +#if defined(__WXWINCE__) && (_WIN32_WCE < 400 || wxUSE_POCKETPC_UI) if (GetToolBar()) { if (!::SendMessage((HWND) GetToolBar()->GetHWND(), TB_DELETEBUTTON, (UINT) pos, (LPARAM) 0)) @@ -1060,85 +1103,12 @@ wxMenu *wxMenuBar::Remove(size_t pos) } } #else -#if wxUSE_MDI_ARCHITECTURE - //MDI - window menu stuff - if (GetFrame() && GetFrame()->IsKindOf(CLASSINFO(wxMDIParentFrame))) - { - //There's two cases which we need to deal with in order - //to remove at the correct index with MDI windows - - //#1 is due to the fact that wxWindows sneakely creates - //a new menu item "Window" on the menu bar natively, without - //notifying the actual wxMenuBar. Therefore, the Window - //menu never go into the actual calculations... - //So if a user tries to insert a menu after the Window menu - //his/her calculations will be one(1) index off, since the - //Window menu is before the to-be-removed menu and - //wxMenuBar doesn't know about the existance of it. - - //There are two ways to deal with this - - //1 - is to force the window menu to always be at the end - //of the menu bar (rightmost, greatest index), I.E. - //override remove and insert functions to force - //the window (and help) menus to be at the rightmost positions - //2 - is to increment pos here if the user is trying - //to remove a menu after the Window menu - - //Solution #2 (which if chosen would go here) - //is a little involved - //1. Search for Window menu - //2. If found note where it is - //3. If the removal point is at or above where the Window - // menu is, ++pos - - - //Case #2 is a MSW MDI "feature", where if a child MDI - //frame is maximized, the system menu of the child MDI - //frame is inserted at index 0 of the parent frame. - - //To deal with this we simply check to see if a child MDI - //frame is maximized, then increment the position we - //are going to remove the menu at. - - //Get a pointer to the children of the wxMDIParentFrame - wxWindowList* pParentsChildren = &(GetFrame()->GetChildren()); - - //Iterate through the children - for (size_t n = 0; n < pParentsChildren->GetCount(); ++n) - { - //Check to see if this particular child window is a - //MDI child - if(pParentsChildren->Item(n)->GetData()->IsKindOf(CLASSINFO(wxMDIChildFrame))) - { - //If so then we need to see if it's maximized - - //Get a pointer to the child... - wxMDIChildFrame* pData = (wxMDIChildFrame*) pParentsChildren->Item(n)->GetData(); - - //Is it maximized? - if(pData->IsMaximized()) - { - //Increase the removal position by one - ++pos; - - //Note that in Windows there can - //Only be one maximized child window - //(well not technically, but there - //can only be one child system menu - //prepended to the parent's menu - //bar, which is what we're concerned about) - break; - } - }//end if child == wxMDIChildFrame - }//end children iteration loop - }//end if GetFrame()->IsKindOf(CLASSINFO(wxMDIParentFrame)) -#endif //wxUSE_MDI_ARCHITECTURE - - if ( !::RemoveMenu(GetHmenu(), (UINT)pos, MF_BYPOSITION) ) + if ( !::RemoveMenu(GetHmenu(), (UINT)MSWPositionForWxMenu(menu,pos), MF_BYPOSITION) ) { wxLogLastError(wxT("RemoveMenu")); } #endif + #if wxUSE_ACCEL if ( menu->HasAccels() ) { @@ -1150,7 +1120,8 @@ wxMenu *wxMenuBar::Remove(size_t pos) Refresh(); } - m_titles.RemoveAt(arraypos); + + m_titles.RemoveAt(pos); return menu; } @@ -1190,6 +1161,36 @@ void wxMenuBar::Attach(wxFrame *frame) { wxMenuBarBase::Attach(frame); +#if defined(__WXWINCE__) && _WIN32_WCE >= 400 + if (!m_hMenu) + this->Create(); +#if wxUSE_POCKETPC_UI + if (GetToolBar()) + { + HWND hCommandBar = (HWND) GetToolBar()->GetHWND(); + if (!CommandBar_InsertMenubarEx(hCommandBar, NULL, (LPTSTR) m_hMenu, 0)) + { + wxLogLastError(wxT("CommandBar_InsertMenubarEx")); + } + } +#else + if (!m_commandBar) + m_commandBar = (WXHWND) CommandBar_Create(wxGetInstance(), (HWND) frame->GetHWND(), NewControlId()); + if (m_commandBar) + { + if (m_hMenu) + { + if (!CommandBar_InsertMenubarEx((HWND) m_commandBar, NULL, (LPTSTR) m_hMenu, 0)) + { + wxLogLastError(wxT("CommandBar_InsertMenubarEx")); + } + } + } +#endif + // wxUSE_POCKETPC_UI +#endif + // __WXWINCE__ && _WIN32_WCE >= 400 + #if wxUSE_ACCEL RebuildAccelTable(); #endif // wxUSE_ACCEL