1.创建基于对话框的MFC工程MyMenuFont;
2.创建空内容的菜单,在rc文件中添加代码;
/
//
// Menu
//
MAINMENU MENU
BEGIN
POPUP "菜单"
BEGIN
MENUITEM "", IDM_BOLD
MENUITEM "", IDM_ITALIC
MENUITEM "", IDM_ULINE
END
POPUP "设置"
BEGIN
MENUITEM "", IDM_FILE
MENUITEM "", IDM_OPEN
END
END
3.在OnInitDialog()函数中添加菜单加载和处理程序;
BOOL CMyMenuFontDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
static HMENU hmenu;
HWND hwnd = ::FindWindow(NULL, _T("MyMenuFont"));
if(!hwnd)
{
TRACE(_T("ERR:%d\n"),GetLastError());
}
hmenu = ::GetMenu(hwnd);
ModifyMenu(hmenu, IDM_BOLD, MF_BYCOMMAND |
MF_OWNERDRAW, IDM_BOLD, (LPCWSTR)&myitem[0]); //设置自绘属性
ModifyMenu(hmenu, IDM_ITALIC, MF_BYCOMMAND |
MF_OWNERDRAW, IDM_ITALIC,(LPCWSTR)&myitem[1]);
ModifyMenu(hmenu, IDM_ULINE, MF_BYCOMMAND |
MF_OWNERDRAW, IDM_ULINE, (LPCWSTR)&myitem[2]);
ModifyMenu(hmenu, IDM_FILE, MF_BYCOMMAND |
MF_OWNERDRAW, IDM_FILE,(LPCWSTR)&myitem[3]);
ModifyMenu(hmenu, IDM_OPEN, MF_BYCOMMAND |
MF_OWNERDRAW, IDM_OPEN, (LPCWSTR)&myitem[4]);
myitem[0].hfont = GetAFont(0);
myitem[0].psz = (LPSTR)_T("Bold");
myitem[1].hfont = GetAFont(1);
myitem[1].psz =(LPSTR)_T("Italic");
myitem[2].hfont = GetAFont(2);
myitem[2].psz =(LPSTR) _T("Underline");
myitem[3].hfont = GetAFont(3);
myitem[3].psz =(LPSTR) _T("File");
myitem[4].hfont = GetAFont(4);
myitem[4].psz =(LPSTR) _T("Open");
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
HFONT GetAFont(int fnFont)
{
static LOGFONT lf;
//获取ANSI固定间距字体的句柄
GetObject(GetStockObject(ANSI_FIXED_FONT), sizeof(LOGFONT), &lf);
// 设置字体属性
if (fnFont == 0)
lf.lfWeight = FW_BOLD;
else
lf.lfWeight = FW_NORMAL;
lf.lfItalic = (fnFont == 1);
lf.lfItalic = (fnFont == 2);
lf.lfHeight = 20;
lf.lfWidth = 50;
return CreateFont(lf.lfHeight, lf.lfWidth,
lf.lfEscapement, lf.lfOrientation, lf.lfWeight,
lf.lfItalic, lf.lfUnderline, lf.lfStrikeOut, lf.lfCharSet,
lf.lfOutPrecision, lf.lfClipPrecision, lf.lfQuality,
lf.lfPitchAndFamily, lf.lfFaceName);
}
4.添加OnMeasureItem和OnDrawItem消息处理函数;
void CMyMenuFontDlg::OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
lpMeasureItemStruct->itemHeight = 35;
lpMeasureItemStruct->itemWidth = 120;
CDialog::OnMeasureItem(nIDCtl, lpMeasureItemStruct);
}
void CMyMenuFontDlg::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
static COLORREF crSelText; // 选定项目的文本颜色
static COLORREF crSelBkgnd; // 选中的项目背景颜色
COLORREF crText; // 未选定项目的文本颜色
COLORREF crBkgnd; // 未被选中的项目背景颜色
WORD wCheckX; // 可选的宽度
int nTextX; // 菜单项宽度
int nTextY; // 菜单项高度
HFONT hfontOld; // 旧字体句柄
BOOL fSelected = FALSE; // 菜单项的选择标记
size_t * pcch = new size_t;
HRESULT hResult=0;
MYITEM *pmyitem;// 指向项目字体和字符串的指针
pmyitem = (MYITEM *) lpDrawItemStruct->itemData;
// 设置选中的菜单项字体颜色和背景
if (lpDrawItemStruct->itemState & ODS_SELECTED)
{
crSelText = RGB(255, 0, 0);
crSelBkgnd = RGB(182, 189,210);
crText = SetTextColor(lpDrawItemStruct->hDC, crSelText);
crBkgnd = SetBkColor(lpDrawItemStruct->hDC, crSelBkgnd);
fSelected = TRUE;
}
// 检索位图的宽度,并将其添加到菜单项的宽度中
wCheckX = GetSystemMetrics(SM_CXMENUCHECK); //检索默认菜单勾选位图的宽度,以像素为单位
nTextX = wCheckX + lpDrawItemStruct->rcItem.left;
nTextY = lpDrawItemStruct->rcItem.top;
//选择字体到菜单项的设备上下文中,然后绘制字符串
hfontOld = (HFONT)SelectObject(lpDrawItemStruct->hDC, pmyitem->hfont);
StringCchLength((LPCWSTR)pmyitem->psz,STRSAFE_MAX_CCH, pcch);
if (FAILED(hResult))
{
delete pcch;
return;
}
ExtTextOut(lpDrawItemStruct->hDC, nTextX, nTextY, ETO_OPAQUE,
&lpDrawItemStruct->rcItem, (LPCWSTR)pmyitem->psz,
*pcch, NULL);
// 将之前的字体选择回设备上下文
SelectObject(lpDrawItemStruct->hDC, hfontOld);
// 返回文本和背景颜色的正常状态(未选中)
if (fSelected)
{
SetTextColor(lpDrawItemStruct->hDC, crText);
SetBkColor(lpDrawItemStruct->hDC, crBkgnd);
}
delete pcch;
CDialog::OnDrawItem(nIDCtl, lpDrawItemStruct);
}
源代码:MyMenuFont代码