X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/f7f50f493baa177e8ae07d12641095baee55d4f8..e3a6a6b2bc15ddda1d614dd232d37e59ad024044:/src/msw/menu.cpp diff --git a/src/msw/menu.cpp b/src/msw/menu.cpp index eb78604c7d..e8c4c22ce1 100644 --- a/src/msw/menu.cpp +++ b/src/msw/menu.cpp @@ -5,8 +5,8 @@ // Modified by: Vadim Zeitlin // Created: 04/01/98 // RCS-ID: $Id$ -// Copyright: (c) Julian Smart and Markus Holzem -// Licence: wxWindows license +// Copyright: (c) Julian Smart +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// // =========================================================================== @@ -44,6 +44,20 @@ #include "wx/msw/private.h" +#ifdef __WXWINCE__ +#include +#include +#include +#include +#include +#include + +#ifndef TBSTYLE_NO_DROPDOWN_ARROW +#define TBSTYLE_NO_DROPDOWN_ARROW 0x0080 +#endif + +#endif + // other standard headers #include @@ -67,6 +81,7 @@ static const int idMenuTitle = -2; // make the given menu item default static void SetDefaultMenuItem(HMENU hmenu, UINT id) { +#ifndef __WXWINCE__ MENUITEMINFO mii; wxZeroMemory(mii); mii.cbSize = sizeof(MENUITEMINFO); @@ -77,7 +92,21 @@ static void SetDefaultMenuItem(HMENU hmenu, UINT id) { wxLogLastError(wxT("SetMenuItemInfo")); } +#endif +} + +#ifdef __WXWINCE__ +UINT GetMenuState(HMENU hMenu, UINT id, UINT flags) +{ + MENUITEMINFO info; + wxZeroMemory(info); + info.cbSize = sizeof(info); + info.fMask = MIIM_STATE; + if ( !GetMenuItemInfo(hMenu, id, flags & MF_BYCOMMAND ? FALSE : TRUE, & info) ) + wxLogLastError(wxT("GetMenuItemInfo")); + return info.fState; } +#endif // ============================================================================ // implementation @@ -163,7 +192,7 @@ void wxMenu::UpdateAccel(wxMenuItem *item) if ( item->IsSubMenu() ) { wxMenu *submenu = item->GetSubMenu(); - wxMenuItemList::Node *node = submenu->GetMenuItems().GetFirst(); + wxMenuItemList::compatibility_iterator node = submenu->GetMenuItems().GetFirst(); while ( node ) { UpdateAccel(node->GetData()); @@ -245,6 +274,10 @@ bool wxMenu::DoInsertOrAppend(wxMenuItem *pItem, size_t pos) id = pItem->GetId(); } +#ifdef __WXWINCE__ + wxString strippedString; +#endif + LPCTSTR pData; #if wxUSE_OWNER_DRAWN @@ -259,7 +292,12 @@ bool wxMenu::DoInsertOrAppend(wxMenuItem *pItem, size_t pos) // menu is just a normal string (passed in data parameter) flags |= MF_STRING; +#ifdef __WXWINCE__ + strippedString = wxStripMenuCodes(pItem->GetText()); + pData = (wxChar*)strippedString.c_str(); +#else pData = (wxChar*)pItem->GetText().c_str(); +#endif } BOOL ok; @@ -329,7 +367,7 @@ bool wxMenu::DoAppend(wxMenuItem *item) { // we need to update its end item item->SetRadioGroupStart(m_startRadioGroup); - wxMenuItemList::Node *node = GetMenuItems().Item(m_startRadioGroup); + wxMenuItemList::compatibility_iterator node = GetMenuItems().Item(m_startRadioGroup); if ( node ) { @@ -369,7 +407,7 @@ wxMenuItem *wxMenu::DoRemove(wxMenuItem *item) { // we need to find the items position in the child list size_t pos; - wxMenuItemList::Node *node = GetMenuItems().GetFirst(); + wxMenuItemList::compatibility_iterator node = GetMenuItems().GetFirst(); for ( pos = 0; node; pos++ ) { if ( node->GetData() == item ) @@ -467,12 +505,26 @@ void wxMenu::SetTitle(const wxString& label) else { // modify the title +#ifdef __WXWINCE__ + MENUITEMINFO info; + wxZeroMemory(info); + info.cbSize = sizeof(info); + info.fMask = MIIM_TYPE; + info.fType = MFT_STRING; + info.cch = m_title.Length(); + info.dwTypeData = (LPTSTR) m_title.c_str(); + if ( !SetMenuItemInfo(hMenu, 0, TRUE, & info) ) + { + wxLogLastError(wxT("SetMenuItemInfo")); + } +#else if ( !ModifyMenu(hMenu, 0u, MF_BYPOSITION | MF_STRING, (unsigned)idMenuTitle, m_title) ) { wxLogLastError(wxT("ModifyMenu")); } +#endif } } @@ -500,7 +552,8 @@ bool wxMenu::MSWCommand(WXUINT WXUNUSED(param), WXWORD id) // useless anyhow (as it could be retrieved using GetId()) and // uncompatible with wxGTK, so now we use the command int instead // to pass the checked status - SendEvent(id, ::GetMenuState(GetHmenu(), id, MF_BYCOMMAND) & MF_CHECKED); + UINT menuState = ::GetMenuState(GetHmenu(), id, MF_BYCOMMAND) ; + SendEvent(id, menuState & MF_CHECKED); } return TRUE; @@ -528,6 +581,9 @@ void wxMenuBar::Init() { m_eventHandler = this; m_hMenu = 0; +#ifdef __WXWINCE__ + m_toolBar = NULL; +#endif } wxMenuBar::wxMenuBar() @@ -557,6 +613,20 @@ wxMenuBar::wxMenuBar(int count, wxMenu *menus[], const wxString titles[]) wxMenuBar::~wxMenuBar() { + // In Windows CE, the menubar is always associated + // with a toolbar, which destroys the menu implicitly. +#ifdef __WXWINCE__ + if (GetToolBar()) + GetToolBar()->SetMenuBar(NULL); +#else + // we should free Windows resources only if Windows doesn't do it for us + // which happens if we're attached to a frame + if (m_hMenu && !IsAttached()) + { + ::DestroyMenu((HMENU)m_hMenu); + m_hMenu = (WXHMENU)NULL; + } +#endif } // --------------------------------------------------------------------------- @@ -567,11 +637,53 @@ void wxMenuBar::Refresh() { wxCHECK_RET( IsAttached(), wxT("can't refresh unattached menubar") ); +#ifdef __WXWINCE__ + if (GetToolBar()) + { + CommandBar_DrawMenuBar((HWND) GetToolBar()->GetHWND(), 0); + } +#else DrawMenuBar(GetHwndOf(GetFrame())); +#endif } WXHMENU wxMenuBar::Create() { +#ifdef __WXWINCE__ + if ( m_hMenu != 0 ) + return m_hMenu; + + if (!GetToolBar()) + return 0; + + HWND hCommandBar = (HWND) GetToolBar()->GetHWND(); + HMENU hMenu = (HMENU)::SendMessage(hCommandBar, SHCMBM_GETMENU, (WPARAM)0, (LPARAM)0); + if (hMenu) + { + TBBUTTON tbButton; + memset(&tbButton, 0, sizeof(TBBUTTON)); + tbButton.iBitmap = I_IMAGENONE; + tbButton.fsState = TBSTATE_ENABLED; + tbButton.fsStyle = TBSTYLE_DROPDOWN | TBSTYLE_NO_DROPDOWN_ARROW | TBSTYLE_AUTOSIZE; + + size_t i; + for (i = 0; i < GetMenuCount(); i++) + { + HMENU hPopupMenu = (HMENU) GetMenu(i)->GetHMenu() ; + tbButton.dwData = (DWORD)hPopupMenu; + wxString label = wxStripMenuCodes(GetLabelTop(i)); + tbButton.iString = (int) label.c_str(); + + tbButton.idCommand = NewControlId(); + if (!::SendMessage(hCommandBar, TB_INSERTBUTTON, i, (LPARAM)&tbButton)) + { + wxLogLastError(wxT("TB_INSERTBUTTON")); + } + } + } + m_hMenu = (WXHMENU) hMenu; + return m_hMenu; +#else if ( m_hMenu != 0 ) return m_hMenu; @@ -583,11 +695,12 @@ WXHMENU wxMenuBar::Create() } else { - size_t count = GetMenuCount(); - for ( size_t i = 0; i < count; i++ ) + size_t count = GetMenuCount(), i; + wxMenuList::iterator it; + for ( i = 0, it = m_menus.begin(); i < count; i++, it++ ) { if ( !::AppendMenu((HMENU)m_hMenu, MF_POPUP | MF_STRING, - (UINT)m_menus[i]->GetHMenu(), + (UINT)(*it)->GetHMenu(), m_titles[i]) ) { wxLogLastError(wxT("AppendMenu")); @@ -596,6 +709,7 @@ WXHMENU wxMenuBar::Create() } return m_hMenu; +#endif } // --------------------------------------------------------------------------- @@ -648,11 +762,26 @@ void wxMenuBar::SetLabelTop(size_t pos, const wxString& label) id = pos; } +#ifdef __WXWINCE__ + MENUITEMINFO info; + wxZeroMemory(info); + info.cbSize = sizeof(info); + info.fMask = MIIM_TYPE; + info.fType = MFT_STRING; + info.cch = label.Length(); + info.dwTypeData = (LPTSTR) label.c_str(); + if ( !SetMenuItemInfo(GetHmenu(), id, TRUE, & info) ) + { + wxLogLastError(wxT("SetMenuItemInfo")); + } + +#else if ( ::ModifyMenu(GetHmenu(), pos, MF_BYPOSITION | MF_STRING | flagsOld, - id, label) == (int)0xFFFFFFFF ) + id, label) == (int)0xFFFFFFFF ) { wxLogLastError(wxT("ModifyMenu")); } +#endif Refresh(); } @@ -715,13 +844,34 @@ bool wxMenuBar::Insert(size_t pos, wxMenu *menu, const wxString& title) if ( IsAttached() ) { +#ifdef __WXWINCE__ + if (!GetToolBar()) + return FALSE; + TBBUTTON tbButton; + memset(&tbButton, 0, sizeof(TBBUTTON)); + tbButton.iBitmap = I_IMAGENONE; + tbButton.fsState = TBSTATE_ENABLED; + tbButton.fsStyle = TBSTYLE_DROPDOWN | TBSTYLE_NO_DROPDOWN_ARROW | TBSTYLE_AUTOSIZE; + + HMENU hPopupMenu = (HMENU) menu->GetHMenu() ; + tbButton.dwData = (DWORD)hPopupMenu; + wxString label = wxStripMenuCodes(title); + tbButton.iString = (int) label.c_str(); + + tbButton.idCommand = NewControlId(); + if (!::SendMessage((HWND) GetToolBar()->GetHWND(), TB_INSERTBUTTON, pos, (LPARAM)&tbButton)) + { + wxLogLastError(wxT("TB_INSERTBUTTON")); + return FALSE; + } +#else if ( !::InsertMenu(GetHmenu(), pos, MF_BYPOSITION | MF_POPUP | MF_STRING, (UINT)GetHmenuOf(menu), title) ) { wxLogLastError(wxT("InsertMenu")); } - +#endif #if wxUSE_ACCEL if ( menu->HasAccels() ) { @@ -748,16 +898,39 @@ bool wxMenuBar::Append(wxMenu *menu, const wxString& title) if ( IsAttached() ) { +#ifdef __WXWINCE__ + if (!GetToolBar()) + return FALSE; + TBBUTTON tbButton; + memset(&tbButton, 0, sizeof(TBBUTTON)); + tbButton.iBitmap = I_IMAGENONE; + tbButton.fsState = TBSTATE_ENABLED; + tbButton.fsStyle = TBSTYLE_DROPDOWN | TBSTYLE_NO_DROPDOWN_ARROW | TBSTYLE_AUTOSIZE; + + size_t pos = GetMenuCount(); + HMENU hPopupMenu = (HMENU) menu->GetHMenu() ; + tbButton.dwData = (DWORD)hPopupMenu; + wxString label = wxStripMenuCodes(title); + tbButton.iString = (int) label.c_str(); + + tbButton.idCommand = NewControlId(); + if (!::SendMessage((HWND) GetToolBar()->GetHWND(), TB_INSERTBUTTON, pos, (LPARAM)&tbButton)) + { + wxLogLastError(wxT("TB_INSERTBUTTON")); + return FALSE; + } +#else if ( !::AppendMenu(GetHmenu(), MF_POPUP | MF_STRING, (UINT)submenu, title) ) { wxLogLastError(wxT("AppendMenu")); } +#endif #if wxUSE_ACCEL if ( menu->HasAccels() ) { - // need to rebuild accell table + // need to rebuild accelerator table RebuildAccelTable(); } #endif // wxUSE_ACCEL @@ -776,11 +949,20 @@ wxMenu *wxMenuBar::Remove(size_t pos) if ( IsAttached() ) { +#ifdef __WXWINCE__ + if (GetToolBar()) + { + if (!::SendMessage((HWND) GetToolBar()->GetHWND(), TB_DELETEBUTTON, (UINT) pos, (LPARAM) 0)) + { + wxLogLastError(wxT("TB_DELETEBUTTON")); + } + } +#else if ( !::RemoveMenu(GetHmenu(), (UINT)pos, MF_BYPOSITION) ) { wxLogLastError(wxT("RemoveMenu")); } - +#endif #if wxUSE_ACCEL if ( menu->HasAccels() ) { @@ -792,7 +974,7 @@ wxMenu *wxMenuBar::Remove(size_t pos) Refresh(); } - m_titles.Remove(pos); + m_titles.RemoveAt(pos); return menu; } @@ -804,9 +986,10 @@ void wxMenuBar::RebuildAccelTable() // merge the accelerators of all menus into one accel table size_t nAccelCount = 0; size_t i, count = GetMenuCount(); - for ( i = 0; i < count; i++ ) + wxMenuList::iterator it; + for ( i = 0, it = m_menus.begin(); i < count; i++, it++ ) { - nAccelCount += m_menus[i]->GetAccelCount(); + nAccelCount += (*it)->GetAccelCount(); } if ( nAccelCount ) @@ -814,9 +997,9 @@ void wxMenuBar::RebuildAccelTable() wxAcceleratorEntry *accelEntries = new wxAcceleratorEntry[nAccelCount]; nAccelCount = 0; - for ( i = 0; i < count; i++ ) + for ( i = 0, it = m_menus.begin(); i < count; i++, it++ ) { - nAccelCount += m_menus[i]->CopyAccels(&accelEntries[nAccelCount]); + nAccelCount += (*it)->CopyAccels(&accelEntries[nAccelCount]); } m_accelTable = wxAcceleratorTable(nAccelCount, accelEntries); @@ -838,8 +1021,6 @@ void wxMenuBar::Attach(wxFrame *frame) void wxMenuBar::Detach() { - m_hMenu = (WXHMENU)NULL; - wxMenuBarBase::Detach(); }