孙鑫VC++视频学习笔记(第六课 菜单的工作原理及编写控件)
2011-12-09 16:01
417 查看
消息分类
1.标准消息:
除WM_COMMAND之外,所有以 WM_ 开头的消息。
从CWnd派生的类,都可以接收到这类消息
2.命令消息
来自菜单、加速键或工具栏按钮的消息。这类消息都以WM_COMMAND呈现。在MFC中,通过菜单项的标识(ID)来区分不同的命令消息;在SDK中通过消息的wParam参数识别
从CCmdTarget派生的类,都可以接收到这类消息。
3通告消息
由控件产生的消息,例如,按钮的单击,列表框的选择等均产生此类消息,为的是想器父窗口(通常是对话框)通知事件的发生。这类消息也是以WM_COMMAND形式呈现
从CCmdTarget派生的类,都可以接收到这类消息
MFC类的结构层次图
菜单的索引是从0开始,子菜单中的菜单项之间的分割符也算一位。
CWnd::GetMenu()
CMenu* GetMenu() const; 获得菜单栏的指针
CMenu::GetSubMenu() 获得一个菜单项的指针
CMenu* GetSubMenu(int nPos) const
CMenu::CheckMenuItem() 在一个菜单项打一个标记
UINT CheckMenuItem(UINT nIDCheckItem, UINT nCheck);
当 nCheck=MF_BYCOMMAND
第一个参数代表的是菜单项的ID号(ID_
当 nCheck=MF_BYPOSITION
第一个参数代表的是菜单项的索引号(0,1,2...)
示例程序
示例程序
可用
将禁用某一个菜单项项,使其变灰
查看MSDN
// The code fragment below shows how to disable (and gray out) the File\New menu item.//NOTE: m_bAutoMenuEnable is set to FALSE in the constructor of CMainFrame so no ON_UPDATE_COMMAND_UI or ON_COMMAND handlers are needed, and CMenu::EnableMenuItem()
will work as expected.
在类的构造函数中可以将m_bAutoMenuEnable=FALSE
加载自己的菜单资源
命令更新
菜单项状态的维护是依赖与CN_UPDATE_COMMAND_UI消息,谁捕获CN_UPDATE_COMMAND_UI消息,MFC就在其中创建一个CCmdUI对象。我们通过手工或利用建立类向导ClassWizard在消息映射中添加ON_UPDATE_COMMAND_UI宏来不活CN_UPDATE_COMMAND_UI消息。
在后台所做的工作是:操作系统发出WM_INITMENUPOPUP消息,然后由MFC的基类CFrameWnd接管。它创建一个CCmdUI对象,并与第一个菜单项相关联,调用对象的一个成员函数DoUpdate()。这个函数发出CN_UPDATE_COMMAND_UI消息,这条消息指向CCmdUI对象的指针。同一个CCmdUI对象就设置为与第二个菜单项相关联,这样顺序进行,直到完成所有菜单项。
更新命令UI处理程序仅应用于弹出式菜单项上的项目,不能应用与永久显示的顶级菜单项目
添加右键弹出菜单功能
VC6编辑器
工程-》添加到工程-》Components and Controls Gallery-》Visual C++ Components-》Pop-up Menu
提示增加到哪个类当中,不要选择框架类,框架类接受不到鼠标消息,可以增加到View类当中!
MFC会在我们的工程当中增加一个菜单资源,和View类中添加一个OnContextMenu函数
手动添加
调用TrackPopupMenu
示例代码
利用ClassWizard添加右键鼠标消息
动态添加菜单
我们可以手动添加对菜单项的响应,一可以通过ClassWizard来添加。
课程实验设计 -------电话本程序
CString m_strLine;
int m_nIndex;
CStringArray m_strArray;
CMenu m_menu;
void CMenu2View::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: Add your message handler code here and/or call default
CClientDC dc(this);
if(0x0d==nChar)
{
if(0==++m_nIndex)
{
m_menu.CreatePopupMenu();
GetParent()->GetMenu()->AppendMenu(MF_POPUP,
(UINT)m_menu.m_hMenu,_T("PhonBook"));//在View类中获得框架类的指针使用GetParent
在在框架类CMainFrame中利用ClassWizard添加虚函数OnCommand()来截获消息并处理
BOOL CMainFrame::OnCommand(WPARAM wParam, LPARAM lParam)
{
// TODO: Add your specialized code here and/or call the base class
int MenuCmdID=LOWORD(wParam); //获得低字节
CMenu2View *pView=(CMenu2View*)GetActiveView();//获得当前视类的指针,从得到我们所需要的其中的m_strArray数据
if(MenuCmdID>=IDM_PHONE1 && MenuCmdID<=IDM_PHONE1+pView->m_strArray.GetSize());
{
//MessageBox("xiaodou");
CClientDC dc(pView);
dc.TextOut(0,0,pView->m_strArray.GetAt(MenuCmdID-IDM_PHONE1));
return TRUE;
}
return CFrameWnd::OnCommand(wParam, lParam);
}
详细程序略
1.标准消息:
除WM_COMMAND之外,所有以 WM_ 开头的消息。
从CWnd派生的类,都可以接收到这类消息
2.命令消息
来自菜单、加速键或工具栏按钮的消息。这类消息都以WM_COMMAND呈现。在MFC中,通过菜单项的标识(ID)来区分不同的命令消息;在SDK中通过消息的wParam参数识别
从CCmdTarget派生的类,都可以接收到这类消息。
3通告消息
由控件产生的消息,例如,按钮的单击,列表框的选择等均产生此类消息,为的是想器父窗口(通常是对话框)通知事件的发生。这类消息也是以WM_COMMAND形式呈现
从CCmdTarget派生的类,都可以接收到这类消息
MFC类的结构层次图
菜单的索引是从0开始,子菜单中的菜单项之间的分割符也算一位。
CWnd::GetMenu()
CMenu* GetMenu() const; 获得菜单栏的指针
CMenu::GetSubMenu() 获得一个菜单项的指针
CMenu* GetSubMenu(int nPos) const
CMenu::CheckMenuItem() 在一个菜单项打一个标记
UINT CheckMenuItem(UINT nIDCheckItem, UINT nCheck);
当 nCheck=MF_BYCOMMAND
第一个参数代表的是菜单项的ID号(ID_
当 nCheck=MF_BYPOSITION
第一个参数代表的是菜单项的索引号(0,1,2...)
示例程序
GetMenu()->GetSubMenu(0)->CheckMenuItem(0,MF_BYPOSITION | MF_CHECKED); GetMenu()->GetSubMenu(0)->CheckMenuItem(ID_FILE_NEW,MF_BYCOMMAND | MF_CHECKED);获得一个子菜单指针,再获取索引号为0的菜单项指针 ,标记索引号为0 (ID号为ID_FILE_NEW)的菜单项
GetMenu()->GetSubMenu(0)->SetDefaultItem(1,TRUE); GetMenu()->GetSubMenu(0)->SetDefaultItem(ID_FILE_OPEN);//第二参数缺省值为FALSE CMenu::SetMenuItemBitmaps BOOL SetMenuItemBitmaps( UINT nPosition, UINT nFlags,//这两个参数与前面的一样 const CBitmap* pBmpUnchecked,//没有选中用这个位图 const CBitmap* pBmpChecked //选中就用这个位图 );创建一个图形标识菜单,在资源视图中添加一个位图(IDB_BITMAP)
示例程序
CBitmap m_bitmap;//用建立类向导ClassWizard添加类的成员变量 m_bitmap.LoadBitmap(IDB_BITMAP); GetMenu()->GetSubMenu(0)->SetMenuItemBitmaps(0,MF_BYPOSITION,&m_bitmap,&m_bitmap);//当背景色为白色的位图可能看不到效果,位图尺寸太大无法显示完整
可用
CString str; str.Format("x=%d,y=%d",::GetSystemMetrics(SM_CXMENUCHECK), ::GetSystemMetrics(SM_CYMENUCHECK);获得缺省的标识位图的尺寸大小(单位:像素)
将禁用某一个菜单项项,使其变灰
GetMenu()->GetSubMenu(0)->EnableMenuItem(1,MF_POSITION | MF_DISABLED | MF_GRAYED);//程序效果无效,结果还是可以打开该菜单项
查看MSDN
// The code fragment below shows how to disable (and gray out) the File\New menu item.//NOTE: m_bAutoMenuEnable is set to FALSE in the constructor of CMainFrame so no ON_UPDATE_COMMAND_UI or ON_COMMAND handlers are needed, and CMenu::EnableMenuItem()
will work as expected.
在类的构造函数中可以将m_bAutoMenuEnable=FALSE
加载自己的菜单资源
SetMenu(NULL); CMenu menu; menu.LoadMenu(IDR_MAINFRAME); SetMenu(&menu); menu.Detach();//当menu为类的成员变量时可不用,当为本地变量时要调用,不然会发生错误
命令更新
菜单项状态的维护是依赖与CN_UPDATE_COMMAND_UI消息,谁捕获CN_UPDATE_COMMAND_UI消息,MFC就在其中创建一个CCmdUI对象。我们通过手工或利用建立类向导ClassWizard在消息映射中添加ON_UPDATE_COMMAND_UI宏来不活CN_UPDATE_COMMAND_UI消息。
在后台所做的工作是:操作系统发出WM_INITMENUPOPUP消息,然后由MFC的基类CFrameWnd接管。它创建一个CCmdUI对象,并与第一个菜单项相关联,调用对象的一个成员函数DoUpdate()。这个函数发出CN_UPDATE_COMMAND_UI消息,这条消息指向CCmdUI对象的指针。同一个CCmdUI对象就设置为与第二个菜单项相关联,这样顺序进行,直到完成所有菜单项。
更新命令UI处理程序仅应用于弹出式菜单项上的项目,不能应用与永久显示的顶级菜单项目
添加右键弹出菜单功能
VC6编辑器
工程-》添加到工程-》Components and Controls Gallery-》Visual C++ Components-》Pop-up Menu
提示增加到哪个类当中,不要选择框架类,框架类接受不到鼠标消息,可以增加到View类当中!
MFC会在我们的工程当中增加一个菜单资源,和View类中添加一个OnContextMenu函数
手动添加
调用TrackPopupMenu
CMenu::TrackPopupMenu
BOOL TrackPopupMenu( UINT nFlags, int x, int y, CWnd* pWnd, LPCRECT lpRect = 0 );
示例代码
利用ClassWizard添加右键鼠标消息
void CMenu1View::OnRButtonDown(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default CMenu menu; menu.LoadMenu(IDR_MENU1);//加载自定义的菜单资源 CMenu *pPopup=menu.GetSubMenu(0); //获得菜单项指针 ClientToScreen(&point);//转换point坐标,将客户区坐标转换为屏幕坐标 pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, GetParent()/*this*/);
//如果为this就表示该弹出窗口拥有者为View类,因此只能是View类为我们的弹出菜单中的菜单项进行命令响应
//如果想要框架类也能为该弹出猜中的菜单项进行命令响应,可以将最后一个参数this改为GetParent()获得框架类的指针 CView::OnRButtonDown(nFlags, point); }
动态添加菜单
CMenu::CreatePopupMenu 创建一个空的弹出菜单
CMenu::AppendMenu 添加一个新的菜单项
CMenu menu;
menu.CreatePopupMenu();
//GetMenu()->AppendMenu(MF_POPUP,(UINT)menu.m_hMenu,_T("WinSun"));
GetMenu()->InsertMenu(2,MF_BYPOSITION | MF_POPUP,(UINT)menu.m_hMenu,_T("WinSun"));
menu.AppendMenu(MF_STRING,111,_T("Hello"));
menu.AppendMenu(MF_STRING,112,_T("Weixin"));
menu.AppendMenu(MF_STRING,113,_T("My"));
menu.Detach();
GetMenu()->GetSubMenu(0)->AppendMenu(MF_STRING,114,_T("WELCOM")); GetMenu()->GetSubMenu(0)->InsertMenu(ID_FILE_OPEN,MF_BYCOMMAND | MF_STRING,115,_T("小豆"));//插入 GetMenu()->DeleteMenu(1,MF_BYPOSITION);//删除 GetMenu()->GetSubMenu(0)->DeleteMenu(2,MF_BYPOSITION);
我们可以手动添加对菜单项的响应,一可以通过ClassWizard来添加。
课程实验设计 -------电话本程序
CString m_strLine;
int m_nIndex;
CStringArray m_strArray;
CMenu m_menu;
void CMenu2View::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: Add your message handler code here and/or call default
CClientDC dc(this);
if(0x0d==nChar)
{
if(0==++m_nIndex)
{
m_menu.CreatePopupMenu();
GetParent()->GetMenu()->AppendMenu(MF_POPUP,
(UINT)m_menu.m_hMenu,_T("PhonBook"));//在View类中获得框架类的指针使用GetParent
GetParent()->DrawMenuBar();//马上更新菜单栏
} m_menu.AppendMenu(MF_STRING,IDM_PHONE1+m_nIndex,m_strLine.Left(m_strLine.Find(' '))); m_strArray.Add(m_strLine); m_strLine.Empty(); Invalidate();//缺省为TRUE,客户区更新 } else { m_strLine+=nChar; dc.TextOut(0,0,m_strLine); } CView::OnChar(nChar, nRepCnt, nFlags); }
在在框架类CMainFrame中利用ClassWizard添加虚函数OnCommand()来截获消息并处理
BOOL CMainFrame::OnCommand(WPARAM wParam, LPARAM lParam)
{
// TODO: Add your specialized code here and/or call the base class
int MenuCmdID=LOWORD(wParam); //获得低字节
CMenu2View *pView=(CMenu2View*)GetActiveView();//获得当前视类的指针,从得到我们所需要的其中的m_strArray数据
if(MenuCmdID>=IDM_PHONE1 && MenuCmdID<=IDM_PHONE1+pView->m_strArray.GetSize());
{
//MessageBox("xiaodou");
CClientDC dc(pView);
dc.TextOut(0,0,pView->m_strArray.GetAt(MenuCmdID-IDM_PHONE1));
return TRUE;
}
return CFrameWnd::OnCommand(wParam, lParam);
}
详细程序略
相关文章推荐
- 孙鑫vc++ 第六课 笔记 菜单的工作原理及编写应用
- 孙鑫VC++视频学习笔记之12:文件操作
- directshow学习笔记四-----视频预览(将预览视频播放到指定picture控件中,个人学习所用,仅供参考)
- Android 高仿 QQ5.0 侧滑菜单效果 自定义控件来袭【学习鸿洋_视频博客笔记总结】
- 孙鑫VC++视频学习笔记之13:文档与串行化
- 孙鑫VC++视频学习笔记之12:文件操作
- 分析集线器的工作原理--视频学习笔记
- 孙鑫VC++视频学习笔记之14:网络编程
- OpenCV学习笔记 利用MFC的Picture控件显示图像+播放视频和捕获摄像头画面 .
- 韩顺平PHP学习视频笔记整理006浮动窗口 表单及表单控件①
- 韩顺平_php从入门到精通_视频教程_第6讲_浮动窗口_表单及表单控件①_学习笔记_源代码图解_PPT文档整理
- 孙鑫VC++视频学习笔记之1: Windows程序内部运行机制
- 孙鑫老师教学视频学习笔记——单文档中菜单操作
- Qt视频学习笔记4(坐标系统 、内存回收、菜单栏、工具栏、核心控件和浮动窗口)
- directshow学习笔记三-----视频预览(还未播放到指定窗口或控件,个人学习所用,仅供参考)
- 学习 Mars 老师 Android 开发视频教程笔记之01_06 Android 常用控件
- OpenCV学习笔记(9)利用MFC的Picture控件显示图像+播放视频和捕获摄像头画面
- 孙鑫VC视频教程笔记之第六课“菜单”
- 孙鑫VC++视频学习笔记之4:文本编辑和字处理软件
- QT学习笔记之QT代码编写控件不显示的问题