+
+ // adjust position to account for the title of a popup menu, if any
+ if ( !GetMenuBar() && !m_title.empty() )
+ pos += 2; // for the title itself and its separator
+
+ BOOL ok = false;
+
+#if wxUSE_OWNER_DRAWN
+ // Under older systems mixing owner-drawn and non-owner-drawn items results
+ // in inconsistent margins, so we force this one to be owner-drawn if any
+ // other items already are.
+ if ( m_ownerDrawn )
+ pItem->SetOwnerDrawn(true);
+#endif // wxUSE_OWNER_DRAWN
+
+ // check if we have something more than a simple text item
+#if wxUSE_OWNER_DRAWN
+ if ( pItem->IsOwnerDrawn() )
+ {
+#ifndef __DMC__
+
+ if ( !m_ownerDrawn && !pItem->IsSeparator() )
+ {
+ // MIIM_BITMAP only works under WinME/2000+ so we always use owner
+ // drawn item under the previous versions and we also have to use
+ // them in any case if the item has custom colours or font
+ static const wxWinVersion winver = wxGetWinVersion();
+ bool mustUseOwnerDrawn = winver < wxWinVersion_98 ||
+ pItem->GetTextColour().IsOk() ||
+ pItem->GetBackgroundColour().IsOk() ||
+ pItem->GetFont().IsOk();
+
+ if ( !mustUseOwnerDrawn )
+ {
+ const wxBitmap& bmpUnchecked = pItem->GetBitmap(false),
+ bmpChecked = pItem->GetBitmap(true);
+
+ if ( (bmpUnchecked.IsOk() && IsGreaterThanStdSize(bmpUnchecked)) ||
+ (bmpChecked.IsOk() && IsGreaterThanStdSize(bmpChecked)) )
+ {
+ mustUseOwnerDrawn = true;
+ }
+ }
+
+ // use InsertMenuItem() if possible as it's guaranteed to look
+ // correct while our owner-drawn code is not
+ if ( !mustUseOwnerDrawn )
+ {
+ WinStruct<MENUITEMINFO> mii;
+ mii.fMask = MIIM_STRING | MIIM_DATA;
+
+ // don't set hbmpItem for the checkable items as it would
+ // be used for both checked and unchecked state
+ if ( pItem->IsCheckable() )
+ {
+ mii.fMask |= MIIM_CHECKMARKS;
+ mii.hbmpChecked = GetHBitmapForMenu(pItem, true);
+ mii.hbmpUnchecked = GetHBitmapForMenu(pItem, false);
+ }
+ else if ( pItem->GetBitmap().IsOk() )
+ {
+ mii.fMask |= MIIM_BITMAP;
+ mii.hbmpItem = GetHBitmapForMenu(pItem);
+ }
+
+ mii.cch = itemText.length();
+ mii.dwTypeData = wxMSW_CONV_LPTSTR(itemText);
+
+ if ( flags & MF_POPUP )
+ {
+ mii.fMask |= MIIM_SUBMENU;
+ mii.hSubMenu = GetHmenuOf(pItem->GetSubMenu());
+ }
+ else
+ {
+ mii.fMask |= MIIM_ID;
+ mii.wID = id;
+ }
+
+ mii.dwItemData = reinterpret_cast<ULONG_PTR>(pItem);
+
+ ok = ::InsertMenuItem(GetHmenu(), pos, TRUE /* by pos */, &mii);
+ if ( !ok )
+ {
+ wxLogLastError(wxT("InsertMenuItem()"));
+ }
+ else // InsertMenuItem() ok
+ {
+ // we need to remove the extra indent which is reserved for
+ // the checkboxes by default as it looks ugly unless check
+ // boxes are used together with bitmaps and this is not the
+ // case in wx API
+ WinStruct<MENUINFO> mi;
+
+ // don't call SetMenuInfo() directly, this would prevent
+ // the app from starting up under Windows 95/NT 4
+ typedef BOOL (WINAPI *SetMenuInfo_t)(HMENU, MENUINFO *);
+
+ wxDynamicLibrary dllUser(wxT("user32"));
+ wxDYNLIB_FUNCTION(SetMenuInfo_t, SetMenuInfo, dllUser);
+ if ( pfnSetMenuInfo )
+ {
+ mi.fMask = MIM_STYLE;
+ mi.dwStyle = MNS_CHECKORBMP;
+ if ( !(*pfnSetMenuInfo)(GetHmenu(), &mi) )
+ {
+ wxLogLastError(wxT("SetMenuInfo(MNS_NOCHECK)"));
+ }
+ }
+
+ // tell the item that it's not really owner-drawn but only
+ // needs to draw its bitmap, the rest is done by Windows
+ pItem->SetOwnerDrawn(false);
+ }
+ }
+ }
+#endif // __DMC__
+
+ if ( !ok )
+ {
+ // item draws itself, pass pointer to it in data parameter
+ flags |= MF_OWNERDRAW;
+ pData = (LPCTSTR)pItem;
+
+ bool updateAllMargins = false;
+
+ // get size of bitmap always return valid value (0 for invalid bitmap),
+ // so we don't needed check if bitmap is valid ;)
+ int uncheckedW = pItem->GetBitmap(false).GetWidth();
+ int checkedW = pItem->GetBitmap(true).GetWidth();
+
+ if ( m_maxBitmapWidth < uncheckedW )
+ {
+ m_maxBitmapWidth = uncheckedW;
+ updateAllMargins = true;
+ }
+
+ if ( m_maxBitmapWidth < checkedW )
+ {
+ m_maxBitmapWidth = checkedW;
+ updateAllMargins = true;
+ }
+
+ // make other item ownerdrawn and update margin width for equals alignment
+ if ( !m_ownerDrawn || updateAllMargins )
+ {
+ // we must use position in SetOwnerDrawnMenuItem because
+ // all separators have the same id
+ int pos = 0;
+ wxMenuItemList::compatibility_iterator node = GetMenuItems().GetFirst();
+ while (node)
+ {
+ wxMenuItem* item = node->GetData();
+
+ if ( !item->IsOwnerDrawn())
+ {
+ item->SetOwnerDrawn(true);
+ SetOwnerDrawnMenuItem(GetHmenu(), pos,
+ reinterpret_cast<ULONG_PTR>(item), TRUE);
+ }
+
+ item->SetMarginWidth(m_maxBitmapWidth);
+
+ node = node->GetNext();
+ pos++;
+ }
+
+ // set menu as ownerdrawn
+ m_ownerDrawn = true;
+
+ ResetMaxAccelWidth();
+ }
+ // only update our margin for equals alignment to other item
+ else if ( !updateAllMargins )
+ {
+ pItem->SetMarginWidth(m_maxBitmapWidth);
+ }
+ }
+ }
+ else
+#endif // wxUSE_OWNER_DRAWN
+ {
+ // item is just a normal string (passed in data parameter)
+ flags |= MF_STRING;
+
+#ifdef __WXWINCE__
+ itemText = wxMenuItem::GetLabelText(itemText);
+#endif
+
+ pData = itemText.t_str();
+ }
+
+ // item might have already been inserted by InsertMenuItem() above
+ if ( !ok )
+ {
+ if ( !::InsertMenu(GetHmenu(), pos, flags | MF_BYPOSITION, id, pData) )
+ {
+ wxLogLastError(wxT("InsertMenu[Item]()"));
+
+ return false;
+ }
+ }
+
+
+ // Check the item if it should be initially checked.
+ if ( checkInitially )
+ pItem->Check(true);
+
+ // if we just appended the title, highlight it
+ if ( id == (UINT_PTR)idMenuTitle )