vc++菜单全集
- 格式:docx
- 大小:43.19 KB
- 文档页数:12
CategoryCD-ROM (1)关闭计算机 (1)重启计算机 (1)枚举所有字体 (1)只运行一个程序实例 (2)得到鼠标位置 (2)显示和隐藏程序菜单 (3)获取可执行文件的图标 (3)窗口自动靠边程序演示 (3)系统菜单添加菜单项 (5)动态增加或删除菜单 (6)改变应用程序的图标 (7)改变窗口标题的方法 (7)剪切板上通过增强元文件拷贝图像数据 (8)剪切板上文本数据的传送 (8)捕捉屏幕图像到剪切板中 (9)将位图缩放显示 (11)改变对话框中控件的颜色 (12)修改窗口外观 (14)获得应用程序主窗口的指针 (15)确定应用程序的路径 (15)获得其他程序的图标 (15)获得各种目录信息 (16)如何自定义消息 (16)改变窗口的缺省风格 (16)将窗口居中显示 (17)一启动就最大化和最小化 (17)限制窗口的大小 (17)创建一个字回绕的CEditView (18)程序保持极小状态 (18)移动窗口 (18)重置窗口的大小 (18)单击窗口标题栏以外区域使窗口移动 (19)改变视窗的背景颜色 (20)防止主框窗口在其说明中显示活动的文档名 (20)获取有关窗口正在处理的当前消息的信息 (21)代码中获取工具条和状态条的指针 (21)使能和禁止工具条的工具提示 (21)如何创建一个不规则形状的窗口 (22)获取应用程序的实例句柄 (24)如何编程结束应用程序 (24)创建和使用无模式对话框 (25)怎样加载其他的应用程序 (26)使窗口始终在最前方 (27)在对话框中显示一个位图 (27)获取一个对话控件的指针 (27)改变控件的字体 (28)OLE控件中使用OLE_COLOR数据类型 (28)在不使用通用文件打开对话的情况下如何显示一个文件列表 (29)旋转按钮控件 (29)用位图显示下压按钮 (29)创建三态下压按钮 (30)如何动态创建控件 (30)限制编辑框中的准许字符 (30)向列表框中添加多个项时防止闪烁 (32)向编辑控件中添加文本 (32)访问预定义的GDI对象 (32)获取GDI对象的属性信息 (33)实现一个橡皮区矩形 (34)更新翻转背景颜色的文本 (36)创建一个具有特定点大小的字体 (36)如何计算一个串的大小 (37)显示旋转文本 (37)显示包含标签字符的串 (39)串太长时如何在其末尾显示一个省略号 (39)为什么即使调用EnableMenuItem菜单项后,菜单项还处于禁止状态 (39)在用户环境中如何确定系统显示元素的颜色 (40)查询和设置系统参数 (40)确定当前屏幕分辨率 (41)使用预定义Windows光标 (41)检索原先的Task Manager应用程序使用的任务列表 (41)确定Windows和Windows系统目录 (42)在哪儿创建临文件 (43)我怎样才能建立一个等待光标 (44)访问桌面窗口 (44)怎样用COLORREF (44)在应用程序中循环浏览已经打开的文档、视图 (45)MFC在窗口标题栏 (45)CD-ROM打开:mciSendString("Set cdAudio door open wait",NULL,0,NULL);关闭:mciSendString("Set cdAudio door closed wait",NULL,0,NULL);关闭计算机OSVERSIONINFO OsVersionInfo; //包含操作系统版本信息的数据结构OsVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);GetVersionEx(&OsVersionInfo); //获取操作系统版本信息if(OsVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS){//Windows98,调用ExitWindowsEx()函数重新启动计算机DWORD dwReserved;ExitWindowsEx(EWX_REBOOT,dwReserved); //可以改变第一个参数,实现注销用户、//关机、关闭电源等操作// 退出前的一些处理程序}重启计算机typedef int (CALLBACK *SHUTDOWNDLG)(int); //显示关机对话框函数的指针HINSTANCE hInst = LoadLibrary("shell32.dll"); //装入shell32.dll SHUTDOWNDLG ShutDownDialog; //指向shell32.dll库中显示关机对话框函数的指针if(hInst != NULL){//获得函数的地址并调用之ShutDownDialog = (SHUTDOWNDLG)GetProcAddress(hInst,(LPSTR)60);(*ShutDownDialog)(0);}枚举所有字体LOGFONT lf;lf.lfCharSet = DEFAULT_CHARSET; // Initialize the LOGFONT structurestrcpy(lf.lfFaceName,"");CClientDC dc (this);// Enumerate the font families::EnumFontFamiliesEx((HDC)dc,&lf,(FONTENUMPROC) EnumFontFamProc,(LPARAM) this,0);//枚举函数int CALLBACK EnumFontFamProc(LPENUMLOGFONT lpelf,LPNEWTEXTMETRIC lpntm,DWORD nFontType,long lparam){// Create a pointer to the dialog windowCDay7Dlg* pWnd = (CDay7Dlg*) lparam;// add the font name to the list boxpWnd ->m_ctlFontList.AddString(lpelf ->elfLogFont.lfFaceName);// Return 1 to continue font enumerationreturn 1;}其中m_ctlFontList是一个列表控件变量只运行一个程序实例if( FindWindow(NULL,"程序标题")) exit(0);或CreateMutx:HANDLE m_hMutex = ::CreateMutex(NULL,true,_T("MBD"));if(GetLastError() == ERROR_ALREADY_EXISTS){ReleaseMutex(m_hMutex);::MessageBox(NULL,_T("应用程序已经运行!"),_T("系统提示"),MB_OK|MB_ICONSTOP);return FALSE;}也可以用CreateThread,方法同CreateMutex得到鼠标位置CPoint pt;GetCursorPos(&pt); //得到位置显示和隐藏程序菜单CWnd *pWnd=AfxGetMainWnd();if(b_m) //隐藏菜单{pWnd->SetMenu(NULL);pWnd->DrawMenuBar();b_m=false;}else{CMenu menu;menu.LoadMenu(IDR_MAINFRAME); ////显示菜单也可改变菜单项pWnd->SetMenu(&menu);pWnd->DrawMenuBar();b_m=true;menu.Detach();}获取可执行文件的图标HICON hIcon=::ExtractIcon(AfxGetInstanceHandle(),_T("NotePad.exe"),0); if (hIcon &&hIcon!=(HICON)-1){pDC->DrawIcon(10,10,hIcon);}DestroyIcon(hIcon);窗口自动靠边程序演示BOOL AdjustPos(CRect* lpRect){//自动靠边int iSX=GetSystemMetrics(SM_CXFULLSCREEN);int iSY=GetSystemMetrics(SM_CYFULLSCREEN);RECT rWorkArea;BOOL bResult = SystemParametersInfo(SPI_GETWORKAREA, sizeof(RECT), &rWorkAre a, 0);CRect rcWA;if(!bResult){//如果调用不成功就利用GetSystemMetrics获取屏幕面积rcWA=CRect(0,0,iSX,iSY);}elsercWA=rWorkArea;int iX=lpRect->left;int iY=lpRect->top;if(iX < rcWA.left + DETASTEP && iX!=rcWA.left){//调整左//pWnd->SetWindowPos(NULL,rcWA.left,iY,0,0,SWP_NOSIZE);lpRect->OffsetRect(rcWA.left-iX,0);AdjustPos(lpRect);return TRUE;}if(iY < rcWA.top + DETASTEP && iY!=rcWA.top){//调整上//pWnd->SetWindowPos(NULL ,iX,rcWA.top,0,0,SWP_NOSIZE);lpRect->OffsetRect(0,rcWA.top-iY);AdjustPos(lpRect);return TRUE;}if(iX + lpRect->Width() > rcWA.right - DETASTEP && iX !=rcWA.right-lpRect->W idth()){//调整右//pWnd->SetWindowPos(NULL ,rcWA.right-rcW.Width(),iY,0,0,SWP_NOSIZE);lpRect->OffsetRect(rcWA.right-lpRect->right,0);AdjustPos(lpRect);return TRUE;}if(iY + lpRect->Height() > rcWA.bottom - DETASTEP && iY !=rcWA.bottom-lpRect->Height()){//调整下//pWnd->SetWindowPos(NULL ,iX,rcWA.bottom-rcW.Height(),0,0,SWP_NOSIZE);lpRect->OffsetRect(0,rcWA.bottom-lpRect->bottom);return TRUE;}return FALSE;}//然后在ONMOVEING事件中使用所下过程调用CRect r=*pRect;AdjustPos(&r);*pRect=(RECT)r;系统菜单添加菜单项给系统菜单添加一个菜单项需要进行下述三个步骤:首先,使用Resource Symbols对话(在View菜单中选择Resource Symbols...可以显示该对话)定义菜单项ID,该ID应大于0x0F而小于0xF000;其次,调用CWnd::GetSystemMenu获取系统菜单的指针并调用CWnd:: Appendmenu将菜单项添加到菜单中。
动态添加菜单项、子菜单、右键菜单VC动态添加菜单项、子菜单、右键菜单(VC)2010-06-27 16:56如何动态添加菜单/菜单项、子菜单、右键菜单有关菜单的操作主要用到CMenu类,当然也可用相应API函数,CMenu类只是MFC对API中操作菜单的函数的封装而已。
不过能用类就尽量用类,类的组织方式好呗,代码看着也舒服。
若是SDK编程,那就用API吧。
CMenu menuMain,menu1;//首先定义CMenu对象一、创建菜单,有两种方法1.用LoadMenu函数从资源加载menuMain.LoadMenu(IDR_MAINFRAME);//从资源加载,这里使用SDI的主菜单资源2.用CreateMenu函数创建menu1.CreateMenu();//创建菜单,还没有菜单项二、添加菜单项,可用AppendMenu()在菜单的最后加、InsertMenu()在指定的位置加.//ID_TEST1在Resource.h中定义,随便给个整数值,不要和已有的重复就行了menu1.AppendMenu(MF_STRING,ID_TEST1,"Test1");//第一项菜单项menu1.AppendMenu(MF_STRING,ID_TEST2,"Test2");//第二项菜单项menu1.InsertMenu(1,MF_BYPOSITION|MF_STRING,(UINT)ID_TEST1,"ID_TEST1");//在第二项菜单项前添加新菜单项三、添加子菜单同样用AppendMenu()、InsertMenu()函数。
不过要注意参数的设置。
menu1.AppendMenu(MF_BYPOSITION|MF_POPUP|MF_STRING,(UINT)menuMain.GetSubMenu(0)-m_hMenu,"子菜单");//第二个参数是菜单的句柄HMENU四、删除菜单用DeleteMenu()、RemoveMenu()函数来删除指定位置的菜单/菜单项。
第一节MessageBox(NULL,TEXT("世界你好"),TEXT("问"),MB_OK|MB_ICONQUESTION);第一个参数暂时不讲;第二个是正文;第三个是标题(Caption);第四个是类型各种按钮:#define MB_OK 0x00000000L#define MB_OKCANCEL 0x00000001L#define MB_ABORTRETRYIGNORE 0x00000002L#define MB_YESNOCANCEL 0x00000003L#define MB_YESNO 0x00000004L#define MB_RETRYCANCEL 0x00000005L各种图标:#define MB_ICONHAND 0x00000010L#define MB_ICONQUESTION 0x00000020L#define MB_ICONEXCLAMATION 0x00000030L#define MB_ICONASTERISK 0x00000040LMessageBox是有返回值的,返回值为用户点击的按钮:#define IDOK 1#define IDCANCEL 2#define IDABORT 3#define IDRETRY 4#define IDIGNORE 5#define IDYES 6#define IDNO 7例子:int ret = MessageBox(NULL, TEXT("你是人吗?"), TEXT("火星人"),MB_YESNO |MB_ICONQUESTION);if(ret==IDYES){MessageBox(NULL, TEXT("火星人你好"), TEXT("问好"),MB_OK);}else{MessageBox(NULL, TEXT("欢迎回家来"), TEXT("问好"),MB_OK);}第2节1.框中图片资源的应用在资源视图中,选择“引入”,然后文件过滤器选择“*.*”,找到bmp图片文件。
VC6MFC菜单详解⼀、消息路由1、消息的路由:MFC在后台把窗⼝过程函数替换成了AfxWndProc函数,由这个函数对所有的消息进⾏处理,该函数内部将调⽤AfxCallWndProc函数,AfxCallWndProc函数⼜将调⽤WindowProc函数(CWnd类的成员函数),应⽤程序所有类型的消息都会进⼊到这个函数中。
WindowProc函数⼜将调⽤OnWndMsg函数,该函数会对到来的消息进⾏⼀个类型判断:若是标准消息,OnWndMsg函数查找相应的消息映射函数进⾏处理;若是命令消息,就交由OnCommand函数来处理,该函数将完成命令消息的路由;若是通告消息,将交由OnNotify 函数来处理,该函数将完成通告消息的路由。
OnCommand函数和OnNotify函数最后都会调⽤OnCmdMsg函数。
如下图所⽰:2、菜单命令消息路由的具体过程:当单击某个菜单项时,最先接收到这个菜单命令消息的是框架类(Frame类)。
框架类将把接收到的这个消息交给它的⼦窗⼝,即视类(View类)。
视类⾸先根据命令消息映射机制查找⾃⾝是否对此消息进⾏了响应,若响应了,就调⽤相应响应函数对这个消息进⾏处理,消息路由结束;若视类没有对此命令消息做出响应,就交由⽂档类。
⽂档类同样查找⾃⾝是否对这个菜单命令进⾏了响应,若响应了,就由⽂档类的命令消息响应函数进⾏处理,路由过程结束。
若⽂档类也未做出响应,就把这个命令消息交还给视类,视类⼜把该消息交还给框架类。
框架类查看⾃⼰是否对这个命令消息进⾏了响应,若它也没有做出响应。
就把这个菜单命令消息交给应⽤程序类来处理。
因此菜单命令的响应顺序依次是:视类、⽂档类、框架类、应⽤程序类。
⼆、菜单1、菜单项前添加标记”√”(1)、通过菜单项位置索引,在Frame类的OnCreate函数中添加:GetMenu()->GetSubMenu(0)->CheckMenuItem(0,MF_BYPOSITION | MF_CHECKED);说明:GetMenu()获得菜单栏,GetSubMenu(0)获得第⼀个⼦菜单,CheckMenuItem(0,MF_BYPOSITION | MF_CHECKED)为⼦菜单的第⼀个菜单项添加标记。
第六章菜单、工具栏和状态栏菜单、工具栏和状态栏是组成Windows图形界面的三个主要元素。
其中菜单、工具栏提供了用户操作应用程序的命令界面;状态栏提供了一个输出区域,用来显示当前程序运行的状态和数据变化等等。
本章将详细的介绍菜单、工具栏和状态栏的使用方法。
6.1 菜单大多数的Windows应用程序都提供菜单作为用户与应用程序之间传递命令的一个特殊的途径。
利用菜单可以不用将大量的命令按钮摆放在窗口上。
既节省空间又使用方便。
本节将主要讲述菜单的种类,菜单的设计与创建,及菜单的消息处理等等。
6.1.1 菜单介绍在众多的应用程序当中,我们最常见到的菜单有下拉式菜单、级联菜单和快捷方式菜单。
下拉式菜单一般出现在应用程序窗口的顶部,分类的类别排成一行,和某个类别相关的所有功能排在那个类别的下面,如果选中某个类别时,其下就会拉出菜单,该菜单中有一系列具有相关功能的菜单项可供选择。
级联菜单是下拉菜单的一个扩展。
如果某个菜单项的右边有一个向右的黑三角符号,那么这个菜单项其实就是一个级联菜单。
级联菜单带有另一个子菜单,子菜单一般显示在所属菜单项的右边。
这个子菜单和下拉式菜单相似,有一系列菜单项可供选择。
需要注意的是,请读者一定要区别弹出式菜单和菜单项。
一般来说,把单击后会出现下拉子菜单的菜单称为弹出式菜单,而把其他菜单叫菜单项。
级联菜单也是弹出式菜单,它右边出现的子菜单中的各个小菜单也叫菜单项。
第三种菜单风格是可以通过在应用程序区域中单击鼠标右键调出的一种很方便的菜单,叫快捷菜单或弹出式菜单。
由于该菜单的菜单项内容依赖于被选中的对象或光标、鼠标在工作区域内所指的位置,因此该种菜单也称为上下文菜单。
一般情况下,当我们新建好一个MFC应用程序时,AppWizard都会为我们生成一个常用的菜单。
单文档应用程序会自动生成标识符为IDR_MAINFRAME的菜单资源,而多文档应用程序自动生成标识符为IDR_MAINFRAME和IDR_xxxTYPE的菜单资源,其中xxx为你的工程名。
VC++控件使⽤——菜单VC++简单应⽤指南四——菜单⼀、菜单资源设计1.打开⼯作区窗⼝,在Resource View选项卡中,右击,选择插⼊2.打开插⼊资源对话框,选择Menu节点,点击新建3.打开菜单资源设计窗⼝,再按Enter键,显⽰菜单资源属性窗⼝4.在菜单资源属性窗⼝中填写标题5.选中菜单标题填写的⼦菜单,并点击Enter 键或者双击6.添加分割线,在菜单资源属性中点选分隔符(Separator)7.⼦菜单添加弹出菜单,菜单资源属性中点选弹出(Pop-up)8.给菜单添加快捷键,在标题后添加“&+字母”,则Alt+字母就是快捷键⼆、菜单项的命令处理1.命令设置在类向导中;打开类向导,点选Message Maps选项卡2.打开Message Maps选项卡,Class name对应对话框;Object IDs对应菜单项ID;Messages 对应事件:COMMAND单击事件3.选择COMMAND单击事件,点击Add Function,弹出创建窗⼝,点击OK4.在类向导中点击Edit Code按钮,显⽰命令处理函数三、动态创建菜单1.创建基于对话框的应⽤程序2.头⽂件中声明⼀个CMenu类对象m_Menu3.1在FileView选项卡中打开资源头⽂件(Resource.h),定义命令ID3.2在资源头⽂件中添加的代码如下#define ID_MENUCAT 1001#define ID_MENUDOG 1002#define ID_MENUMONKEY 10034.1在对话框OnInitDialog⽅法中创建菜单 4.2创建菜单程序m_Menu.CreateMenu();CMenu m_PopMenu;m_PopMenu.CreatePopupMenu();m_Menu.AppendMenu(MF_POPUP,(UINT)m_PopMenu,m_hMenu,"动物");m_PopMenu.AppendMenu(MF_STRING,ID_MENUCAT,"猫");m_PopMenu.AppendMenu(MF_STRING,ID_MENUDOG,"狗");m_PopMenu.AppendMenu(MF_STRING,ID_MENUMONKEY,"猴⼦");m_PopMenu.Detach();SetMenu(&m_Menu);5.2程序5.1在对话框的头⽂件中声明菜单的消息处理函数afx_msg void OnMenucat();afx_msg void OnMenudog();afx_msg void OnMenumonkey();6.2程序6.1在对话框源⽂件中添加消息映射宏,将命令ID关联到消息处理函数中ON_COMMAND(ID_MENUCAT,OnMenucat)ON_COMMAND(ID_MENUDOG,OnMenudog)ON_COMMAND(ID_MENUMONKEY,OnMenumonkey) 7.1在对话框源⽂件中添加消息处理函数7.2程序void CMy124Dlg::OnMenucat(){MessageBox("猫");}void CMy124Dlg::OnMenudog(){MessageBox("狗");}void CMy124Dlg::OnMenumonkey(){MessageBox("猴⼦");}四、创建弹出式菜单1.创建基于对话框的应⽤程序2.在资源选项卡中右击,选择插⼊,在插⼊资源窗⼝中选择Menu 点击新建3.对菜单进⾏编辑4.在对话框头⽂件中声明⼀个CMenu类对象m_Menu6.在类视图选项卡中,右击对话框程序节点,然后选择Add Windows Message Handler命令,在弹出的对话框中选择WM_RBUTTONUP 事件,点击Add Handler ,点击确定:⿏标右键抬起触发m_Menu.LoadMenu(IDR_MENU1);7.1在⿏标右键抬起事件处理函数中添加代码7.2程序CMenu *pMenu =m_Menu.GetSubMenu(0);CRect rect;ClientToScreen(&point);rect.top = point.x;rect.left = point.y;pMenu->TrackPopupMenu(TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_VERTICAL,rect.top,rect.left,this,&rect);8.1给弹出菜单中添加⽂件增加单击事件8.2程序MessageBox("成功");五、创建图标菜单1.创建基于对话框的应⽤程序2.在⼯作区窗⼝选择Recource View选项卡,右击⼀个节点,弹出快捷菜单,点击Insert命令3.在插⼊资源窗⼝,选择菜单资源,插⼊并编辑4.新建⼀个类;打开类向导,创建类名为CMenuIcon,5.打开CMenuIcon类的头⽂件,为该类添加⼀个基类Cmenu6.1在CMenuIcon头⽂件中定义⼀个数据结6.2程序构,⽤来保存菜单信息struct CMenuItem{CString m_ItemText;int m_IconIndex;int m_ItemID;};int m_Index;int m_IconIndex;CImageList m_ImageList;8.2程序8.1在CMenuIcon类的构造函数中初始化图像列表m_Index=0;m_IconIndex=0;m_ImageList.Create(16,16,ILC_COLOR24|ILC_MASK,0,0);m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON1));m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON2));m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON3));m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON4));m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON5));m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON6));9.1在CMenuIcon类中添加AttatchMenu⽅法9.2AttatchMenu⽅法中添加程序9.3程序LoadMenu(m_uID);return TRUE;10.210.1在CMenuIcon类中添加MenuItem⽅法,并添加程序BOOL CMenuIcon::MenuItem(CMenu *pMenu){if(pMenu!=NULL){int m_Count=pMenu->GetMenuItemCount();for(int i=0;ipMenu->GetMenuString(i,m_ItemLists[m_Index].m_ItemText,MF_B YPOSITION);int m_itemID=pMenu->GetMenuItemID(i);m_ItemLists[m_Index].m_ItemID=m_itemID;if(m_itemID>0){m_ItemLists[m_Index].m_IconIndex=m_IconIndex;m_IconIndex+=1;}RING,m_ItemLists[m_Index].m_ItemID,(LPSTR)&(m_ItemLists[m_Index])); m_Index+=1;CMenu *m_SubMenu=pMenu->GetSubMenu(i);if(m_SubMenu){MenuItem(m_SubMenu);}}} return TRUE;}11.2程序11.1重载CMenuIcon类中MeasureItem虚拟⽅法,计算菜单项的⼤⼩1.在类上⽅右击,选择新建成员函数,并创建voidCMenuIcon::MeasureItem(LPMEASUREITEMSTRUCT IpStruct){if(IpStruct->CtlType==ODT_MENU){IpStruct->itemHeight=ITEMHEIGHT;IpStruct->itemWidth=ITEMWIDTH;CMenuItem* m_item;m_item=(CMenuItem*)IpStruct->itemData;IpStruct->itemWidth=((CMenuItem*)IpStruct->itemData)->m_ItemText.GetLength()*10;if(m_item->m_ItemID==0){IpStruct->itemHeight=2;}}}员函数,绘制菜单项⽂本void CMenuIcon::DrawItemText(CDC *pDC,LPSTR Str, CRect Rect){pDC->DrawText(Str,Rect,DT_CENTER|DT_VCENTER|DT_SINGLELINE);13.2程序13.1在CMenuIcon类中添加DrawItemIcon成员函数,绘制菜单项图标void CMenuIcon::DrawItemIcon(CDC *pDC, CRect Rect, int Icon){m_ImageList.Draw(pDC,Icon,CPoint(Rect.left+2,Rect.top+4),ILD_TRANSPARENT);}14.2程序14.1在CMenuIcon类中添加DrawSeparater成员函数,绘制分隔条void CMenuIcon::DrawSeparater(CDC *pDC, CRect Rect){pDC->Draw3dRect(Rect,RGB(255,0,255),RGB(255,0,255));}15.2程序15.1在CMenuIcon类中添加DrawTopMenu成员函数,绘制顶层菜单void CMenuIcon::DrawTopMenu(CDC *pDC, CRect Rect, BOOL Selected){if(Selected){pDC->Rectangle(&Rect);Rect.DeflateRect(1,1);pDC->FillSolidRect(Rect,RGB(192,170,220));}else{pDC->FillSolidRect(&Rect,RGB(192,192,192));}成员函数,绘制普通菜单项void CMenuIcon::DrawComMenu(CDC *pDC, CRect Rect, BOOL Selected) {if(Selected){pDC->Rectangle(&Rect);Rect.DeflateRect(1,1);pDC->FillSolidRect(Rect,RGB(255,0,0));}else{pDC->FillSolidRect(&Rect,RGB(255,255,255));}}17.2程序17.1重载CMenuIcon类中DrawItem虚拟⽅法,根据菜单项的不同状态绘制菜单项void CMenuIcon::DrawItem(LPDRAWITEMSTRUCT IpStruct){ if(IpStruct->CtlType==ODT_MENU) {if(IpStruct->itemData==NULL)return;unsigned int m_state=IpStruct->itemState;CDC* pDC=CDC::FromHandle(IpStruct->hDC);CString str =((CMenuItem*)(IpStruct->itemData))->m_ItemText;LPSTR m_str = str.GetBuffer(str.GetLength());intm_itemID=((CMenuItem*)(IpStruct->itemData))->m_ItemID;intm_itemicon=((CMenuItem*)(IpStruct->itemData))->m_IconIndex;CRect m_rect=IpStruct->rcItem;pDC->SetBkMode(TRANSPARENT);switch(m_itemID) {case -1: {DrawTopMenu(pDC,m_rect,(m_state&ODS_SELECTED)||(mDrawItemText(pDC,m_str,m_rect);break; }case 0: {DrawSeparater(pDC,m_rect);break;}default: {DrawComMenu(pDC,m_rect,m_state&ODS_SELECTED);DrawItemText(pDC,m_str,m_rect);DrawItemIcon(pDC,m_rect,m_itemicon);break; }}}}18.在对话框头⽂件中声明CMenuIcon类对象m_Menu 19.在对话框OnInitDialog⽅法中加载菜单资源,并设置菜单项m_Menu.AttatchMenu(IDR_MENU1);m_Menu.MenuItem(&m_Menu);this->SetMenu(&m_Menu);20重载对话框的OnDrawItem⽅法,在该⽅法中体⽤菜单类中DrawItem⽅法21重载对话框的OnMeasureItem⽅法,在该⽅法中体⽤菜单类中MeasureItem⽅法22.屏蔽message_map 23.析构函数中添加程序m_ImageList.Detach();。
在系统菜单中添加菜单项(一)本文介绍如何向系统菜单中添加自己的菜单项,如下:1.创建一个基于对话框的工程:AddMenuToSysMenu。
2.在对话框类中添加一个成员函数:CMenu* m_pMenu;用来添加自己的菜单项。
3.在resouce.h中定义#define IDI_PECULIARMENU1201来代表自己要添加的菜单项资源。
4.在OnInitDialog中添加如下代码:m_pMenu = GetSystemMenu(FALSE);m_pMenu->AppendMenu(MF_STRING,IDI_PECULIARMENU,"系统菜单");5.在OnSysCommand中添加如下代码相应自己的消息。
elseif(nID == IDI_PECULIARMENU){MessageBox("系统菜单"," 提示",MB_OK|MB_ICONINFORMATION);}注:1.改变标题栏菜单图标如下:m_hIcon = AfxGetApp()->LoadIcon(IDI_MAINMENU);2.用位图填充对话框如下:在OnPaint中添加如下代码:CDC *pDC = this->GetDC();CDC m_Menu;m_Menu.CreateCompatibleDC(pDC);CBitmap m_bitmap;m_bitmap.LoadBitmap(IDB_MAIN);m_Menu.SelectObject(&m_bitmap);CRect m_rect;pDC->BitBlt(0,0,800,700,&m_Menu,0,0,SRCCOPY);m_bitmap.DeleteObject();pDC->DeleteDC();带图标的程序菜单(二)本文介绍在基于单文档程序中,如何实现带图标的程序菜单。
如下:1.创建一个单文档工程:AddIconMenu2.这个工程里面用到了一个类来实现对程序菜单图标的添加以及颜色的设定等等。
添加到工程。
头文件如下:IconMenu.h// IconMenu1.h: interface for the CIconMenu class.////////////////////////////////////////////////////////////////////////#if !defined(AFX_ICONMENU1_H__FAA8B855_EE72_4332_96D7_73F8FA0 7E521__INCLUDED_)#defineAFX_ICONMENU1_H__FAA8B855_EE72_4332_96D7_73F8FA07E521__IN CLUDED_#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000constint MAX_MENUCOUNT = 60,ITEMHEIGHT = 26,ITEMWIDTH= 120; //菜单项数量/*********** **************************CMenuIte mInfo结构用于记录菜单项信息*************************************/structCMenuItemInfo{CString m_ItemText;//菜单项文本int m_IconIndex;//菜单项索引int m_ItemID;//菜单标记-2顶层菜单,-1弹出式菜单,0分隔条,其他普通菜单};classCIconMenu : publicCMenu{public:CMenuItemInfo m_ItemLists[MAX_MENUCOUNT]; //菜单项信息int m_index; //临时索引int m_iconindex;CImageList m_imagelist;//存储菜单项图标CIconMenu();BOOL ChangeMenuItem(CMenu* m_menu,BOOL m_Toped = FALSE);BOOL AttatchMenu(HMENU m_hmenu);void DrawItemText(CDC* m_pdc,LPSTR str,CRect m_rect);void DrawTopMenu(CDC* m_pdc,CRect m_rect,BOOL m_selected = FALSE); //绘制顶层菜单void DrawSeparater(CDC* m_pdc,CRect m_rect);//绘制分隔条void DrawComMenu(CDC*m_pdc,CRect m_rect,COLORREF m_fromcolor,COLORREF m_tocolor, BOOL m_selected = FALSE);void DrawMenuIcon(CDC* m_pdc,CRect m_rect,int m_icon );//override memu's viutual methodvirtual ~CIconMenu();virtualvoid MeasureItem( LPMEASUREITEMSTRUCT lpStruct );//设置菜单项大小virtualvoid DrawItem( LPDRAWITEMSTRUCT lpStruct );//重绘菜单项};#endif// !defined(AFX_ICONMENU1_H__FAA8B855_EE72_4332_96D7_73F8FA07 E521__INCLUDED_)实现文件如下:// IconMenu1.cpp: implementation of the CIconMenu class.////////////////////////////////////////////////////////////////////////#include "stdafx.h"//#include "IconMenu.h"//#include "IconMenu1.h"#include "AddIconMenu.h"#include "IconMenu.h"#ifdef _DEBUG#undef THIS_FILEstaticchar THIS_FILE[]=__FILE__;#define newDEBUG_NEW#endif//////////////////////////////////////////////////////////////////////// Construction/Destruction//////////////////////////////////////////////////////////////////////CIconMenu::CIconMenu(){m_index= 0;m_iconindex= 0;//创建图像列表m_imagelist.Create(16,16,ILC_COLOR24|ILC_MASK,0,0);//添加图标m_imagelist.Add(AfxGetApp()->LoadIcon(IDI_ICON1));m_imagelist.Add(AfxGetApp()->LoadIcon(IDI_ICON2));m_imagelist.Add(AfxGetApp()->LoadIcon(IDI_ICON3));m_imagelist.Add(AfxGetApp()->LoadIcon(IDI_ICON4));m_imagelist.Add(AfxGetApp()->LoadIcon(IDI_ICON5));m_imagelist.Add(AfxGetApp()->LoadIcon(IDI_ICON6));m_imagelist.Add(AfxGetApp()->LoadIcon(IDI_ICON7));m_imagelist.Add(AfxGetApp()->LoadIcon(IDI_ICON8));m_imagelist.Add(AfxGetApp()->LoadIcon(IDI_ICON9));m_imagelist.Add(AfxGetApp()->LoadIcon(IDI_ICON10));}CIconMenu::~CIconMenu(){m_imagelist.Detach();}BOOL CIconMenu::AttatchMenu(HMENU m_hmenu){this->Attach(m_hmenu);return TRUE;}BOOLCIconMenu::ChangeMenuItem(CMenu* m_menu,BOOL m_Toped){if (m_menu != NULL){int m_itemcount = m_menu->GetMenuItemCount();for (int i=0;i<m_itemcount;i++){m_menu->GetMenuString(i,m_ItemLists[m_index].m_ItemText, MF_BYPOSITION);int m_itemID = m_menu->GetMenuItemID(i);if (m_itemID==-1 && m_Toped){m_itemID = -2;//顶层菜单};m_ItemLists[m_index].m_ItemID = m_itemID;if (m_itemID>0){m_ItemLists[m_index].m_IconIndex= m_iconindex;m_iconindex+=1;}m_menu->ModifyMenu(i,MF_OWNERDRAW|MF_BYPOSITION |MF_STRING,m_ItemLists[m_index].m_ItemID,(LPSTR)&(m_ItemLists[m_ind ex]));m_index+=1;CMenu* m_subMenu = m_menu->GetSubMenu(i);if (m_subMenu){ChangeMenuItem(m_subMenu);}}}return TRUE ;}voidCIconMenu::MeasureItem( LPMEASUREITEMSTRUCT lpStruct ){if (lpStruct->CtlType==ODT_MENU){lpStruct->itemHeight = ITEMHEIGHT;lpStruct->itemWidth = ITEMWIDTH;CMenuItemInfo* m_iteminfo;m_iteminfo = (CMenuItemInfo*)lpStruct->itemData;lpStruct->itemWidth =((CMenuItemInfo*)lpStruct->itemData)->m_ItemText.GetLength()*10;switch(m_iteminfo->m_ItemID){case 0: //分隔条{lpStruct->itemHeight = 1;break;}}}}voidCIconMenu::DrawItem( LPDRAWITEMSTRUCT lpStruct ){if (lpStruct->CtlType==ODT_MENU){if(lpStruct->itemData == NULL) return;unsignedint m_state = lpStruct->itemState;CDC* m_dc = CDC::FromHandle(lpStruct->hDC);//m_dc.Attach(lpStruct->hDC);CString str = ((CMenuItemInfo*)(lpStruct->itemData))->m_ItemText;LPSTR m_str = str.GetBuffer(str.GetLength());int m_itemID = ((CMenuItemInfo*)(lpStruct->itemData))->m_ItemID;int m_itemicon =((CMenuItemInfo*)(lpStruct->itemData))->m_IconIndex;CRect m_rect = lpStruct->rcItem;m_dc->SetBkMode(TRANSPARENT);switch(m_itemID){case -2:{DrawTopMenu(m_dc,m_rect,(m_state&ODS_SELECTED)|| (m_state&0x0040)); //0x0040 ==ODS_HOTLIGHTDrawItemText(m_dc,m_str,m_rect);break;}case -1:{DrawItemText(m_dc,m_str,m_rect);break;}case 0:{DrawSeparater(m_dc,m_rect);break;}default:{DrawComMenu(m_dc,m_rect,0xfaa0,0xf00ff,m_state&ODS _SELECTED);DrawItemText(m_dc,m_str,m_rect);DrawMenuIcon(m_dc,m_rect,m_itemicon);break;}}}}/*************************************************************功能描述: 绘制菜单项文本参数说明: m_pdc标识画布对象,str标识菜单文本,m_rect标识菜单区域*************************************************************/ voidCIconMenu::DrawItemText(CDC* m_pdc,LPSTR str,CRect m_rect){m_rect.DeflateRect(20,0);m_pdc->DrawText(str,m_rect,DT_SINGLELINE|DT_VCENTER|DT_LEF T);}voidCIconMenu::DrawTopMenu(CDC*m_pdc,CRect m_rect,BOOL m_selected ){if (m_selected){m_pdc->SelectStockObject(BLACK_PEN);m_pdc->Rectangle(&m_rect);m_rect.DeflateRect(1,1);m_pdc->FillSolidRect(m_rect,RGB(150, 185, 255));}else{CRect rect;AfxGetMainWnd()->GetClientRect(rect);rect.top = m_rect.top;rect.bottom = m_rect.bottom;rect.left= 360;rect.right +=4;//CRect c_rect(m_rect);m_pdc->FillSolidRect(&rect,RGB(200,187, 255));m_pdc->FillSolidRect(&m_rect,RGB(200,187, 255));//m_pdc->SelectStockObject(BLACK_PEN);//m_pdc->FillSolidRect(m_rect,RGB(100, 185, 255));}}voidCIconMenu::DrawSeparater(CDC* m_pdc,CRect m_rect){if (m_pdc != NULL){m_pdc->Draw3dRect(m_rect,RGB(255,0,0),RGB(0,0,255));}}voidCIconMenu::DrawComMenu(CDC*m_pdc,CRect m_rect,COLORREF m_fromcolor,COLORREF m_tocolor, BOOL m_selected ){if (m_selected){m_pdc->Rectangle(m_rect);m_rect.DeflateRect(1,1);int r1,g1,b1;//读取渐变起点的颜色值r1 = GetRValue(m_fromcolor);g1 = GetGValue(m_fromcolor);b1 = GetBValue(m_fromcolor);int r2,g2,b2;//读取渐变终点的颜色值r2 = GetRValue(m_tocolor);g2 = GetGValue(m_tocolor);b2 = GetBValue(m_tocolor);float r3,g3,b3;//菜单区域水平方向每个点RGB值应该变化的度(范围)r3 = ((float)(r2-r1)) / (float)(m_rect.Height());g3 = (float)(g2-g1)/(float)(m_rect.Height());b3 = (float)(b2-b1)/(float)(m_rect.Height());COLORREF r,g,b;//菜单区域水平方向每个点的颜色值CPen* m_oldpen ;for (int i = m_rect.top;i<m_rect.bottom;i++){r = r1+(int)r3*(i-m_rect.top);g = g1+(int)g3*(i-m_rect.top);b = b1+ (int)b3*(i-m_rect.top);CPen m_pen (PS_SOLID,1,RGB(r,g,b));m_oldpen = m_pdc->SelectObject(&m_pen);m_pdc->MoveTo(m_rect.left,i);m_pdc->LineTo(m_rect.right,i);}m_pdc->SelectObject(m_oldpen);}else{m_pdc->FillSolidRect(m_rect,RGB(0x000000F9, 0x000000F8, 0x000000F7));}}voidCIconMenu::DrawMenuIcon(CDC* m_pdc,CRect m_rect,int m_icon ){m_imagelist.Draw(m_pdc,m_icon,CPoint(m_rect.left+2,m_rect.top+4),IL D_TRANSPARENT);}当然这里面需要的图标资源,自己拷贝到res目录下即可。