In vckbase see the Custom Painting menu are derived from a new class, in fact, do not need to be so troublesome, add three functions to achieve the Framework menu painting, convenient and simple, easy to maintain.
In MFC, if the menu has a Mf_ownerdraw flag, the program calls the OnDrawItem and OnMeasureItem functions to draw the menu.
Now let's do it! First in the CMainFrame response three messages, respectively:
WM_DRAWITEM:绘制菜单的样式
WM_MEASUREITEM:指定要绘制菜单的大小
WM_INITMENU:把框架菜单全部改成带MF_OWNERDRAW标志
Below I post the three function code, you do not want to change, the code of these three functions to copy your program, compile a look at your program menu is not become very beautiful:)
void Cmainframe::onmeasureitem (int nidctl, lpmeasureitemstruct lpmeasureitemstruct)
{
lpmeasureitemstruct& lpm=lpmeasureitemstruct; A few names, easy to use
if (Lpm->ctltype==odt_menu) {//Judge whether the menu is to be painted
if (lpm->itemid!=id_separator)//Set the size of the normal menu and separator bar individually
{
lpm->itemheight=20; Separator Bar Size
lpm->itemwidth=150;
}
Else
{
lpm->itemheight=1; Normal menu Size
lpm->itemwidth=150;
}
}
}
void Cmainframe::ondrawitem (int nidctl, lpdrawitemstruct lpdrawitemstruct)
{
lpdrawitemstruct& lpd=lpdrawitemstruct; A few names, easy to use
Judge whether the menu is self drawn, because the button can also be painted
if (nidctl==0)
{
cdc* Pdc=cdc::fromhandle (LPD->HDC); Gets the device pointer to the menu to draw the menu
Pdc->setbkmode (Transparent);
CMenu menu;
Menu. Attach ((hmenu) lpd->hwnditem); Get Frame Menu Object
CRect Allrgn (Lpd->rcitem); Gets the size of the currently drawn menu option item
CRect Frontrgn (Allrgn.left,allrgn.top,20,allrgn.bottom);
CBrush Brushall (RGB (250,250,250)); Initializing a painting brush
CBrush Brushfront (RGB (230,230,230));
CBrush Brushsel (RGB (148,170,214));
CString StrText;
Menu. Getmenustring (Lpd->itemid,strtext,mf_bycommand); Gets the text of the currently drawn menu option
if (lpd->itemid!=id_separator)//menu and separator bars are plotted separately
{
if (Lpd->itemaction & Oda_select)//Menu selected style
{
Pdc->fillrect (Allrgn,&brushsel); Draw
if (Lpd->itemstate &ods_grayed)
Set text color (to be drawn at the end)
Pdc->settextcolor (RGB (194,194,194));
else if (Lpd->itemstate & ods_selected)
Pdc->settextcolor (RGB (250,250,250));
}
The style when the menu is not selected
if (!) ( (Lpd->itemaction & Oda_select) && (Lpd->itemstate & ods_selected))
{
Pdc->fillrect (Allrgn,&brushall); Draw
Pdc->fillrect (Frontrgn,&brushfront);
if (Lpd->itemstate & ods_grayed)
Pdc->settextcolor (RGB (194,194,194));
Else
Pdc->settextcolor (RGB (66,110,180));
}
}
Else
Pdc->fillrect (Allrgn,&brushfront); Draw Separator Bar
Pdc->textout (Allrgn.left+30,allrgn.top+5,strtext); Print out fonts
Menu. Detach ()//Separator menu handle and object (necessary!)
}
}
void Cmainframe::oninitmenu (cmenu* pmenu)
{
CMenu *psubmenu;
UINT Ncount,nsubcount,nid;
CString StrText;
Ncount=pmenu->getmenuitemcount ();
for (UINT i=0;i<ncount;i++)
{
Psubmenu =pmenu->getsubmenu (i);
Nsubcount=psubmenu->getmenuitemcount ();
for (UINT j=0;j<nsubcount;j++)
{
Nid=psubmenu->getmenuitemid (j);
Add Mf_ownerdraw flags to all menus in the frame menu
Psubmenu->modifymenu (j,mf_byposition| Mf_ownerdraw,nid);
Psubmenu->getmenustring (j,strtext,mf_byposition);
}
}
}
In this way, your program has a beautiful menu: It's just an initial plate.