分享
 
 
 

孙鑫VC视频教程笔记之---Lesson 6 菜单

王朝vc·作者佚名  2006-01-10
窄屏简体版  字體: |||超大  

CMenuApp 并不是从CWnd派生出来的,所以不能使用MessageBox函数。

但可以使用全局的MessageBox函数:AfxMessageBox函数

int AfxMessageBox(LPCTSTR lpszText,UINT nType,UINT nIDHelp);

对菜单项Test响应的顺序: View-Doc-MainFrame-App

消息的分类

标准消息 除WM_COMMAND之外,所有以WM_开头的消息。从CWnd派生的类,都可以接收到这类消息。

命令消息 来自菜单、加速键或工具栏按钮的消息。这类消息都以WM_COMMAND呈现。

在MFC中,通过菜单项的标识(ID)来区分不同的命令消息;

在SDK中,通过消息的wParam参数识别。从CCmdTarget派生的类,都可以接收到这类消息。

通告消息 由控件产生的消息,例如,按钮的单击,列表框的选择等均产生此类消息,

为的是向其父窗口(通常是对话框)通知事件的发生。

这类消息也是以WM_COMMAND形式呈现。从CCmdTarget派生的类,都可以接收到这类消息。

CWnd是由CCmdTarget派生

CWnd::GetMenu

CMenu* GetMenu()const;

CMenu封装了一些和菜单有关的操作,封装了windows的HMENU(菜单句柄)

CMenu::GetSubMenu

CMenu* GetSubMenu( int nPos) const; //获取子菜单

CMenu::CheckMenuItem

UINT CheckMenuItem( UINT nIDCheckItem, UINT nCheck);// Return the previous state of the item

CMenu::SetDefaultIte

//BOOL SetDefaultItem( UINT uItem, BOOL fByPos=FALSE) //设置缺省的菜单项

指定的缺省菜单项将会被加黑显示

CAUTION! 一个子菜单中,只能有一个缺省菜单项

CMenu::SetMenuItemBitmaps

//BOOL SetMenuItemBitmaps( UINT nPosition, UINT nFlags,

const CBitmaps* pBmpUnchecked, const CBitmaps* pBmpChecked)

创建图形标记菜单

获取图形标记菜单位图的大小:

int GetSystemMetrics( int nIndex)

nIndex: //system metric or configuration setting

SM_CXMENUCHECK //缺省的菜单标记位图的高度

SM_CYMENUCHECK //缺省的菜单标记位图的宽度

CString str;

str.Format("x=%d, y=%d",GetSystemMetrics(SM_CXMENUCHECK),

GetSystemMetrics(SM_CYMENUCHECK));

MessageBox(str);

//改变菜单项的状态

CMenu::EnableMenuItem

UINT EnableMenuItem( UINT nIDEnableItem, UINT nEnable );

CAUTION! 只有在CMainFrame的构造函数中将变量 m_bAutoMenuEnable=FALSE时,

EnableMenuItem函数才会起作用

m_bAutoMenuEnable=FALSE时MFC就不会使用他的命令更新机制去判断哪个菜单项能使用

哪个菜单项不能使用,此时这些操作都要由我们自己去完成

如何将整个菜单取消:

CWnd::SetMenu

//BOOL SetMenu( CMenu* pMenu);

SetMenu( NULL); //移走当前菜单

重新加载菜单:

CMenu menu; // 不能是局部对象

menu.LoadMenu( IDM_MAINFRAME /×菜单ID*/)//动态的更换菜单

SetMenu(&menu);

menu.Detach();//如果menu是局部对象,一定要调用Detach()函数,它将菜单的句柄和我们的C++对象断开,

这样当局部对象CMenu析构时,不会销毁我们的菜单

MFC对菜单项采用的命令更新机制:01:18:00

命令更新

菜单项状态的维护是依赖于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处理程序仅应用于弹出式菜单项上的项目,不能应用于永久显示的顶级菜单项目。

void CMainFrame::OnUpdateEditCut( CCmdUI* pCmdUI)

{

pCmdUI->Enable();//Enable()函数的缺省参数为 BOOL类型TRUE

}

工具栏上的图标,和它所对应的菜单项的ID号是一样的。所以当对菜单项DISABLE或者ENABLE时能够相应

的在工具栏上显现出来。

CAYTION!:如果在改变菜单项状态的过程中是用的菜单项ID号,则菜单项状态的改变能在工具栏上相应的

图标上显现出来,但如果使用的是菜单项的位置索引,则相应的状态不会在工具栏上显现出来。

这是因为工具栏上的图标和相应菜单项具有相同的ID号,但位置索引是不相同的。

实现右键弹出菜单的功能:

Project->Add To Project->Components and Controls->Visual C++ Components->Pop-up Menu

注意:应该把菜单加入CMenuView类

此时,会在CMenuView类中加入一个函数OnContextMenu( CWnd* , CPoint)

//CWnd::OnContextMenu

//afx_msg void OnContextMenu( CWnd* pWnd,CPoint pos)

//Called by framework when the user has clicked the right mouse button(right clicked)

//in the window.You can process(处理)this message by displaying a context menu using the

//TrackPopupMenu(用来显示弹出菜单)

