]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/menu.cpp
Support encodings in wxGTK_CONV_BACK() in the same way as we do it in
[wxWidgets.git] / src / msw / menu.cpp
index 03c844447cef3c5b371f21f1c9f74f324be238ff..0c2a54e3a908758ce97ab111bd814e973c5cabd3 100644 (file)
@@ -29,6 +29,7 @@
 #include "wx/menu.h"
 
 #ifndef WX_PRECOMP
+    #include "wx/msw/wrapcctl.h" // include <commctrl.h> "properly"
     #include "wx/frame.h"
     #include "wx/utils.h"
     #include "wx/intl.h"
@@ -41,9 +42,6 @@
 
 #include "wx/msw/private.h"
 
-// include <commctrl.h> "properly"
-#include "wx/msw/wrapcctl.h"
-
 #ifdef __WXWINCE__
 #include <windows.h>
 #include <windowsx.h>
@@ -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<MENUITEMINFO> 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));