改变菜单栏字体的大小
来源:互联网 发布:广州大数据 平台 编辑:程序博客网 时间:2024/05/31 19:05
这两天在菜单栏,需要改变菜单栏字体的大小,但是CMenu类没有提供相应的方法,自己上网找了点,找到了两种方法,具体的使用情况还有待研究,先做点笔记吧
方法一:在MainFrame的OnCreate函数中增加如下代码
// startLOGFONT m_lf; memset(&m_lf, 0, sizeof(LOGFONT)); m_lf.lfHeight = 26; m_lf.lfWeight = 700;//设置字体为粗体(一般为400,粗体为700)_tcsncpy_s(m_lf.lfFaceName, LF_FACESIZE, _T("Arial"), 7); //字符拷贝函数,使用的如果是UNICODE编码,则采用wcscpy_s()函数,如果是多字节编码,则采用strcpy_s()函数 ,m_lf.lfFaceName设置字体名称m_wndMenuBar.SetMenuFont(&m_lf); // end
或者这么写:
LOGFONT logfont = {0};::SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(LOGFONT), &logfont, 0);logfont.lfHeight = 26;logfont.lfWeight = 700;afxGlobalData.SetMenuFont(&logfont, true);这里似乎只能改变主窗口的菜单字体,并且主窗口其他地方的体统字体都会随之改变。那么如果在一个弹出对话框中,要改变其菜单的字体如何实现呢?请看方法二
方法二:
首先从CMenu派生出一个子类CNewMenu(利用向导建立新的MFC类时,选择基类时没有CMenu,而CMenu派生自CObject,所以可以先将CNewMenu派生自CObject,然后再声明和定义的地方将CObject改成CMenu),然后往这个类添加三个成员函数,MeasureItem(设置菜单宽高),
DrawItem(自绘菜单),ChangeMenuItem(修改菜单项类型)
三个函数分别定义如下:
void CNewMenu::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
void CNewMenu::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
void CNewMenu::ChangeMenuItem(CMenu *pMenu)
其中MeasureItem和DrawItem是CMenu类的虚函数。
各函数的代码如下:
void CNewMenu::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct){ lpMeasureItemStruct->itemHeight=25;//项高 lpMeasureItemStruct->itemWidth=120;//项宽}
void CNewMenu::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct){// TODO: Add your code to draw the specified itemCRect rect=lpDrawItemStruct->rcItem;//菜单项矩形区域CRect rectCheck=lpDrawItemStruct->rcItem;rectCheck.right = rectCheck.left + 25;//icon或checkmark的矩形区域CDC dc;dc.Attach(lpDrawItemStruct->hDC);dc.FillSolidRect(rect,/*RGB(255,255,255)*/dc.GetBkColor());//设置菜单项的文本背景色dc.DrawEdge(&rect, EDGE_ETCHED, BF_TOP);//绘制菜单项边界CFont Font;Font.CreatePointFont(125,"宋体");//创建字体dc.SelectObject(&Font);CString *pText=(CString *)lpDrawItemStruct->itemData;rect.left += 25;if(lpDrawItemStruct->itemState&ODS_SELECTED){dc.FillSolidRect(rect,RGB(0,255,0));//设置菜单被选中时的背景色}dc.SetTextColor(RGB(10,0,181));//设置文本颜色dc.DrawText(*pText,rect,DT_VCENTER|DT_LEFT|DT_SINGLELINE);//绘制文字//通过菜单项ID来确定是否显示icon以及是否checkedswitch(lpDrawItemStruct->itemID){case IDM_MENU21://DrawMenuItemIcon(&dc,rectCheck,FALSE/*,IDB_BITMAP1*/);DrawCheckMark(&dc,rectCheck,TRUE);//DrawCheckMark(&dc,rectCheck,FALSE);break;case IDM_MENU22:DrawMenuItemIcon(&dc,rectCheck,TRUE,IDB_BITMAP1);//DrawCheckMark(&dc,rectCheck,TRUE);break;case IDM_MENU31:DrawMenuItemIcon(&dc,rectCheck,TRUE,IDB_BITMAP1);break;case IDM_MENU13:DrawMenuItemIcon(&dc,rectCheck,TRUE,IDB_BITMAP1);break;}dc.Detach();}
void CNewMenu::ChangeMenuItem(CMenu * pMenu){int itemCount=pMenu->GetMenuItemCount();//获取弹出菜单项个数for(int i=0;i<itemCount;i++){CString *pText=new CString;UINT itemID=pMenu->GetMenuItemID(i);//通过菜单项的编号位置获取菜单项ID号pMenu->GetMenuString(i,*pText,MF_BYPOSITION);//获取菜单文本//ModifyMenu函数最后一个参数对应DRAWITEMSTRUCT结构里的itemData变量pMenu->ModifyMenu(i,MF_OWNERDRAW|MF_BYPOSITION|MF_STRING,itemID,(LPSTR)pText);if(itemID==-1)//如果是一个弹出式菜单{ChangeMenuItem(pMenu->GetSubMenu(i));}} }
另外在类中添加两个绘制菜单项icon和checkMark的函数:
void CNewMenu::DrawMenuItemIcon(CDC * pDC, CRect rect, BOOL bSelected,UINT nIDBmpResource){//如果不绘制icon,则用背景色填充icon所在区域if(!bSelected){CBrush MenuItemBKBrush;MenuItemBKBrush.CreateSysColorBrush(COLOR_BTNFACE);FillRect(pDC->GetSafeHdc(),&rect,(HBRUSH)MenuItemBKBrush);return;}CBitmap bmp;if (bmp.LoadBitmap(nIDBmpResource)){//获取位图属性BITMAP bmpInfo;bmp.GetBitmap(&bmpInfo);// 创建一个与当前DC兼容的内存DCCDC dcMemory;dcMemory.CreateCompatibleDC(pDC);// 将位图选入内存DCCBitmap* pOldBitmap = dcMemory.SelectObject(&bmp);//获取bmp图片绘制的适当位置int nX = rect.left + (rect.Width() - bmpInfo.bmWidth) / 2;int nY = rect.top + (rect.Height() - bmpInfo.bmHeight) / 2;// 将内存DC中的位图拷贝到当前DC进行显示pDC->BitBlt(nX ,nY , bmpInfo.bmWidth, bmpInfo.bmHeight, &dcMemory, 0, 0, SRCCOPY);//dcMemory.SelectObject(pOldBitmap);}}
void CNewMenu::DrawCheckMark(CDC * pDC, CRect rect, BOOL bSelected){//这是自绘的方式,但是使用资源图片直接贴上去会更简单//if(!bSelected)//return;//const int nCheckDots = 8;//CPoint pt1, pt2, pt3;//3 point of the checkmark//pt1.x = 0;// 5/18 of the rect width//pt1.y = 3;//pt2.x = 2;//pt2.y = 5;//pt3.x = 7;//pt3.y = 0;//int xOff = (rect.Width()-nCheckDots)/2 + rect.left ;//int yOff = (rect.Height()-nCheckDots)/2 + rect.top;//pt1.Offset(xOff, yOff);//pt2.Offset(xOff, yOff);//pt3.Offset(xOff, yOff);//CPenpen(PS_SOLID, 1, RGB(0, 0, 0));//CGdiObject *pOldPen = pDC->SelectObject(&pen);//pDC->MoveTo(pt1);//pDC->LineTo(pt2);//pDC->LineTo(pt3);//pt1.Offset(0, 1);//pt2.Offset(0, 1);//pt3.Offset(0, 1);//pDC->MoveTo(pt1);//pDC->LineTo(pt2);//pDC->LineTo(pt3);//pt1.Offset(0, 1);//pt2.Offset(0, 1);//pt3.Offset(0, 1);//pDC->MoveTo(pt1);//pDC->LineTo(pt2);//pDC->LineTo(pt3);//pDC->SelectObject(pOldPen);DrawMenuItemIcon(pDC,rect,bSelected,IDB_CHECKMARK);}
必须让每个菜单项具有MF_OWNERDRAW属性,不然接不到WM_MEASUREITEM和WM_DRAWITEM消息,而且菜单项不具有MF_OWNERDRAW属性, 即使接到消息,也无法自绘,所以上面的ChangeMenuItem函数就是用于修改菜单项属性
WM_MEASUREITEM和WM_DRAWITEM消息不是直接发给菜单窗口的,会被父窗口给收到,所以得处理父窗口的WM_MEASUREITEM和WM_DRAWITEM消息,给话框类添加这两个消息处理函数,两个函数里的代码分别如下:
void CFirstDlg::OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct){ // TODO: Add your message handler code here and/or call default if(lpMeasureItemStruct->CtlType==ODT_MENU)//如果类型是菜单 newMenu.MeasureItem(lpMeasureItemStruct);//调用CNewMenu类的MeasureItem成员函数 else CDialog::OnMeasureItem(nIDCtl, lpMeasureItemStruct); }
void CFirstDlg::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct){ // TODO: Add your message handler code here and/or call default if(lpDrawItemStruct->CtlType==ODT_MENU) newMenu.DrawItem(lpDrawItemStruct); else CDialog::OnDrawItem(nIDCtl, lpDrawItemStruct);}
接着我们在对话类添加一个成员变量:
CNewMenu newMenu; (记得要包含头文件:"NewMenu.h"),然后在对话框类的OnInitDialog函数添加如下代码:
newMenu.LoadMenu(IDR_MENU1);SetMenu(&newMenu);//只更改下主菜单下的第一项,更改全部:newMenu.ChangeMenuItem(&newMenu);newMenu.ChangeMenuItem(newMenu.GetSubMenu(1));newMenu.CheckMenuItem(IDM_MENU12,MF_CHECKED);newMenu.ChangeMenuItem(newMenu.GetSubMenu(2));
现在可以运行了,但是还是存在一些问题,请看下图:
菜单名的大小并没有变,这个问题还有待研究
这里绘制菜单的文字和icon都是在类的DrawItem中完成的,由于刚刚接触MFC不久,还不知道怎么写好点的接口实现动态设置icon,希望得到大家的指点
0 0
- 改变菜单栏字体的大小
- Java GUI菜单栏(非下拉菜单)的字体及大小的改变
- jquery 改变字体的大小
- 修改android studio菜单栏和代码的字体和大小
- VB.NET中改变字体的大小
- 改变flex中ToolTip字体的大小
- android listview改变字体的大小、颜色
- 如何改变CEdit的字体颜色大小
- jQuery 改变页面字体的大小
- 如何改变CEdit的字体颜色大小
- 如何改变编辑框字体的大小
- 改变字体的颜色和大小
- 改变webView上面字体的大小方法
- android listview改变字体的大小、颜色
- vivado中改变代码字体的大小
- textView 动态改变字体的大小
- android listview改变字体的大小、颜色
- MFC改变静态控件字体的大小
- Windows查找文件夹下所有文件-C实现
- 黑马程序员-io读取键盘录入之转换流
- ASP.NET:EXCEL找不到文件、权限不够之综合解决方案
- UIKit各类概述
- swift 普通数组和元组数组排序
- 改变菜单栏字体的大小
- Android 5.x Theme 与 ToolBar 实战
- Android的WebView控件载入网页显示速度慢的究极解决方案
- Android 内存泄漏与分析方法
- 【machine learning】朴素贝叶斯分类方法
- 对java中public、static的理解
- 在ZigBee网络中怎么实现节电断电之后重新加入网络
- CNN框架理解
- 【leetcode】【单链表,vector,queue】【23】Merge k Sorted Lists