CMenu:: TrackPopupMenu

//BOOL TrackPopupMenu( UINT nFlags, //弹出菜单相对于x的位置

int x, int y, //鼠标点击的位置坐标,注意这个位置坐标是相对于屏幕坐标

//而不是客户区坐标,使用是需要进行坐标转换

CWnd* pWnd, //菜单的拥有者

LPCRECT lpRect=NULL //指定一个矩形,当鼠标在矩形外点击时,菜单消失

//在矩形内点击时,弹出菜单不消失

);

坐标转换:

CWnd::ClientToScreen

void ClientToScreen( LPPOINT lpPoint) const;

void ClientToScreen( LPRECT lpRect) const;

为弹出菜单的“显示”菜单项,在CMenuView和CMainFrame类中分别加入命令捕获OnShow函数

选中“显示”项,发现只有CMenuView类对菜单命令进行捕获,原因是用TrackPopupMenu显示弹出

菜单时,指定了弹出菜单的拥有者窗口指针

即使将指针设置为父窗口指针,子窗口依然最先响应菜单命令,只有当子窗口不响应时,才交由父窗口响应

通过代码来动态添加菜单

CMenu::AppendMenu

//BOOL AppendMenu( UINT nFlags, UINT nIDNewItem=0, LPCTSTR lpszNewItem=NULL);

//BOOL AppendMenu( UINT nFlags, UINT nIDNewItem, const CBitmap* pBmp);

//可以将一个菜单或者一个菜单项添加到现有菜单的末尾

//nFlags: MF_STRING MF_POPUP MF_SEPARATOR

//nIDNewItem:当nFlags=MF_POPUP,则nIDNewItem为POPUP菜单的句柄

//当nFlags=MF_SEPARATOR,则nIDNewItem被Ignored

CMenu::CreatePopupMenu

//Creates an empty pop-up menu and attaches it to a CMenu object

//BOOL CreatePopupMenu()

插入菜单

CMenu::InsertMenu

//BOOL InsertMenu( UINT nPosition, UINT nFlags, UINT nIDNewItem=0,LPCTSTR lpszNewItem);

//BOOL InsertMenu( UINT nPosition, UINT nFlags, UINT nIDNewItem,const CBitmap* pBmp);

//nPosition的取值由nFlags来确定,如果nFlags=MF_BYPOSITION,则nPosition为位置所以号

//如果nFlags=MF_BYCOMMAND,则nPosition为菜单项ID号

//nIDNewItem:当nFlags=MF_POPUP,则nIDNewItem为POPUP菜单的句柄

//当nFlags=MF_SEPARATOR,则nIDNewItem被Ignored

删除子菜单

CMenu::DeleteMenu()

//BOOL DeleteMenu( UINT nPosition, UINT Flags); //删除一个指定的菜单项或弹出菜单

对动态创建的菜单项进行命令响应

头文件Resource.h定义了资源的ID

做一个菜单命令的命令响应函数,它的添加和消息响应函数时一样的,一共有三个步骤:

step1:首先在头文件中做命令响应函数的原型

//MainFrm.h

//protected:

//afx_msg void OnHello();

step2: 消息映射 //使用教程中的方法时,消息映射一定要放到注释宏的外面

//MainFrm.cpp

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)

//{{AFX_MSG_MAP(CMainFrame)

// NOTE - the ClassWizard will add and remove mapping macros here.

// DO NOT EDIT what you see in these blocks of generated code !

ON_WM_CREATE()

//}}AFX_MSG_MAP

ON_COMMAND(IDM_HELLO/*ID号*/,OnHello/*命令响应函数*/) //注意!不要加任何的标点符号

END_MESSAGE_MAP()

step3:命令响应函数的实现

//MainFrm.cpp

void CMainFrame::OnHello()

{

MessageBox("Hello!");

}

编写电话本程序

注:菜单栏是属于框架窗口的,在view类中调用GetMenu()是无法获得指向菜单的指针的,因为view窗口根本

没有菜单

对菜单栏进行重绘

CWnd::DrawMenuBar

void DrawMenuBar()

//Redraw the menu bar .If a menu bar is changed after windows has created the window,

//cal the function to draw the changed menu bar.

利用父窗口(框架窗口)调用DrawMenuBar

对窗口进行重绘

CWnd::Invalidate

//void Invalidate( BOOL bErase=TRUE)

CString的查找功能

CString::Find

int Find( TCHAR ch)const;

int Find( LPCTSTR lpszSub)const;

int Find( TCHAR ch, int nStart)const;

int Find( LPCTSTR pstr, int nStart)const;

Return Value

返回基于0的第一个匹配的字符(串)索引,如果找不到,返回-1

存储字符串集合类 CStringArray

CWnd::OnCommand

//virtual BOOL OnCommand( WPARAM wParam, LPARAM lParam) 虚函数

//The framework calls this member function when the user selects an item from a menu,when a

//child control sends a notification message(通告消息),or when an accelerator keystroke is

//translated

//OnCommand 处理消息映射

如何得到框架窗口下的视图窗口的指针:

CFrameWnd::GetActiveView

CView* GetActiveView() const;

Return Value

A point to the current CView.If there is no current view, returns NULL.

//获取当前视类的指针

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有