X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/90527a50d74bed6ed6b4d163e8170ae8c3f5d869..30083ad8e7c0eb9ea3dcf4f2588149eeb7fe3e32:/src/msw/menu.cpp diff --git a/src/msw/menu.cpp b/src/msw/menu.cpp index 03c844447c..0c2a54e3a9 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 @@ -403,28 +401,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 +#if defined(MIIM_BITMAP) && (_WIN32_WINNT >= 0x0500) 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()); @@ -447,6 +473,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); @@ -746,7 +777,12 @@ 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 + // update the check item when it's clicked + wxMenuItem * const item = FindItem(id); + if ( item && item->IsCheckable() ) + item->Toggle(); + + // get the checked status of the menu item: note that menuState is the // old state of the menu, so the test for MF_CHECKED must be inverted UINT menuState = ::GetMenuState(GetHmenu(), id, MF_BYCOMMAND); SendEvent(id, !(menuState & MF_CHECKED));