X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/90527a50d74bed6ed6b4d163e8170ae8c3f5d869..1a1f3e4b53fd5d1515b16905edf4250dfb2fc676:/src/msw/menu.cpp diff --git a/src/msw/menu.cpp b/src/msw/menu.cpp index 03c844447c..ad2f91eac1 100644 --- a/src/msw/menu.cpp +++ b/src/msw/menu.cpp @@ -29,6 +29,7 @@ #include "wx/menu.h" #ifndef WX_PRECOMP + #include "wx/msw/wrapcctl.h" // include "properly" #include "wx/frame.h" #include "wx/utils.h" #include "wx/intl.h" @@ -41,9 +42,6 @@ #include "wx/msw/private.h" -// include "properly" -#include "wx/msw/wrapcctl.h" - #ifdef __WXWINCE__ #include #include @@ -61,7 +59,25 @@ // other standard headers #include -#if wxUSE_OWNER_DRAWN && defined(MIIM_BITMAP) +//VC6 needs these defining, though they are in winuser.h +#ifndef MIIM_BITMAP +#define MIIM_STRING 0x00000040 +#define MIIM_BITMAP 0x00000080 +#define MIIM_FTYPE 0x00000100 +#define HBMMENU_CALLBACK ((HBITMAP) -1) +typedef struct tagMENUINFO +{ + DWORD cbSize; + DWORD fMask; + DWORD dwStyle; + UINT cyMax; + HBRUSH hbrBack; + DWORD dwContextHelpID; + DWORD dwMenuData; +} MENUINFO, FAR *LPMENUINFO; +#endif + +#if wxUSE_OWNER_DRAWN #include "wx/dynlib.h" #endif @@ -403,30 +419,56 @@ bool wxMenu::DoInsertOrAppend(wxMenuItem *pItem, size_t pos) BOOL ok = false; +#if wxUSE_OWNER_DRAWN + // Currently, mixing owner-drawn and non-owner-drawn items results in + // inconsistent margins, so we force this to be owner-drawn if any other + // items already are. Later we might want to use a boolean in the wxMenu + // to avoid search. Also we might make this fix unnecessary by getting the correct + // margin using NONCLIENTMETRICS. + if ( !pItem->IsOwnerDrawn() && !pItem->IsSeparator() ) + { + // Check if any other items are ownerdrawn, and make ownerdrawn if so + wxMenuItemList::compatibility_iterator node = GetMenuItems().GetFirst(); + while (node) + { + if (node->GetData()->IsOwnerDrawn()) + { + pItem->SetOwnerDrawn(true); + break; + } + node = node->GetNext(); + } + } +#endif + // check if we have something more than a simple text item #if wxUSE_OWNER_DRAWN if ( pItem->IsOwnerDrawn() ) { - // is the item owner-drawn just because of the bitmap? - if ( pItem->GetBitmap().Ok() && + // is the item owner-drawn just because of the [checked] bitmap? + if ( (pItem->GetBitmap(false).Ok() || pItem->GetBitmap(true).Ok()) && !pItem->GetTextColour().Ok() && !pItem->GetBackgroundColour().Ok() && - !pItem->GetFont().Ok() && - !pItem->GetBitmap(true).Ok() ) + !pItem->GetFont().Ok() ) { // try to use InsertMenuItem() as it's guaranteed to look correct // while our owner-drawn code is not - - // first compile-time check -#ifdef MIIM_BITMAP +#ifndef __DMC__ + // DMC at march 2007 doesn't have HBITMAP hbmpItem tagMENUITEMINFOA /W + // MIIM_BITMAP only works under WinME/2000+ WinStruct mii; - - // now run-time one: MIIM_BITMAP only works under WinME/2000+ if ( wxGetWinVersion() >= wxWinVersion_98 ) { mii.fMask = MIIM_STRING | MIIM_DATA | MIIM_BITMAP; + if ( pItem->IsCheckable() ) + { + // need to set checked/unchecked bitmaps as otherwise our + // MSWOnDrawItem() item is not called + mii.fMask |= MIIM_CHECKMARKS; + } + mii.cch = itemText.length(); - mii.dwTypeData = wx_const_cast(wxChar *, itemText.c_str()); + mii.dwTypeData = wx_const_cast(wxChar *, itemText.wx_str()); if (flags & MF_POPUP) { @@ -447,6 +489,11 @@ bool wxMenu::DoInsertOrAppend(wxMenuItem *pItem, size_t pos) // // so instead draw it ourselves in MSWOnDrawItem() mii.dwItemData = wx_reinterpret_cast(ULONG_PTR, pItem); + if ( pItem->IsCheckable() ) + { + mii.hbmpChecked = + mii.hbmpUnchecked = HBMMENU_CALLBACK; + } mii.hbmpItem = HBMMENU_CALLBACK; ok = ::InsertMenuItem(GetHmenu(), pos, TRUE /* by pos */, &mii); @@ -481,7 +528,7 @@ bool wxMenu::DoInsertOrAppend(wxMenuItem *pItem, size_t pos) pItem->ResetOwnerDrawn(); } } -#endif // MIIM_BITMAP +#endif // __DMC__ } if ( !ok ) @@ -501,7 +548,7 @@ bool wxMenu::DoInsertOrAppend(wxMenuItem *pItem, size_t pos) itemText = wxMenuItem::GetLabelFromText(itemText); #endif - pData = (wxChar*)itemText.c_str(); + pData = (wxChar*)itemText.wx_str(); } // item might have already been inserted by InsertMenuItem() above @@ -684,7 +731,7 @@ void wxMenu::SetTitle(const wxString& label) if ( !label.empty() ) { if ( !::InsertMenu(hMenu, 0u, MF_BYPOSITION | MF_STRING, - (unsigned)idMenuTitle, m_title) || + (unsigned)idMenuTitle, m_title.wx_str()) || !::InsertMenu(hMenu, 1u, MF_BYPOSITION, (unsigned)-1, NULL) ) { wxLogLastError(wxT("InsertMenu")); @@ -720,7 +767,7 @@ void wxMenu::SetTitle(const wxString& label) #else if ( !ModifyMenu(hMenu, 0u, MF_BYPOSITION | MF_STRING, - (unsigned)idMenuTitle, m_title) ) + (unsigned)idMenuTitle, m_title.wx_str()) ) { wxLogLastError(wxT("ModifyMenu")); } @@ -746,10 +793,15 @@ bool wxMenu::MSWCommand(WXUINT WXUNUSED(param), WXWORD id) // ignore commands from the menu title if ( id != (WXWORD)idMenuTitle ) { - // get the checked status of the command: notice that menuState is the - // old state of the menu, so the test for MF_CHECKED must be inverted + // update the check item when it's clicked + wxMenuItem * const item = FindItem(id); + if ( item && item->IsCheckable() ) + item->Toggle(); + + // get the status of the menu item: note that it has been just changed + // by Toggle() above so here we already get the new state of the item UINT menuState = ::GetMenuState(GetHmenu(), id, MF_BYCOMMAND); - SendEvent(id, !(menuState & MF_CHECKED)); + SendEvent(id, menuState & MF_CHECKED); } return true; @@ -927,7 +979,7 @@ WXHMENU wxMenuBar::Create() { if ( !::AppendMenu((HMENU)m_hMenu, MF_POPUP | MF_STRING, (UINT)(*it)->GetHMenu(), - m_titles[i]) ) + m_titles[i].wx_str()) ) { wxLogLastError(wxT("AppendMenu")); } @@ -1033,7 +1085,7 @@ void wxMenuBar::SetLabelTop(size_t pos, const wxString& label) #else if ( ::ModifyMenu(GetHmenu(), mswpos, MF_BYPOSITION | MF_STRING | flagsOld, - id, label) == (int)0xFFFFFFFF ) + id, label.wx_str()) == (int)0xFFFFFFFF ) { wxLogLastError(wxT("ModifyMenu")); } @@ -1078,7 +1130,7 @@ wxMenu *wxMenuBar::Replace(size_t pos, wxMenu *menu, const wxString& title) if ( !::InsertMenu(GetHmenu(), (UINT)mswpos, MF_BYPOSITION | MF_POPUP | MF_STRING, - (UINT)GetHmenuOf(menu), title) ) + (UINT)GetHmenuOf(menu), title.wx_str()) ) { wxLogLastError(wxT("InsertMenu")); } @@ -1145,7 +1197,7 @@ bool wxMenuBar::Insert(size_t pos, wxMenu *menu, const wxString& title) #else if ( !::InsertMenu(GetHmenu(), mswpos, MF_BYPOSITION | MF_POPUP | MF_STRING, - (UINT)GetHmenuOf(menu), title) ) + (UINT)GetHmenuOf(menu), title.wx_str()) ) { wxLogLastError(wxT("InsertMenu")); } @@ -1204,7 +1256,7 @@ bool wxMenuBar::Append(wxMenu *menu, const wxString& title) } #else if ( !::AppendMenu(GetHmenu(), MF_POPUP | MF_STRING, - (UINT)submenu, title) ) + (UINT)submenu, title.wx_str()) ) { wxLogLastError(wxT("AppendMenu")); }