本主题包含使用菜单中所有者绘制的菜单项的应用程序的示例。该菜单包含设置当前字体的属性的项目,并使用适当的字体属性显示项目。
以下是资源定义文件中菜单的定义。请注意,正常,粗体,斜体和下划线菜单项的字符串在运行时分配,因此其资源定义文件中的字符串为空。
主菜单菜单
BEGIN
POPUP“&字符”
BEGIN
MENUITEM "", IDM_REGULAR
MENUITEM SEPARATOR
MENUITEM "", IDM_BOLD
MENUITEM "", IDM_ITALIC
MENUITEM "", IDM_ULINE
END
END
应用程序的窗口过程处理使用所有者绘制菜单项所涉及的消息。该应用程序使用WM_CREATE消息来执行以下操作:
*设置菜单项的MF_OWNERDRAW标志。
*设置菜单项的文本字符串。
*获取用于绘制项目的字体的句柄。
*获取所选菜单项的文本和背景颜色值。
文本字符串和字体句柄存储在应用程序定义的MYITEM结构的数组中。应用程序定义的GetAFont函数创建一个与给定字体属性对应的字体,并返回字体的句柄。处理WM_DESTROY消息期间手柄被销毁。
在WM_MEASUREITEM消息的处理期间,该示例获取菜单项字符串的宽度和高度,并将这些值复制到MEASUREITEMSTRUCT结构中。Windows使用width和height值来计算菜单的大小。
在WM_DRAWITEM消息的处理过程中,菜单项的字符串将被绘制,并在复选标记位图的字符串旁边留下空格。如果用户选择项目,则使用所选择的文本和背景颜色来绘制项目。
LRESULT APIENTRY MainWndProc(hwnd,uMsg,wParam,lParam)en
HWND hwnd;
UINT uMsg;
WPARAM wParam;
LPARAM lParam;
{
typedef struct _MYITEM {en
HFONT HFONT;
LPSTR PES;
} MYITEM; //项目字体和字符串的结构
MYITEM * pmyitem; //指向项目的字体和字符串的指针
静态MYITEM myitem [CITEMS]; // MYITEMS数组
静态HMENU hmenu; //主菜单的句柄
静态COLORREF crSelText; //所选项目的文字颜色
静态COLORREF crSelBkgnd; //所选项目的背景颜色
COLORREF crText; //未选择的项目的文本颜色
COLORREF crBkgnd; // background color unselected item
LPMEASUREITEMSTRUCT lpmis; //指向数据项
LPDRAWITEMSTRUCT lpdis; //指向项目绘图数据
HDC hdc //屏幕DC的处理
尺寸大小; //菜单项文本区域
DWORD dwCheckXY; //检查标记尺寸
WORD wCheckX; //检查标记宽度
int nTextX; //菜单项的宽度
int nTextY; //菜单项的高度
int i //循环计数器
HFONT hfontOld; //处理旧字体
BOOL fSelected = FALSE; //菜单项选择标志
开关(uMsg){
case WM_CREATE:
//修改常规,粗体,斜体和下划线
//菜单项,使其成为所有者绘制的项目。关联
//一个MYITEM结构,每个项目包含
//每个项目的字符串和字体句柄。
hmenu = GetMenu(hwnd);
ModifyMenu(hmenu,IDM_REGULAR,MF_BYCOMMAND |
MF_CHECKED | MF_OWNERDRAW, IDM_REGULAR,
(LPTSTR){989 796 005} {Mayitem 989 796 007});
ModifyMenu(hmenu,IDM_BOLD,MF_BYCOMMAND |
MF_OWNERDRAW,IDM_BOLD,(LPTSTR)& myitem [BOLD]);
ModifyMenu(hmenu,IDM_ITALIC,MF_BYCOMMAND |
MF_OWNERDRAW, IDM_ITALIC,
(LPTSTR){989 796 005} {Mayitem 989 796 009});
ModifyMenu(hmenu,IDM_ULINE,MF_BYCOMMAND |
MF_OWNERDRAW,IDM_ULINE,(LPTSTR)& myitem [ULINE]);
//检索每个项目的字体句柄并将其复制
//每个项目的MYITEM结构的hfont成员。
//此外,将每个项目的字符串复制到结构中。
myitem [REGULAR] .hfont = GetAFont(REGULAR);
myitem [REGULAR] .psz =“常规”;
myitem [BOLD] .hfont = GetAFont(BOLD);
myitem [BOLD] .psz =“Bold”;
myitem [ITALIC] .hfont = GetAFont(ITALIC);
myitem [ITALIC] .psz =“斜体”;
myitem [ULINE] .hfont = GetAFont(ULINE);
myitem [ULINE] .psz =“下划线”;
//获取文本和背景颜色
//选择菜单文本。
crSelText = GetSysColor(COLOR_HIGHLIGHTTEXT);
crSelBkgnd = GetSysColor(COLOR_HIGHLIGHT);
返回0;
案例WM_MEASUREITEM:
//检索主窗口的设备上下文。
hdc = GetDC(hwnd);
//检索菜单项的指针
// MEASUREITEMSTRUCT结构和MYITEM结构。
lpmis =(LPMEASUREITEMSTRUCT)lParam;
pmyitem =(MYITEM *)lpmis- > itemData;
//选择与该项目相关联的字体
//主窗口的设备上下文。
hfontOld = SelectObject(hdc,pmyitem- > hfont);
//检索项目的字符串的宽度和高度,
//然后将宽度和高度复制到
// MEASUREITEMSTRUCT结构的itemWidth和
// itemHeight成员。
GetTextExtentPoint32(hdc,pmyitem- > psz,
lstrlen(pmyitem- > psz),& size);
lpmis- > itemWidth = size.cx;
lpmis- > itemHeight = size.cy;
//将旧字体返回设备上下文,
//然后释放设备上下文。
SelectObject(hdc,hfontOld);
ReleaseDC(hwnd,hdc);
返回TRUE;
打破;
案例WM_DRAWITEM:
//获取菜单项的DRAWITEMSTRUCT的指针
//结构和MYITEM结构。
lpdis =(LPDRAWITEMSTRUCT)lParam;
pmyitem =(MYITEM *)lpdis- > itemData;
//如果用户选择了该项目,请使用所选项
//文字和背景颜色显示项目。
if(lpdis- > itemState & ODS_SELECTED){
crText = SetTextColor(lpdis- > hDC,crSelText);
crBkgnd = SetBkColor(lpdis- > hDC,crSelBkgnd);
fSelected = TRUE;
}
//记住在菜单项中留下空格
//复选标记位图。检索位图的宽度
//并将其添加到菜单项的宽度。
dwCheckXY GetMenuCheckMarkDimensions =();
wCheckX = LOWORD(dwCheckXY);
nTextX = wCheckX + lpdis- > rcItem.left;
nTextY = lpdis- > rcItem.top;
//选择与该项目相关联的字体
// item的设备上下文,然后绘制字符串。
hfontOld = SelectObject(lpdis- > hDC,pmyitem- > hfont);
ExtTextOut(lpdis- > hDC,nTextX,nTextY,ETO_OPAQUE,
lpdis- rcItem pmyitem- PSZ,
lstrlen(pmyitem- > psz),NULL);
//将上一个字体选择回设备
//上下文
SelectObject(lpdis- > hDC,hfontOld);
//返回文本和背景色
//正常状态(未选择)。
if(fSelected){
SetTextColor(lpdis- > hDC,crText);
SetBkColor(lpdis- > hDC,crBkgnd);
}
返回TRUE;
.
.//处理其他消息。
.
案例WM_DESTROY:
//销毁菜单项的字体句柄。
for(i = 0; i < CITEMS; i ++)
DeleteObject(myitem[i].hfont);
PostQuitMessage(0);
打破;
默认:
返回DefWindowProc(hwnd,uMsg,wParam,lParam);
}
返回NULL;
}
HFONT GetAFont(fnFont)
int fnFont; // font-attribute标志
{
静态LOGFONT lf; //字体信息的结构
//获取ANSI固定间距字体的句柄,并复制
//有关字体到LOGFONT结构的信息。
GetObject(GetStockObject(ANSI_FIXED_FONT)),sizeof(LOGFONT),
&lf);
//根据需要设置字体属性。
if(fnFont == BOLD)
lf.lfWeight = FW_BOLD;
其他
lf.lfWeight = FW_NORMAL;
lf.lfItalic =(fnFont == ITALIC);
lf.lfItalic =(fnFont == ULINE);
//创建字体,然后返回其句柄。
返回CreateFont(lf.lfHeight,lf.lfWidth,
lf.lfEscapement,lf.lfOrientation,lf.lfWeight,ar-Latn
lf.lfItalic,lf.lfUnderline,lf.lfStrikeOut,lf.lfCharSet,ar-Latn
lf.lfOutPrecision,lf.lfClipPrecision,lf.lfQuality,ar-Latn
lf.lfPitchAndFamily,lf.lfFaceName);en
}