- 浏览: 874346 次
- 性别:
- 来自: 杭州
文章分类
- 全部博客 (341)
- Ajax (1)
- Asp.net (18)
- Java (5)
- Php (27)
- JavaScript (19)
- jQuery (12)
- 正则表达式 (4)
- SEO优化 (1)
- Windows 应用 (5)
- Flash (12)
- Asp (9)
- CSS (10)
- SQL Server (6)
- Flex (1)
- Ubuntu (0)
- mysql (34)
- PHP框架 (2)
- Apache (10)
- html (3)
- 网页切入 (1)
- Linux (33)
- vc++ (38)
- 友情链接 (0)
- firefox 插件 (4)
- SEO (1)
- Apache 压力测试 (1)
- imacros教程(一):imacros变量 (0)
- JS调用imacros所用到的函数 (0)
- imacros教程(三):调用csv文件 (1)
- imacros教程(二):JS调用imacros所用到的函数 (1)
- imacros 常用代码 (1)
- CSS最大宽度 (1)
- svn (1)
- WordPress (1)
- 网线的两种接法 (1)
- TP-LINK WR 系列无线路由器安全设置 (1)
- mysql talble is full ERR1114 (0)
- 解决mysql的内存表“table is full”错误 (1)
- linux 用户操作 (1)
- CentOS 挂载 ntfs 移动硬盘 (1)
- linux 储蓄设备操作 (1)
- Starting MySQL. ERROR! Manager of pid-file quit without updating file. (1)
- extmail 1.1 升级到 1.2 (1)
- extmail (0)
- emos (2)
- squid 3.0 (2)
- centos 6 minimal 安装 (1)
- linux实用命令详解 (1)
- win7 (1)
- php 字符串大小写转换 (1)
- 跟踪路由 tracert (1)
- css英文单词首字母添加样式 (1)
- jquery iframe 操作 (1)
- php 获取时间今天明天昨天时间戳 (1)
- php 上传限制 (1)
- ckeditor 配置 (1)
- flash 显示在 div 下 (1)
- flash + php 留言本乱码问题 (1)
- squid purge 出现 access denied 的解决方法 (1)
- delphi (1)
- 让delphi嵌入的WebBrowser无边框无滚动条 (1)
- delphi打开一个IE窗口 (1)
- delphi 获取鼠标当前位置的相对坐标 (1)
- delphi 获取可执行文件的当前路径 (1)
- delphi webbrowser 常用方法示例 (1)
- javascript 禁止鼠标右键... (1)
- delphi 播放gif 动画 (1)
- delphi弹出信息框大全 (1)
- Delphi中禁止WebBrowser右键的方法 (1)
- DELPHI 让程序只能运行一次 (1)
- Delphi XE2 破解补丁注册机下载使用教程 (1)
- Delphi RAD Studio XE2编译程序体积大的问题 (1)
- delphi 制作圆角窗口 (1)
- delphi 窗口 (1)
- delphi 窗体全透明,但窗体上的控件不透明 (1)
- delphi 窗口阴影 (1)
- delphi 获取任务栏高度 (1)
- delphi bsNone 之后任务栏右键无反应 (1)
- delphi 程序打开隐藏软件任务栏条 (0)
- delphi bsNone后的相关问题解决方法 (1)
- delphi bsNone 后显示边框 (1)
- delphi url编码操作 (1)
- delphi 调用exe文件 (1)
- delphi dll窗体的制作和调用 (1)
- delphi dll 调用窗体时的数据传递 (0)
- delphi 窗口显示在屏幕右下角 (1)
- 内网穿透&UDP打洞 (1)
- delphi idhttp post应用 (1)
- inno setup 开机启动 (1)
- inno setup 添加桌面快捷方式 (1)
- Delphi实现程序只运行一次并激活已打开的程序 (1)
- 解决 float point division by zero (1)
- Delphi 窗体显示在最前面,并获得焦点 (1)
- delphi 点击关闭按钮时隐藏窗口 (1)
- delphi 非客户区右键点击 (1)
- delphi真正可以截获WINDOWS关机消息的源码 (1)
- delphi utf8转码 (1)
最新评论
-
zj7243886:
非常感谢,这东西解决我的问题;谢谢你的分享
Linux 安装 jpeg-6b 错误 ./libtool 命令未找到 -
丶Sk.Mabon:
能让html也绕过吗。。机房限制很悲剧
绕过 <?PHP exit(’Access Denied’); ?> 限制 -
丶Sk.Mabon:
请教gzip.php 的写法。万分感谢!
apache 开启 gzip -
hyxj1220:
火狐中单纯的定义这样的样式,貌似不行,必须要让容器浮动
英文长文本换行CSS -
逆水寒龙:
太好了,正好用上,谢谢博主共享
Asp.net 将中文汉字转换成拼音首字和拼音全拼
(右键)菜单相关
对话框
void Panel::OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu)
{
CDialog::OnInitMenuPopup(pPopupMenu, nIndex, bSysMenu);
CCmdUI CmdUI;
for(UINT Idx = 0;Idx < pPopupMenu->GetMenuItemCount();Idx++)
{
CmdUI.m_nID = pPopupMenu->GetMenuItemID(Idx);
CmdUI.m_nIndex = Idx;
CmdUI.m_nIndexMax = pPopupMenu->GetMenuItemCount();
CmdUI.m_pMenu = pPopupMenu;
CmdUI.DoUpdate(this,FALSE);
}
}
利用菜单接受用户命令是一中很简单的交互方法,同时也是一种很有效的方法。通常菜单作为一中资源存储在文件中,因此我们可以在设计时就利用资源编辑器设计好一个菜单。关于使用VC设计菜单我就不再多讲了,但你在编写菜单时应该尽量在属性对话框的底部提示(Prompt)处输入文字,这虽然不是必要的,但MFC在有状态栏和工具条的情况下会使用该文字,文字的格式为“状态栏出说明\n工具条提示”。图33_g1
我们要面临的任务是如何知道用户何时选择了菜单,他选的是什么菜单项。当用户选择了一个有效的菜单项时系统会向应用发送一个WM_COMMAND消息,在消息的参数中表明来源。在MFC中我们只需要进行一次映射,将某一菜单ID映射到一处理函数,图33_g2。在这里我们在CView的派生类中处理菜单消息,同时我对同一ID设置两个消息映射,接下来将这两种映射的作用。
ON_COMMAND 映射的作用为在用户选择该菜单时调用指定的处理函数。如:ON_COMMAND(IDM_COMMAND1, OnCommand1)会使菜单被选择时调用OnCommand1成员函数。
ON_UPDATE_COMMAND_UI(IDM_COMMAND1, OnUpdateCommand1) 映射的作用是在菜单被显示时通过调用指定的函数来进行确定其状态。在这个处理函数中你可以设置菜单的允许/禁止状态,其显示字符串是什么,是否在前面打钩。函数的参数为CCmdUI* pCmdUI,CCmdUI是MFC专门为更新命令提供的一个类,你可以调用
Enable 设置允许/禁止状态
SetCheck 设置是否在前面打钩
SetText 设置文字
下面我讲解一个例子:我在CView派生类中有一个变量m_fSelected,并且在视中处理两个菜单的消息,当IDM_COMMAND1被选时,对m_fSelected进行逻辑非操作,当IDM_COMMAND2被选中时出一提示;同时IDM_COMMAND1根据m_fSelected决定菜单显示的文字和是否在前面打上检查符号,IDM_COMMAND2根据m_fSelected的值决定菜单的允许/禁止状态。下面是代码和说明:下载示例代码 17K
void CMenuDView::OnCommand1()
{
m_fSelected=!m_fSelected;
TRACE("command1 selected\n");
}
void CMenuDView::OnUpdateCommand1(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck(m_fSelected);//决定检查状态
pCmdUI->SetText(m_fSelected?"当前被选中":"当前未被选中");//决定所显示的文字
}
void CMenuDView::OnUpdateCommand2(CCmdUI* pCmdUI)
{//决定是否为允许
pCmdUI->Enable(m_fSelected);
}
void CMenuDView::OnCommand2()
{//选中时给出提示
AfxMessageBox("你选了command2");
}
接下来再讲一些通过代码操纵菜单的方法,在MFC中有一个类CMenu用来处理和菜单有关的功能。在生成一个CMenu对象时你需要从资源中装如菜单,通过调用BOOL CMenu:oadMenu( UINT nIDResource )进行装入,然后你就可以对菜单进行动态的修改,所涉及到的函数有:
CMenu* GetSubMenu( int nPos ) 一位置得到子菜单的指针,因为一个CMenu对象只能表示一个弹出菜单,如果菜单中的某一项也为弹出菜单,就需要通过该函数获取指针。
BOOL AppendMenu( UINT nFlags, UINT nIDNewItem = 0, LPCTSTR lpszNewItem = NULL ) 在末尾添加一项,nFlag为MF_SEPARATOR表示增加一个分隔条,这样其他两个参数将会被忽略;为MF_STRING表示添加一个菜单项uIDNewItem为该菜单的ID命令值;为MF_POPUP表示添加一个弹出菜单项,这时uIDNewItem为另一菜单的句柄HMENU。lpszNewItem为菜单文字说明。
BOOL InsertMenu( UINT nPosition, UINT nFlags, UINT nIDNewItem = 0, LPCTSTR lpszNewItem = NULL )用于在指定位置插入一菜单,位置由变量nPosition指明。如果nFlags包含MF_BYPOSITION则表明插入在nPosition位置,如果包含MF_BYCOMMAND表示插入在命令ID为nPosition的菜单处。
BOOL ModifyMenu( UINT nPosition, UINT nFlags, UINT nIDNewItem = 0, LPCTSTR lpszNewItem = NULL )用于修改某一位置的菜单,如果nFlags包含MF_BYPOSITION则表明修改nPosition位置的菜单,如果包含MF_BYCOMMAND表示修改命令ID为nPosition处的菜单。
BOOL RemoveMenu( UINT nPosition, UINT nFlags )用于删除某一位置的菜单。如果nFlags包含MF_BYPOSITION则表明删除nPosition位置的菜单,如果包含MF_BYCOMMAND表示删除命令ID为nPosition处的菜单。
BOOL AppendMenu( UINT nFlags, UINT nIDNewItem, const CBitmap* pBmp ) 和 BOOL InsertMenu( UINT nPosition, UINT nFlags, UINT nIDNewItem, const CBitmap* pBmp )可以添加一位图菜单,但这样的菜单在选中时只是反色显示,并不美观。(关于使用自绘OwnerDraw菜单请参考我翻译的一篇文章自绘菜单类)
视图中是没有菜单的,在框架窗口中才有,所以只有用AfxGetApp()->m_pMainWnd->GetMenu()才能得到应用的菜单指针。
最后我讲一下如何在程序中弹出一个菜单,你必须先装入一个菜单资源,你必需得到一个弹出菜单的指针然后调用BOOL TrackPopupMenu( UINT nFlags, int x, int y, CWnd* pWnd, LPCRECT lpRect = NULL )弹出菜单,你需要指定(x,y)为菜单弹出的位置,pWnd为接收命令消息的窗口指针。下面有一段代码说明方法,下载示例代码 17K。当然为了处理消息你应该在pWnd指明的窗口中对菜单命令消息进行映射。
CMenu menu;
menu.LoadMenu(IDR_POPUP);
CMenu* pM=menu.GetSubMenu(0);
CPoint pt;
GetCursorPos(&pt);
pM->TrackPopupMenu(TPM_LEFTALIGN,pt.x,pt.y,this);
另一种做法是通过CMenu::CreatePopupMenu()建立一个弹出菜单,然后使用TrackPopupMenu弹出菜单。使用CreatePopupMenu创建的菜单也可以将其作为一个弹出项添加另一个菜单中。下面的伪代码演示了如何创建一个弹出菜单并进行修改后弹出:
CMenu menu1,menu2;
menu1.CreatePopupMenu
menu1.InsertMenu(1)
menu1.InsertMenu(2)
menu1.InsertMenu(3)
menu2.CreatePopupMenu
menu2.AppendMenu(MF_POPUP,1,menu1.Detach()) 将弹出菜单加入 or InsertMenu...
menu2.InsertMenu("string desc");
menu.TrackPopupMenu(...)
当我们提到动态菜单的实现时,我们通常的做法是使用GetMenu() 函数获取一个Cmenu 类指针,然后调用CMenu 类方法AppendMenu, InsertMenu, ModifyMenu, RemoveMenu 等。本文介绍一种更加简洁的方法,它利用MFC 的消息映像机制及CCmdUI 类方法来实现。
---- 首先,我们简要说说VC 中MFC 的消息映像。每个Windows 程序员大概都对以前使用的窗口函数WindowProc 记忆犹新,当我们面对各种消息时,我们别无他方,只能使用庞大而机械的switch-case 语句来实现不同的分支选择。在VC5.0 中使用V4.2 版的MFC 基本类库,你将告别switch-case 语句,代之以透明的消息映像。要在一个类中使用消息映像,在类声明中,必须显式的加入宏DECLARE_MESSAGE_MAP:
class CMyClass: public CBaseClass
{
DECLARE_MESSAGE_MAP()
}
---- 在类实现中,必须使用两个宏BEGIN_MESSAGE_MAP 和END_MESSAGE_MAP,BEGIN_MESSAGE_MAP 带两个参数:当前类和直接父类:
---- BEGIN_MESSAGE_MAP(CMyClass, CBaseClass)
---- // 消息映像项
---- ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
---- // 消息映像项
---- END_MESSAGE_MAP()
---- 消息映像项使用下列基本语法:
---- ON_MessageName(ID, ClassMethod)
---- MessageName 是需要处理的消息,ID 是发送消息的标识符,而ClassMethod 为处理此消息的类方法名。MessageName 是MFC 预定义的,可分为以下三种:
---- 命令消息
---- 子窗口通知消息
---- Windows 消息
---- 共一百多个,用户不必记住它们,因为消息映像可以很简单的利用ClassWizard 加入。处理一个消息的类方法ClassMethod 必须在类定义中声明,且有实现代码。其原型为:
---- Afx_msg return_type ClassMethod(paras table)
---- 类CCmdUI 专门(且仅仅)与ON_UPDATE_COMMAND_UI 消息映像宏配套使用,用于管理菜单(还有工具栏按扭等)的实时状态,如是否变灰,是否加选中标记等。
---- ON_UPDATE_COMMAND_UI 消息映像宏原型为:
---- ON_UPDATE_COMMAND_UI(Menu_Item_ID, Menu_Proc)
---- ON_UPDATE_COMMAND_UI 消息映像宏将一个菜单项(命令项)和一个更新处理过程联结,从而在适当的时机自动调用此更新处理过程来完成对菜单项状态的更新。
---- Menu_Item_ID 为菜单项的ID 号,Menu_Proc 为此菜单项的更新处理函数,? 为:
---- afx_msg void Menu_Proc (CCmdUI* pCmdUI)
---- 它带有一个CCmdUI 类指针,使用它可调用CCmdUI 的类方法。与菜单有关的类方法有:
Enable(BOOL) 使菜单项有效或无效
SetText(LPCTSTR) 设置菜单项的文本
SetCheck(int) 加上或去掉选中标记“X”
SetRadio(BOOL) 加上或去掉选中标记“.”
---- MenuProc 被调用的时机有以下几种情况:
---- 用鼠标选中包含该菜单项的菜单条
---- 用热键选中包含该菜单项的菜单条
---- 用快捷键选中与该菜单项在同一菜单条下的任一菜单项
---- 我们以下面菜单结构为例:
Test menu
Item One ID_ITEM_ONE Ctrl+1
Item Two ID_ITEM_TWO Ctrl+2
Popup Popup One ID_POPUP_ONE Ctrl+3
Popup Two ID_POPUP_TWO Ctrl+4
---- 当用鼠标左键点按Test menu 菜单条或按Alt+t 或按Ctrl+1/2/3/4 时,四个菜单项的更新处理过程MenuProc 都将被调用。
---- 当我们考察上面这个具有嵌套结构的菜单时,我们面临这样一个问题:菜单项Item One/Item Two 的更新函数和Popup One/Popup Two 的更新函数形式上是否一致?当Popup One 和Popup Two 都变灰时Popup 是否自动变灰?
---- 根据MFC 的内部机制,仅仅弹出菜单的第一项应附加一些代码,其余项的形式基本是一致的。也就是说在上例中,除菜单项Popup One 外,其他菜单项更新函数的代码基本一致,即根据条件,简单调用CCmdUI 类方法即可。菜单项Popup One 由于是弹出式菜单Popup 的第一项,它的更新函数在以下两种情况下都会被调用:
---- 当弹出式菜单(Popup)的菜单项(Popup One 和Popup Two)要被绘出时
---- 当此弹出式菜单即Popup 本身要被绘出时
---- 第一种情况很好理解,正如我们选中Test menu 而Item One 和Item Two 的更新函数会自动执行一样。第二种情况其实也很自然,因为Popup 和Item One/Item Two 不一样,它没有ID 号,不能添加消息映像项,那么它的状态如何更新呢?于是它的第一项的更新函数被调用,为了区分是不同的调用,它将CCmdUI 的类成员变量m_pSubMenu 设置为不同的值。在第一种情况下,m_pSubMenu 等于NULL, 第二种情况下,m_pSubMenu 不等于NULL。
---- 以下我们给出一个实际的编程范例。由于篇幅关系,我们仅仅给出一些关键的语句,其余的则一并略去。
---- 在头文件的类声明中:
BOOL m_bItemOne, m_bItemTwo, m_bPopupOne, m_bPopupTwo;
//用于决定各个菜单项的状态
protected:
afx_msg void OnUpdateMenuitemOne(CCmdUI* pCmdUI);
afx_msg void OnUpdateMenuitemTwo(CCmdUI* pCmdUI);
afx_msg void OnUpdatePopupOne(CCmdUI* pCmdUI);
afx_msg void OnUpdatePopupTwo(CCmdUI* pCmdUI);
//各菜单项的更新函数
DECLARE_MESSAGE_MAP()
在源文件中:
BEGIN_MESSAGE_MAP(CMyDoc, CDocument)
ON_UPDATE_COMMAND_UI (ID_ITEM_ONE,
OnUpdateMenuitemOne)
ON_UPDATE_COMMAND_UI (ID_ITEM_TWO,
OnUpdateMenuitemTwo)
ON_UPDATE_COMMAND_UI (ID_POPUP_ONE,
OnUpdatePopupOne)
ON_UPDATE_COMMAND_UI (ID_ POPUP_TWO,
OnUpdatePopupTwo)
END_MESSAGE_MAP()
void CMyApp::OnUpdatetMenuitemOne (CCmdUI* pCmdUI)
{
pCmdUI->Enable(m_bItemOne);
if(m_bItemOne) pCmdUI->SetText("Item One");
else pCmdUI->SetText("Item One is now disabled");
}
void CMyApp::OnUpdatetMenuitemTwo (CCmdUI* pCmdUI)
{
pCmdUI->Enable(m_bItemTwo);
if(m_bItemTwo) pCmdUI->SetText("Item Two");
else pCmdUI->SetText("Item Two is now disabled");
}
void CMyApp::OnUpdatePopupOne(CCmdUI* pCmdUI)
{
if (pCmdUI->m_pSubMenu != NULL)
{
BOOL b_Popup = m_bPopupOne || m_bPopupTwo;
pCmdUI->m_pMenu->EnableMenuItem(pCmdUI->m_nIndex,
MF_BYPOSITION |
(bEnable ? MF_ENABLED :
(MF_DISABLED | MF_GRAYED)));
return;
}
pCmdUI->Enable(m_bPopupOne);
}
void CMyApp::OnUpdatePopupTwo(CCmdUI* pCmdUI)
{
pCmdUI->Enable(m_bPopupTwo);
}
(右键)菜单相关
对话框void Panel::OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu) { CDialog::OnInitMenuPopup(pPopupMenu, nIndex, bSysMenu); CCmdUI CmdUI; for(UINT Idx = 0;Idx < pPopupMenu->GetMenuItemCount();Idx++) { CmdUI.m_nID = pPopupMenu->GetMenuItemID(Idx); CmdUI.m_nIndex = Idx; CmdUI.m_nIndexMax = pPopupMenu->GetMenuItemCount(); CmdUI.m_pMenu = pPopupMenu; CmdUI.DoUpdate(this,FALSE); } } 利用菜单接受用户命令是一中很简单的交互方法,同时也是一种很有效的方法。通常菜单作为一中资源存储在文件中,因此我们可以在设计时就利用资源编辑器设计好一个菜单。关于使用VC设计菜单我就不再多讲了,但你在编写菜单时应该尽量在属性对话框的底部提示(Prompt)处输入文字,这虽然不是必要的,但MFC在有状态栏和工具条的情况下会使用该文字,文字的格式为“状态栏出说明\n工具条提示”。图33_g1 我们要面临的任务是如何知道用户何时选择了菜单,他选的是什么菜单项。当用户选择了一个有效的菜单项时系统会向应用发送一个WM_COMMAND消息,在消息的参数中表明来源。在MFC中我们只需要进行一次映射,将某一菜单ID映射到一处理函数,图33_g2。在这里我们在CView的派生类中处理菜单消息,同时我对同一ID设置两个消息映射,接下来将这两种映射的作用。 ON_COMMAND 映射的作用为在用户选择该菜单时调用指定的处理函数。如:ON_COMMAND(IDM_COMMAND1, OnCommand1)会使菜单被选择时调用OnCommand1成员函数。 ON_UPDATE_COMMAND_UI(IDM_COMMAND1, OnUpdateCommand1) 映射的作用是在菜单被显示时通过调用指定的函数来进行确定其状态。在这个处理函数中你可以设置菜单的允许/禁止状态,其显示字符串是什么,是否在前面打钩。函数的参数为CCmdUI* pCmdUI,CCmdUI是MFC专门为更新命令提供的一个类,你可以调用 Enable 设置允许/禁止状态 SetCheck 设置是否在前面打钩 SetText 设置文字 下面我讲解一个例子:我在CView派生类中有一个变量m_fSelected,并且在视中处理两个菜单的消息,当IDM_COMMAND1被选时,对m_fSelected进行逻辑非操作,当IDM_COMMAND2被选中时出一提示;同时IDM_COMMAND1根据m_fSelected决定菜单显示的文字和是否在前面打上检查符号,IDM_COMMAND2根据m_fSelected的值决定菜单的允许/禁止状态。下面是代码和说明:下载示例代码 17K void CMenuDView::OnCommand1() { m_fSelected=!m_fSelected; TRACE("command1 selected\n"); } void CMenuDView::OnUpdateCommand1(CCmdUI* pCmdUI) { pCmdUI->SetCheck(m_fSelected);//决定检查状态 pCmdUI->SetText(m_fSelected?"当前被选中":"当前未被选中");//决定所显示的文字 } void CMenuDView::OnUpdateCommand2(CCmdUI* pCmdUI) {//决定是否为允许 pCmdUI->Enable(m_fSelected); } void CMenuDView::OnCommand2() {//选中时给出提示 AfxMessageBox("你选了command2"); } 接下来再讲一些通过代码操纵菜单的方法,在MFC中有一个类CMenu用来处理和菜单有关的功能。在生成一个CMenu对象时你需要从资源中装如菜单,通过调用BOOL CMenu:oadMenu( UINT nIDResource )进行装入,然后你就可以对菜单进行动态的修改,所涉及到的函数有: CMenu* GetSubMenu( int nPos ) 一位置得到子菜单的指针,因为一个CMenu对象只能表示一个弹出菜单,如果菜单中的某一项也为弹出菜单,就需要通过该函数获取指针。 BOOL AppendMenu( UINT nFlags, UINT nIDNewItem = 0, LPCTSTR lpszNewItem = NULL ) 在末尾添加一项,nFlag为MF_SEPARATOR表示增加一个分隔条,这样其他两个参数将会被忽略;为MF_STRING表示添加一个菜单项uIDNewItem为该菜单的ID命令值;为MF_POPUP表示添加一个弹出菜单项,这时uIDNewItem为另一菜单的句柄HMENU。lpszNewItem为菜单文字说明。 BOOL InsertMenu( UINT nPosition, UINT nFlags, UINT nIDNewItem = 0, LPCTSTR lpszNewItem = NULL )用于在指定位置插入一菜单,位置由变量nPosition指明。如果nFlags包含MF_BYPOSITION则表明插入在nPosition位置,如果包含MF_BYCOMMAND表示插入在命令ID为nPosition的菜单处。 BOOL ModifyMenu( UINT nPosition, UINT nFlags, UINT nIDNewItem = 0, LPCTSTR lpszNewItem = NULL )用于修改某一位置的菜单,如果nFlags包含MF_BYPOSITION则表明修改nPosition位置的菜单,如果包含MF_BYCOMMAND表示修改命令ID为nPosition处的菜单。 BOOL RemoveMenu( UINT nPosition, UINT nFlags )用于删除某一位置的菜单。如果nFlags包含MF_BYPOSITION则表明删除nPosition位置的菜单,如果包含MF_BYCOMMAND表示删除命令ID为nPosition处的菜单。 BOOL AppendMenu( UINT nFlags, UINT nIDNewItem, const CBitmap* pBmp ) 和 BOOL InsertMenu( UINT nPosition, UINT nFlags, UINT nIDNewItem, const CBitmap* pBmp )可以添加一位图菜单,但这样的菜单在选中时只是反色显示,并不美观。(关于使用自绘OwnerDraw菜单请参考我翻译的一篇文章自绘菜单类) 视图中是没有菜单的,在框架窗口中才有,所以只有用AfxGetApp()->m_pMainWnd->GetMenu()才能得到应用的菜单指针。 最后我讲一下如何在程序中弹出一个菜单,你必须先装入一个菜单资源,你必需得到一个弹出菜单的指针然后调用BOOL TrackPopupMenu( UINT nFlags, int x, int y, CWnd* pWnd, LPCRECT lpRect = NULL )弹出菜单,你需要指定(x,y)为菜单弹出的位置,pWnd为接收命令消息的窗口指针。下面有一段代码说明方法,下载示例代码 17K。当然为了处理消息你应该在pWnd指明的窗口中对菜单命令消息进行映射。 CMenu menu; menu.LoadMenu(IDR_POPUP); CMenu* pM=menu.GetSubMenu(0); CPoint pt; GetCursorPos(&pt); pM->TrackPopupMenu(TPM_LEFTALIGN,pt.x,pt.y,this); 另一种做法是通过CMenu::CreatePopupMenu()建立一个弹出菜单,然后使用TrackPopupMenu弹出菜单。使用CreatePopupMenu创建的菜单也可以将其作为一个弹出项添加另一个菜单中。下面的伪代码演示了如何创建一个弹出菜单并进行修改后弹出: CMenu menu1,menu2; menu1.CreatePopupMenu menu1.InsertMenu(1) menu1.InsertMenu(2) menu1.InsertMenu(3) menu2.CreatePopupMenu menu2.AppendMenu(MF_POPUP,1,menu1.Detach()) 将弹出菜单加入 or InsertMenu... menu2.InsertMenu("string desc"); menu.TrackPopupMenu(...) 当我们提到动态菜单的实现时,我们通常的做法是使用GetMenu() 函数获取一个Cmenu 类指针,然后调用CMenu 类方法AppendMenu, InsertMenu, ModifyMenu, RemoveMenu 等。本文介绍一种更加简洁的方法,它利用MFC 的消息映像机制及CCmdUI 类方法来实现。 ---- 首先,我们简要说说VC 中MFC 的消息映像。每个Windows 程序员大概都对以前使用的窗口函数WindowProc 记忆犹新,当我们面对各种消息时,我们别无他方,只能使用庞大而机械的switch-case 语句来实现不同的分支选择。在VC5.0 中使用V4.2 版的MFC 基本类库,你将告别switch-case 语句,代之以透明的消息映像。要在一个类中使用消息映像,在类声明中,必须显式的加入宏DECLARE_MESSAGE_MAP: class CMyClass: public CBaseClass { DECLARE_MESSAGE_MAP() } ---- 在类实现中,必须使用两个宏BEGIN_MESSAGE_MAP 和END_MESSAGE_MAP,BEGIN_MESSAGE_MAP 带两个参数:当前类和直接父类: ---- BEGIN_MESSAGE_MAP(CMyClass, CBaseClass) ---- // 消息映像项 ---- ON_COMMAND(ID_APP_ABOUT, OnAppAbout) ---- // 消息映像项 ---- END_MESSAGE_MAP() ---- 消息映像项使用下列基本语法: ---- ON_MessageName(ID, ClassMethod) ---- MessageName 是需要处理的消息,ID 是发送消息的标识符,而ClassMethod 为处理此消息的类方法名。MessageName 是MFC 预定义的,可分为以下三种: ---- 命令消息 ---- 子窗口通知消息 ---- Windows 消息 ---- 共一百多个,用户不必记住它们,因为消息映像可以很简单的利用ClassWizard 加入。处理一个消息的类方法ClassMethod 必须在类定义中声明,且有实现代码。其原型为: ---- Afx_msg return_type ClassMethod(paras table) ---- 类CCmdUI 专门(且仅仅)与ON_UPDATE_COMMAND_UI 消息映像宏配套使用,用于管理菜单(还有工具栏按扭等)的实时状态,如是否变灰,是否加选中标记等。 ---- ON_UPDATE_COMMAND_UI 消息映像宏原型为: ---- ON_UPDATE_COMMAND_UI(Menu_Item_ID, Menu_Proc) ---- ON_UPDATE_COMMAND_UI 消息映像宏将一个菜单项(命令项)和一个更新处理过程联结,从而在适当的时机自动调用此更新处理过程来完成对菜单项状态的更新。 ---- Menu_Item_ID 为菜单项的ID 号,Menu_Proc 为此菜单项的更新处理函数,? 为: ---- afx_msg void Menu_Proc (CCmdUI* pCmdUI) ---- 它带有一个CCmdUI 类指针,使用它可调用CCmdUI 的类方法。与菜单有关的类方法有: Enable(BOOL) 使菜单项有效或无效 SetText(LPCTSTR) 设置菜单项的文本 SetCheck(int) 加上或去掉选中标记“X” SetRadio(BOOL) 加上或去掉选中标记“.” ---- MenuProc 被调用的时机有以下几种情况: ---- 用鼠标选中包含该菜单项的菜单条 ---- 用热键选中包含该菜单项的菜单条 ---- 用快捷键选中与该菜单项在同一菜单条下的任一菜单项 ---- 我们以下面菜单结构为例: Test menu Item One ID_ITEM_ONE Ctrl+1 Item Two ID_ITEM_TWO Ctrl+2 Popup Popup One ID_POPUP_ONE Ctrl+3 Popup Two ID_POPUP_TWO Ctrl+4 ---- 当用鼠标左键点按Test menu 菜单条或按Alt+t 或按Ctrl+1/2/3/4 时,四个菜单项的更新处理过程MenuProc 都将被调用。 ---- 当我们考察上面这个具有嵌套结构的菜单时,我们面临这样一个问题:菜单项Item One/Item Two 的更新函数和Popup One/Popup Two 的更新函数形式上是否一致?当Popup One 和Popup Two 都变灰时Popup 是否自动变灰? ---- 根据MFC 的内部机制,仅仅弹出菜单的第一项应附加一些代码,其余项的形式基本是一致的。也就是说在上例中,除菜单项Popup One 外,其他菜单项更新函数的代码基本一致,即根据条件,简单调用CCmdUI 类方法即可。菜单项Popup One 由于是弹出式菜单Popup 的第一项,它的更新函数在以下两种情况下都会被调用: ---- 当弹出式菜单(Popup)的菜单项(Popup One 和Popup Two)要被绘出时 ---- 当此弹出式菜单即Popup 本身要被绘出时 ---- 第一种情况很好理解,正如我们选中Test menu 而Item One 和Item Two 的更新函数会自动执行一样。第二种情况其实也很自然,因为Popup 和Item One/Item Two 不一样,它没有ID 号,不能添加消息映像项,那么它的状态如何更新呢?于是它的第一项的更新函数被调用,为了区分是不同的调用,它将CCmdUI 的类成员变量m_pSubMenu 设置为不同的值。在第一种情况下,m_pSubMenu 等于NULL, 第二种情况下,m_pSubMenu 不等于NULL。 ---- 以下我们给出一个实际的编程范例。由于篇幅关系,我们仅仅给出一些关键的语句,其余的则一并略去。 ---- 在头文件的类声明中: BOOL m_bItemOne, m_bItemTwo, m_bPopupOne, m_bPopupTwo; //用于决定各个菜单项的状态 protected: afx_msg void OnUpdateMenuitemOne(CCmdUI* pCmdUI); afx_msg void OnUpdateMenuitemTwo(CCmdUI* pCmdUI); afx_msg void OnUpdatePopupOne(CCmdUI* pCmdUI); afx_msg void OnUpdatePopupTwo(CCmdUI* pCmdUI); //各菜单项的更新函数 DECLARE_MESSAGE_MAP() 在源文件中: BEGIN_MESSAGE_MAP(CMyDoc, CDocument) ON_UPDATE_COMMAND_UI (ID_ITEM_ONE, OnUpdateMenuitemOne) ON_UPDATE_COMMAND_UI (ID_ITEM_TWO, OnUpdateMenuitemTwo) ON_UPDATE_COMMAND_UI (ID_POPUP_ONE, OnUpdatePopupOne) ON_UPDATE_COMMAND_UI (ID_ POPUP_TWO, OnUpdatePopupTwo) END_MESSAGE_MAP() void CMyApp::OnUpdatetMenuitemOne (CCmdUI* pCmdUI) { pCmdUI->Enable(m_bItemOne); if(m_bItemOne) pCmdUI->SetText("Item One"); else pCmdUI->SetText("Item One is now disabled"); } void CMyApp::OnUpdatetMenuitemTwo (CCmdUI* pCmdUI) { pCmdUI->Enable(m_bItemTwo); if(m_bItemTwo) pCmdUI->SetText("Item Two"); else pCmdUI->SetText("Item Two is now disabled"); } void CMyApp::OnUpdatePopupOne(CCmdUI* pCmdUI) { if (pCmdUI->m_pSubMenu != NULL) { BOOL b_Popup = m_bPopupOne || m_bPopupTwo; pCmdUI->m_pMenu->EnableMenuItem(pCmdUI->m_nIndex, MF_BYPOSITION | (bEnable ? MF_ENABLED : (MF_DISABLED | MF_GRAYED))); return; } pCmdUI->Enable(m_bPopupOne); } void CMyApp::OnUpdatePopupTwo(CCmdUI* pCmdUI) { pCmdUI->Enable(m_bPopupTwo); } |
发表评论
-
VC获取系统时间、程序运行时间
2011-03-28 20:26 1572VC获取系统时间、程序运行时间关键词: VC 系统时间 1 ... -
MFC CListCtrl 获取行信息
2011-03-28 17:43 2606int nItem = m_list_friend- ... -
VC CListCtrl 图标不显示的问题
2011-03-28 14:41 2538VC CListCtrl 图标不显示的问题 1。没有将C ... -
CImageList 使用指南
2011-03-27 22:05 13031.综述在MFC中CImageList类封装了图像列表控件的功 ... -
CDialog::OnInitDialog() ----转
2011-03-27 20:13 2066BOOL CmapfileDlg::OnInitDialog( ... -
MFC 添加对话框背景图片
2011-03-27 17:09 9755先载入一张图片,ID为ID ... -
MFC 给对话框添加背景色
2011-03-27 16:54 21501. 重载OnCtlColor (CDC* pD ... -
MFC 画线的几种方式
2011-03-24 22:07 17917一.画鼠标按下到弹起之间的直线 1.创建 CView 的私 ... -
关于UNICODE下SKIN++的使用
2011-03-21 17:43 1543SKIN++使用起来应该说是比较方便的。但,官方说法,只有 ... -
判断控件是否已经被创建
2011-03-20 20:08 1350// Resize the edit control cont ... -
MFC 获取对话框控件
2011-03-20 19:49 1330CButton* btn = (CButton*)Get ... -
MFC 限制对话框,窗口大小
2011-03-20 19:08 54881.在类的头文件中加入函数申明 (.h文件) ... -
PROGRESS控件(CProgressCtrl类)
2011-03-20 17:41 3318CProgressCtrl *lpctrlPr = (CP ... -
mfc 关闭窗口
2011-03-20 15:28 1375退出程序用 AfxGetMainWnd()->SendM ... -
edit 设置enable
2011-03-20 13:42 15301. As you can disable other c ... -
mfc radio button 设置默认选中
2011-03-19 17:45 10998我们假设有两个RADIO控件:IDC_RADIO_SINGLE ... -
picture control 载入图片
2011-03-19 17:21 1307HBITMAP hBitmap; CStatic *pSt ... -
SysLink 用法
2011-03-19 13:35 1477SysLink SysLink.SetWindowText( ... -
窗口破坏过程与Windows消息循环
2011-03-19 03:20 2025从用户单击关闭按钮( ... -
VC++ UDP通信程序
2011-03-08 19:05 4045UDP的服务器端:(UdpSrv.cpp) ...
相关推荐
WPF 与 WinForm 调用系统右键菜单/资源管理器右键菜单/桌面右键菜单示例 内含 WPF 与 WinForm 示例
右键菜单案例、BootStrap样式、右键菜单案例、BootStrap样式、右键菜单案例、BootStrap样式、右键菜单案例、BootStrap样式、右键菜单案例、BootStrap样式、右键菜单案例、BootStrap样式、右键菜单案例、BootStrap...
Web右键菜单 很不错的右键菜单 Web右键菜单 很不错的右键菜单
动态及静态添加右键菜单策略,含有两个工程,一个是动态添加右键菜单的策略,一个是静态添加右键菜单的策略。
flex添加右键菜单实例。很经典的实例。
网页添加右键菜单.zip网页添加右键菜单.zip网页添加右键菜单.zip网页添加右键菜单.zip
一键清除所有多余的桌面右键菜单 一键清除所有多余的桌面右键菜单
注册表修改右键菜单注册表修改右键菜单注册表修改右键菜单
echarts 右键菜单实例,不修改源码
右键管理员身份执行,一键去除Intel显卡桌面右键菜单
3种不同的ContextMenu右键菜单演示.,3种不同的ContextMenu右键菜单演示.3种不同的ContextMenu右键菜单演示.
jQuery实现右键菜单 jQuery实现右键菜单 jQuery实现右键菜单 jQuery实现右键菜单 jQuery实现右键菜单
网上有不少添加UtraEdit右键菜单的方法,集中方法,本人尝试过好用,版本15.20 但有一种修改注册表的方法,在Win7下尝试不成功。 本人用的是WIN7 64位旗舰版,32位同理。 本人感觉,还是在UE软件中找找比较好。 终于...
联想工程师专用小工具 修复右键菜单的新建文件夹V4.04.1联想工程师专用小工具 修复右键菜单的新建文件夹V4.04.1联想工程师专用小工具 修复右键菜单的新建文件夹V4.04.1联想工程师专用小工具 修复右键菜单的新建...
易语言源码易语言编辑框增加右键菜单项源码.rar 易语言源码易语言编辑框增加右键菜单项源码.rar 易语言源码易语言编辑框增加右键菜单项源码.rar 易语言源码易语言编辑框增加右键菜单项源码.rar 易语言源码易语言...
联想工程师专用小工具 修复右键菜单的新建文件夹V4.17.1联想工程师专用小工具 修复右键菜单的新建文件夹V4.17.1联想工程师专用小工具 修复右键菜单的新建文件夹V4.17.1联想工程师专用小工具 修复右键菜单的新建...
扩展openalayers 自定义右键菜单开发,样式可以自行覆盖调整
该文件里有2个压缩包:BC3ShellExFix.zip + BC4ShellExFix.zip,分别是Beyond compare3和Beyond compare4的右键菜单修复方法,具体如下: 这里介绍Beyond compare4,在32位PC机上的右键菜单修复方法: 1)先把BC4...
本例用C++实现了在系统右键菜单中添加自定义菜单项和删除该自定义菜单项,内附源代码和可执行的release的exe文件。
C#在gridview添加右键菜单(C#源码) C#在gridview添加右键菜单(C#源码) C#在gridview添加右键菜单(C#源码) C#在gridview添加右键菜单(C#源码) C#在gridview添加右键菜单(C#源码) C#在gridview添加右键菜单...