Refactor wxMSW: move some code from wxMenu to wxMenuItem.
This will allow reusing it for other wxMenuItem bitmap-related operations. See #9388. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@76190 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -118,6 +118,12 @@ private:
|
|||||||
// helper function for draw std menu check mark
|
// helper function for draw std menu check mark
|
||||||
void DrawStdCheckMark(WXHDC hdc, const tagRECT* rc, wxODStatus stat);
|
void DrawStdCheckMark(WXHDC hdc, const tagRECT* rc, wxODStatus stat);
|
||||||
|
|
||||||
|
// helper function to determine if the item must be owner-drawn
|
||||||
|
bool MustUseOwnerDrawn();
|
||||||
|
|
||||||
|
// helper function to get a handle of bitmap associated with item
|
||||||
|
WXHBITMAP GetHBitmapForMenu(bool checked = true);
|
||||||
|
|
||||||
#else // !wxUSE_OWNER_DRAWN
|
#else // !wxUSE_OWNER_DRAWN
|
||||||
// Provide stubs for the public functions above to ensure that the code
|
// Provide stubs for the public functions above to ensure that the code
|
||||||
// still compiles without wxUSE_OWNER_DRAWN -- it makes sense to just drop
|
// still compiles without wxUSE_OWNER_DRAWN -- it makes sense to just drop
|
||||||
@@ -141,6 +147,9 @@ private:
|
|||||||
m_bmpDisabled;
|
m_bmpDisabled;
|
||||||
#endif // wxUSE_OWNER_DRAWN
|
#endif // wxUSE_OWNER_DRAWN
|
||||||
|
|
||||||
|
// Give wxMenu access to our MustUseOwnerDrawn() and GetHBitmapForMenu().
|
||||||
|
friend class wxMenu;
|
||||||
|
|
||||||
DECLARE_DYNAMIC_CLASS_NO_COPY(wxMenuItem)
|
DECLARE_DYNAMIC_CLASS_NO_COPY(wxMenuItem)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -236,12 +236,6 @@ UINT GetMenuState(HMENU hMenu, UINT id, UINT flags)
|
|||||||
}
|
}
|
||||||
#endif // __WXWINCE__
|
#endif // __WXWINCE__
|
||||||
|
|
||||||
inline bool IsGreaterThanStdSize(const wxBitmap& bmp)
|
|
||||||
{
|
|
||||||
return bmp.GetWidth() > ::GetSystemMetrics(SM_CXMENUCHECK) ||
|
|
||||||
bmp.GetHeight() > ::GetSystemMetrics(SM_CYMENUCHECK);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@@ -412,49 +406,6 @@ void wxMenu::UpdateAccel(wxMenuItem *item)
|
|||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
// helper of DoInsertOrAppend(): returns the HBITMAP to use in MENUITEMINFO
|
|
||||||
HBITMAP GetHBitmapForMenu(wxMenuItem *pItem, bool checked = true)
|
|
||||||
{
|
|
||||||
// Under versions of Windows older than Vista we can't pass HBITMAP
|
|
||||||
// directly as hbmpItem for 2 reasons:
|
|
||||||
// 1. We can't draw it with transparency then (this is not
|
|
||||||
// very important now but would be with themed menu bg)
|
|
||||||
// 2. Worse, Windows inverts the bitmap for the selected
|
|
||||||
// item and this looks downright ugly
|
|
||||||
//
|
|
||||||
// So we prefer to instead draw it ourselves in MSWOnDrawItem().by using
|
|
||||||
// HBMMENU_CALLBACK when inserting it
|
|
||||||
//
|
|
||||||
// However under Vista using HBMMENU_CALLBACK causes the entire menu to be
|
|
||||||
// drawn using the classic theme instead of the current one and it does
|
|
||||||
// handle transparency just fine so do use the real bitmap there
|
|
||||||
#if wxUSE_IMAGE
|
|
||||||
if ( wxGetWinVersion() >= wxWinVersion_Vista )
|
|
||||||
{
|
|
||||||
#if wxUSE_OWNER_DRAWN
|
|
||||||
wxBitmap bmp = pItem->GetBitmap(checked);
|
|
||||||
if ( bmp.IsOk() )
|
|
||||||
{
|
|
||||||
// we must use PARGB DIB for the menu bitmaps so ensure that we do
|
|
||||||
wxImage img(bmp.ConvertToImage());
|
|
||||||
if ( !img.HasAlpha() )
|
|
||||||
{
|
|
||||||
img.InitAlpha();
|
|
||||||
pItem->SetBitmap(img, checked);
|
|
||||||
}
|
|
||||||
|
|
||||||
return GetHbitmapOf(pItem->GetBitmap(checked));
|
|
||||||
}
|
|
||||||
#endif // wxUSE_OWNER_DRAWN
|
|
||||||
//else: bitmap is not set
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
#endif // wxUSE_IMAGE
|
|
||||||
|
|
||||||
return HBMMENU_CALLBACK;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
bool wxMenu::MSWGetRadioGroupRange(int pos, int *start, int *end) const
|
bool wxMenu::MSWGetRadioGroupRange(int pos, int *start, int *end) const
|
||||||
@@ -558,36 +509,9 @@ bool wxMenu::DoInsertOrAppend(wxMenuItem *pItem, size_t pos)
|
|||||||
|
|
||||||
if ( !m_ownerDrawn && !pItem->IsSeparator() )
|
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();
|
|
||||||
|
|
||||||
// Windows XP or earlier don't display menu bitmaps bigger than
|
|
||||||
// standard size correctly (they're truncated), so we must use
|
|
||||||
// owner-drawn items to show them correctly there. OTOH Win7
|
|
||||||
// doesn't seem to have any problems with even very large bitmaps
|
|
||||||
// so don't use owner-drawn items unnecessarily there (Vista wasn't
|
|
||||||
// actually tested but I assume it works as 7 rather than as XP).
|
|
||||||
if ( !mustUseOwnerDrawn && winver < wxWinVersion_Vista )
|
|
||||||
{
|
|
||||||
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
|
// use InsertMenuItem() if possible as it's guaranteed to look
|
||||||
// correct while our owner-drawn code is not
|
// correct while our owner-drawn code is not
|
||||||
if ( !mustUseOwnerDrawn )
|
if ( !pItem->MustUseOwnerDrawn() )
|
||||||
{
|
{
|
||||||
WinStruct<MENUITEMINFO> mii;
|
WinStruct<MENUITEMINFO> mii;
|
||||||
mii.fMask = MIIM_STRING | MIIM_DATA;
|
mii.fMask = MIIM_STRING | MIIM_DATA;
|
||||||
@@ -597,13 +521,13 @@ bool wxMenu::DoInsertOrAppend(wxMenuItem *pItem, size_t pos)
|
|||||||
if ( pItem->IsCheckable() )
|
if ( pItem->IsCheckable() )
|
||||||
{
|
{
|
||||||
mii.fMask |= MIIM_CHECKMARKS;
|
mii.fMask |= MIIM_CHECKMARKS;
|
||||||
mii.hbmpChecked = GetHBitmapForMenu(pItem, true);
|
mii.hbmpChecked = pItem->GetHBitmapForMenu(true);
|
||||||
mii.hbmpUnchecked = GetHBitmapForMenu(pItem, false);
|
mii.hbmpUnchecked = pItem->GetHBitmapForMenu(false);
|
||||||
}
|
}
|
||||||
else if ( pItem->GetBitmap().IsOk() )
|
else if ( pItem->GetBitmap().IsOk() )
|
||||||
{
|
{
|
||||||
mii.fMask |= MIIM_BITMAP;
|
mii.fMask |= MIIM_BITMAP;
|
||||||
mii.hbmpItem = GetHBitmapForMenu(pItem);
|
mii.hbmpItem = pItem->GetHBitmapForMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
mii.cch = itemText.length();
|
mii.cch = itemText.length();
|
||||||
|
@@ -134,6 +134,12 @@ private:
|
|||||||
int m_modeOld;
|
int m_modeOld;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline bool IsGreaterThanStdSize(const wxBitmap& bmp)
|
||||||
|
{
|
||||||
|
return bmp.GetWidth() > ::GetSystemMetrics(SM_CXMENUCHECK) ||
|
||||||
|
bmp.GetHeight() > ::GetSystemMetrics(SM_CYMENUCHECK);
|
||||||
|
}
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@@ -1249,6 +1255,82 @@ void wxMenuItem::GetColourToUse(wxODStatus stat, wxColour& colText, wxColour& co
|
|||||||
wxOwnerDrawn::GetColourToUse(stat, colText, colBack);
|
wxOwnerDrawn::GetColourToUse(stat, colText, colBack);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool wxMenuItem::MustUseOwnerDrawn()
|
||||||
|
{
|
||||||
|
// 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 ||
|
||||||
|
GetTextColour().IsOk() ||
|
||||||
|
GetBackgroundColour().IsOk() ||
|
||||||
|
GetFont().IsOk();
|
||||||
|
|
||||||
|
// Windows XP or earlier don't display menu bitmaps bigger than
|
||||||
|
// standard size correctly (they're truncated), so we must use
|
||||||
|
// owner-drawn items to show them correctly there. OTOH Win7
|
||||||
|
// doesn't seem to have any problems with even very large bitmaps
|
||||||
|
// so don't use owner-drawn items unnecessarily there (Vista wasn't
|
||||||
|
// actually tested but I assume it works as 7 rather than as XP).
|
||||||
|
if ( !mustUseOwnerDrawn && winver < wxWinVersion_Vista )
|
||||||
|
{
|
||||||
|
const wxBitmap& bmpUnchecked = GetBitmap(false),
|
||||||
|
bmpChecked = GetBitmap(true);
|
||||||
|
|
||||||
|
if ( (bmpUnchecked.IsOk() && IsGreaterThanStdSize(bmpUnchecked)) ||
|
||||||
|
(bmpChecked.IsOk() && IsGreaterThanStdSize(bmpChecked)) )
|
||||||
|
{
|
||||||
|
mustUseOwnerDrawn = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mustUseOwnerDrawn;
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns the HBITMAP to use in MENUITEMINFO
|
||||||
|
HBITMAP wxMenuItem::GetHBitmapForMenu(bool checked)
|
||||||
|
{
|
||||||
|
// Under versions of Windows older than Vista we can't pass HBITMAP
|
||||||
|
// directly as hbmpItem for 2 reasons:
|
||||||
|
// 1. We can't draw it with transparency then (this is not
|
||||||
|
// very important now but would be with themed menu bg)
|
||||||
|
// 2. Worse, Windows inverts the bitmap for the selected
|
||||||
|
// item and this looks downright ugly
|
||||||
|
//
|
||||||
|
// So we prefer to instead draw it ourselves in MSWOnDrawItem().by using
|
||||||
|
// HBMMENU_CALLBACK when inserting it
|
||||||
|
//
|
||||||
|
// However under Vista using HBMMENU_CALLBACK causes the entire menu to be
|
||||||
|
// drawn using the classic theme instead of the current one and it does
|
||||||
|
// handle transparency just fine so do use the real bitmap there
|
||||||
|
#if wxUSE_IMAGE
|
||||||
|
if ( wxGetWinVersion() >= wxWinVersion_Vista )
|
||||||
|
{
|
||||||
|
#if wxUSE_OWNER_DRAWN
|
||||||
|
wxBitmap bmp = GetBitmap(checked);
|
||||||
|
if ( bmp.IsOk() )
|
||||||
|
{
|
||||||
|
// we must use PARGB DIB for the menu bitmaps so ensure that we do
|
||||||
|
wxImage img(bmp.ConvertToImage());
|
||||||
|
if ( !img.HasAlpha() )
|
||||||
|
{
|
||||||
|
img.InitAlpha();
|
||||||
|
SetBitmap(img, checked);
|
||||||
|
}
|
||||||
|
|
||||||
|
return GetHbitmapOf(GetBitmap(checked));
|
||||||
|
}
|
||||||
|
#endif // wxUSE_OWNER_DRAWN
|
||||||
|
//else: bitmap is not set
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif // wxUSE_IMAGE
|
||||||
|
|
||||||
|
return HBMMENU_CALLBACK;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // wxUSE_OWNER_DRAWN
|
#endif // wxUSE_OWNER_DRAWN
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
Reference in New Issue
Block a user