Re: CMenu + COwnerDraw is it possible?
"Konstantin Mironovich" <[email protected]> Tue, 25 Mar 2014 09:21:48 +0400
| Newsgroups | gmane.comp.windows.wtl |
|---|---|
| Organization | ixbt.com |
| Message-ID | <23760D6F7851445388C8994C845B806E@KLM64> |
Hi Igor,
thanks for the reply.
actually I've seen your article some time ago. as well as many other works
at codeproject, codeguru, etc..
your approach uses member object m_menuEdit with predefined menu.
I've found a bit simpler solution for my needs:
LRESULT OnTreeItemRClick(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/)
{
POINT pt; ::GetCursorPos(&pt);
CTitleMenu menu;
menu.CreatePopupMenu();
menu.AddMenuTitle(_T("Select new action"));
menu.AppendMenu(MFT_STRING, ID_APP_ABOUT, _T("Action about"));
menu.AppendMenu(MFT_STRING, ID_FILE_OPEN, _T("Action open"));
menu.AppendMenu(MFT_STRING, ID_APP_EXIT, _T("Action exit"));
menu.TrackPopupMenu(TPM_CENTERALIGN, pt.x, pt.y, GetParent());
return 0;
}
// implementation
class CTitleMenu
: public ATL::CWindowImpl<CTitleMenu>
, public COwnerDraw<CTitleMenu>
, public CMenu
{
protected:
typedef ATL::CWindowImpl<CTitleMenu> baseClass;
static const int GAP = 8;
public:
~CTitleMenu() { baseClass::UnsubclassWindow(); }
// overridden to provide proper initialization
BOOL TrackPopupMenu(UINT nFlags, int x, int y, HWND hWnd, LPCRECT lpRect =
NULL)
{
baseClass::SubclassWindow(hWnd);
m_font = WTL::AtlCreateBoldFont((HFONT)::SendMessage(hWnd, WM_GETFONT,
0, 0));
return CMenu::TrackPopupMenu(nFlags, x, y, hWnd, lpRect);
}
void AddMenuTitle(LPCTSTR title)
{
m_title = title;
InsertMenu(0, MF_BYPOSITION | MFT_SEPARATOR);
InsertMenu(0, MF_BYPOSITION | MFT_OWNERDRAW | MFT_STRING | MF_DISABLED);
}
BEGIN_MSG_MAP(CTitleMenu)
CHAIN_MSG_MAP(COwnerDraw<CTitleMenu>)
DEFAULT_REFLECTION_HANDLER()
END_MSG_MAP()
void DrawItem(LPDRAWITEMSTRUCT pdis)
{
if (m_font)
{
CDCHandle dc(pdis->hDC);
dc.FillRect(&pdis->rcItem, COLOR_ACTIVECAPTION);
// save
int mode = dc.SetBkMode(TRANSPARENT);
COLORREF clr = dc.SetTextColor(::GetSysColor(COLOR_MENUTEXT));
HFONT font = dc.SelectFont(m_font);
pdis->rcItem.left += ::GetSystemMetrics(SM_CXMENUCHECK) + GAP;;
// draw the text left aligned and vertically centered
dc.DrawText(m_title, -1, &pdis->rcItem, DT_SINGLELINE | DT_VCENTER);
dc.SelectFont(font);
// restore
dc.SetBkMode(mode);
dc.SetTextColor(clr);
}
}
void MeasureItem(LPMEASUREITEMSTRUCT pdis)
{
if (m_font && (pdis->CtlType == ODT_MENU))
{
CClientDC dc(NULL);
HFONT font = dc.SelectFont(m_font);
SIZE size;
dc.GetTextExtent(m_title, -1, &size);
dc.SelectFont(font);
size.cx += ::GetSystemMetrics(SM_CXMENUCHECK) + GAP;;
pdis->itemWidth = size.cx;
pdis->itemHeight = ::GetSystemMetrics(SM_CYMENU);
}
}
protected:
CString m_title;
WTL::CFont m_font; // bold font
};
-km
----- Original Message -----
From: Igor Vigdorchik
To: [email protected]
Sent: Tuesday, March 25, 2014 4:23 AM
Subject: Re: [wtl] CMenu + COwnerDraw is it possible?
Konstantin,
Please take a look at this article
http://www.codeproject.com/Articles/13406/Owner-drawn-context-menu-in-WTL
Regards,
Igor
------------------------------------------------------------------------------
From: Konstantin Mironovich <[email protected]>
To: [email protected]
Sent: Monday, March 24, 2014 8:33 AM
Subject: [wtl] CMenu + COwnerDraw is it possible?
Hi folks,
I need to create an owner drawn context menu object on stack and do not
have
a solid idea how to redirect WM_OWNERDRAW(...) messages from parent window
to the object.
maybe to create some kind of proxy window and subclass it?
this proxy could contain CMenu-based object and do all the work needed..
any ideas?
thanks
-km