I'm simply trying to add small color swatches to my context menu (displayed via the TrackPopupMenu API.) Here's a Photoshopped version of what I'm trying to achieve:
As far as I understand the default menu does not support it. Btw, the sample above (without color swatches) was generated by doing this:
MENUITEMINFO mii = {0};
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_FTYPE | MIIM_ID | MIIM_STATE | MIIM_STRING;
mii.fType = MFT_STRING;
mii.wID = ID_1_MARKER_01 + m;
mii.dwTypeData = L"Marker";
mii.cch = TSIZEOF(L"Marker");
mii.fState = m == 1 ? MFS_CHECKED : MFS_ENABLED;
if(m == 2)
mii.fState |= MFS_GRAYED;
VERIFY(::InsertMenuItem(hMenu, ID_1_BEFORE, FALSE, &mii));
So I discovered that I need to use MFT_OWNERDRAW
style to draw menu items myself, but that's where the problems begin.
I changed my code to display my menu as such:
MENUITEMINFO mii = {0};
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_FTYPE | MIIM_ID | MIIM_STATE;
mii.fType = MFT_OWNERDRAW;
mii.wID = ID_1_MARKER_01 + m;
mii.dwItemData = MARKER_ID_01 + m;
mii.fState = m == 1 ? MFS_CHECKED : MFS_ENABLED;
if(m == 2)
mii.fState |= MFS_GRAYED;
VERIFY(::InsertMenuItem(hMenu, ID_1_BEFORE, FALSE, &mii));
then I needed to override WM_MEASUREITEM
and WM_DRAWITEM
messages. But when I do it with the code that I'll show below, here's what I get:
So please bear with me. I have several questions on this topic:
1) While processing WM_MEASUREITEM
how am I supposed to know the size of text if they do not supply neither DC
nor HWND
for the menu? In other words, if I do this, the size of the menus is wrong:
#define TSIZEOF(f) ((sizeof(f) - sizeof(TCHAR)) / sizeof(TCHAR))
//hwnd = HWND supplied in WM_MEASUREITEM notification
HDC hDC = ::GetDC(hwnd);
HGDIOBJ hOldFont = ::SelectObject(hDC, ::SendMessage(hwnd, WM_GETFONT, 0, 0));
SIZE szTxt = {0};
::GetTextExtentPoint32(hDC,
L"Marker",
TSIZEOF(L"Marker"),
&szTxt);
//lpmis = MEASUREITEMSTRUCT*
lpmis->itemWidth = szTxt.cx;
lpmis->itemHeight = szTxt.cy;
::SelectObject(hDC, hOldFont);
::ReleaseDC(hwnd, hDC);
2) Then while processing WM_DRAWITEM
how do I know the offset to begin drawing text on the left? If I do this, my menus aren't offset enough to the right (as you can see from the screenshot above):
int nCheckW = ::GetSystemMetrics(SM_CXMENUCHECK);
//lpdis = DRAWITEMSTRUCT*
::ExtTextOut(lpdis->hDC,
lpdis->rcItem.left + nCheckW,
lpdis->rcItem.top,
ETO_OPAQUE,
&lpdis->rcItem,
L"Marker",
TSIZEOF(L"Marker"),
NULL);
3) And lastly how do I draw that default checkbox on the left of the menu item?
Aucun commentaire:
Enregistrer un commentaire