实验5菜单工具栏和状态栏Word下载.docx
《实验5菜单工具栏和状态栏Word下载.docx》由会员分享,可在线阅读,更多相关《实验5菜单工具栏和状态栏Word下载.docx(15页珍藏版)》请在冰点文库上搜索。
![实验5菜单工具栏和状态栏Word下载.docx](https://file1.bingdoc.com/fileroot1/2023-5/5/570f5f32-410c-4512-aced-f2a349e107f5/570f5f32-410c-4512-aced-f2a349e107f51.gif)
双击COMMAND弹出对话框,要求在该对话框中输入消息处理函数的名称,选择默认函数名,确定后,双击消息处理函数OnEllipse进行编辑(矩形同样进行编辑,消息处理函数为OnRectangle),代码如下:
intflag;
voidCEx61View:
:
OnEllipse()//椭圆画图
{flag=0;
//TODO:
Addyourcommandhandlercodehere
Invalidate();
UpdateWindow();
CDC*pDC=GetDC();
pDC->
Ellipse(100,100,200,200);
}
OnRectangle()//矩形画图
{flag=1;
//TODO:
Invalidate();
UpdateWindow();
CDC*pDC=GetDC();
pDC->
Rectangle(100,100,200,200);
(5)给“椭圆”和“矩形”子菜单添加UPDATE_COMMAND_UI消息,并在消息处理函数中实现在选中的子菜单项前打钩。
UPDATE_COMMAND_UI消息的添加和WM_COMMAND消息类似。
在上图中,在Messages中选择UPDATE_COMMAND_UI即可。
消息处理函数为:
VoidCE61View:
OnUpdateEllipse(CCmdUI*pCmdUI)
{
pCmdUI->
SetCheck(flag==0);
VoidCE61View:
OnUpdateRectangle(CCmdUI*pCmdUI)
SetCheck(flag==1);
例2.用上下文菜单实现例1的功能。
创建上下文菜单的步骤如下:
(1)创建一个新菜单资源。
用AppWizard创建一个基于MFC的SDI应用程序,工程名为ex62。
在工作区的ResourceView选项卡中,右击Menu文件夹,在弹出菜单中选择插入菜单便可创建一个新的菜单资源,其ID为IDR_MENU1。
右击IDR_MENU1,在弹出菜单中选择属性,修改其ID为IDR_POPMENU。
双击IDR_POPMENU资源进入编辑对话框,对弹出式菜单进行编辑,方法见例1,完成后的菜单资源如图:
(2)添加代码,实现鼠标右键单击时显示弹出式菜单。
在查看菜单项中选择建立类向导来添加右键单击弹出式菜单WM_CONTEXTMENU及消息处理函数,这时MFC会发现创建了一个新资源,将询问是否创建一个新类,取消后,弹出下图对话框,选择ID为CEx62View,Messages为WM_CONTEXTMENU,双击该消息或单击AddFunction按钮,将为该消息添加默认处理函数,单击EditCode按钮进入OnContextMenu()函数,对其进行编辑。
在相应的消息处理函数中添加代码如下:
voidCEx62View:
OnContextMenu(CWnd*pWnd,CPointpoint)
Addyourmessagehandlercodehere
CMenumenu;
menu.LoadMenu(IDR_POPMENU);
menu.GetSubMenu(0)->
TrackPopupMenu(TPM_LEFTALIGN|TPM_LEFTBUTTON,point.x,point.y,AfxGetMainWnd());
(3)为“椭圆”和“矩形”子菜单添加WM_COMMAND和UPDATE_COMMAND_UI消息映射,并编辑相应的消息处理函数;
具体方法同例1。
修改例1,增加工具栏按钮的步骤如下:
打开工程ex61,在ResourceView页面中,双击Toolbar文件夹,可以看到有一个ID位ID_MAINFRAME的工具栏。
双击ID_MAINFRAME工具栏,在工具栏编辑框中出现如下图所示的工具栏。
在工具栏的最右边有一空白按钮,双击该按钮,弹出对话框如下图,其中ID选择ID_ELLIPSE,即“椭圆”按钮。
该按钮显示在编辑窗口中,可以通过Graphics和Colors工具箱及鼠标画自己的图标。
(矩形工具栏图标同椭圆方法)
例3(状态栏)在状态上添加信息行,用来实时显示当前鼠标在视图中的位置,同时也添加一个状态指示器,用来显示当前是否按下了Ctrl键。
步骤如下:
第一步,C乘车基于AppWizard[exe]的单文档工程,名称为ex63。
第二步,添加新的窗格,在窗格中显示鼠标的位置,详细步骤如下:
(1)为新窗口创建一个ID标识号。
选择主菜单中的view下的ResourceSymbols菜单项,弹出ResourceSymbols对话框,它显示了用户应用程序中的所有资源符号。
单击NEW按钮,在显示的NewSymbols对话框中添加新的ID值ID_xy,去默认值:
确定后关闭对话框。
(2)定义新窗格的默认字符串。
为了表示一个窗格,ID必须和一个定义它的字符串相连。
定义字符串,在ResourceView页面下,打开StringTable文件夹,双击StringTable资源,在字符串编辑器中打开它。
双击最后一个空白行,弹出下图对话框,在ID的下拉列表框中选择ID_xy,在Caption中键入“x=100,y=100”。
选中一个以“ID_INDICATOR_”开头的字符串资源,在键盘上按下“Insert“键,插入一个新的字符串资源,将标识号(ID)设置为ID_INDICATOR_CTRL,内容(Caption)设置为“Ctrl键“。
(3)添加窗口的ID标识到状态栏的提示符数组中。
窗格在状态栏中的位置由状态栏的提示符数组决定。
前面提到,在应用程序的MainFrame.cpp文件中定义了提示符数组,若在第一窗格显示“鼠标位置”,修改后的数组如下:
staticUINTindicators[]=
ID_SEPARATOR,//statuslineindicator
ID_xy,
ID_INDICATOR_CTRL,
ID_INDICATOR_CAPS,
ID_INDICATOR_NUM,
ID_INDICATOR_SCRL,
};
第三步,创建状态栏。
(1)声明一个CStatusBar类对象。
在头文件MainFrm.h中可以看到CStatusBar类对象的声明如下:
CStatusBarm_wndStatusBar;
(2)调用Create()函数创建状态栏。
调用SetIndicators()函数,设置指示器的标识符为数组中相应元素指定的值,装载每个标识符指定的字符串资源并将字符串设为提示符文本。
在CMainFrame:
OnCreate()函数中可以状看到态栏的创建代码如下:
intCMainFrame:
OnCreate(LPCREATESTRUCTlpCreateStruct)
if(CFrameWnd:
OnCreate(lpCreateStruct)==-1)
return-1;
if(!
m_wndToolBar.CreateEx(this,TBSTYLE_FLAT,WS_CHILD|WS_VISIBLE|CBRS_TOP
|CBRS_GRIPPER|CBRS_TOOLTIPS|CBRS_FLYBY|CBRS_SIZE_DYNAMIC)||
!
m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
{
TRACE0("
Failedtocreatetoolbar\n"
);
//failtocreate
}
m_wndStatusBar.Create(this)||
m_wndStatusBar.SetIndicators(indicators,
sizeof(indicators)/sizeof(UINT)))
Failedtocreatestatusbar\n"
Deletethesethreelinesifyoudon'
twantthetoolbarto
//bedockable
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&
m_wndToolBar);
return0;
第4步,调用SetPaneText()函数更新窗格中的文字。
当鼠标移动时,坐标值发生变化,第一窗格内的文字随之相应变化。
在CEx63View类中添加WM_ONMOUSEMOVE消息,在其消息处理函数OnMouseMove()中,更新窗格内容,代码如下:
voidCEx63View:
OnMouseMove(UINTnFlags,CPointpoint)
{
Addyourmessagehandlercodehereand/orcalldefault
CStringstr;
str.Format("
x=%d,y=%d"
point.x,point.y);
CMainFrame*pMainFrame=(CMainFrame*)(AfxGetApp()->
GetMainWnd());
pMainFrame->
m_wndStatusBar.SetPaneText(1,str);
CView:
OnMouseMove(nFlags,point);
注:
由于CEx63View类使用了CMainFrame类,因此,需要将类的定义包含进来,在CEx63View.cpp文件头部增加#include“MainFrm.h”。
由于在CEx63View类中访问了成员变量m_wndStatusBar,因此需要将成员变量m_wndStatusBar的受保护类型变为公有类型。
第5步,添加Ctrl键的消息函数。
为了在状态指示器中显示ctrl键的状态,可以在视图类中手工添加相应的消息响应函数。
(1)在ex63View.h中找到类的定义处,添加消息处理函数原型。
classCEx63View:
publicCView
………………
//Generatedmessagemapfunctions
protected:
//{{AFX_MSG(CEx63View)
afx_msgvoidOnMouseMove(UINTnFlags,CPointpoint);
afx_msgvoidOnUpdateKeyCtrl(CCmdUI*pCmdUI);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
(2)找到文件ex63View.cpp中消息映射宏的定义处,在其中添加消息映射宏:
BEGIN_MESSAGE_MAP(CEx63View,CView)
//{{AFX_MSG_MAP(CEx63View)
ON_WM_MOUSEMOVE()
ON_UPDATE_COMMAND_UI(ID_INDICATOR_CTRL,OnUpdateKeyCtrl)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
(3)在文件ex63View.cpp末尾添加消息响应函数体:
OnUpdateKeyCtrl(CCmdUI*pCmdUI)
pCmdUI->
Enable(:
GetKeyState(VK_CONTROL)<
0);
//更新状态指示器
编译、链接并运行程序,状态栏中的显示为:
,第一窗格显示的内容是ID_xy中定义的字符串,当鼠标移动时,窗口内容随便发生变化。
第二窗格则在Ctrl键按下时显示其状态。
思考与联系
1.资源描述文件的作用是什么?
资源页面的作用是什么?
答:
在基于MFC框架编程中,经常要使用一些位图、菜单、对话框、工具栏之类的资源均在文件资源中,其相关的一些信息也都存储在资源描述文件中。
资源界面中有相关于界面设计的一些基本信息。
2.resource.h文件的作用是什么?
与其他头文件类似,它包含了MFC界面设计的基本函数,通过声明resourse.h头文件,便可以调用其中的库函数用于用户界面的开发。
3.菜单消息的消息映射为什么不采用标准的消息映射?
菜单消息映射的控件通知消息主要由窗口类即直接或间接由CWND类派生类处理.相对标准WINDOWS消息及控件通知消息而言,命令消息的处理对象范围就广得多.它不仅可以由窗口类处理,还可以由文档类,文档模板类及应用类所处理。
因此菜单的消息映射函数并没有采用标准的消息映射函数。
4.为什么一般把快捷键和图标资源的ID定义为菜单的ID相同?
图标资源是以位图形式保存的,这一位图资源会放在工程的哪个文件夹中?
通过相同的ID可以直接定位到快捷键以及图标资源相对应的菜单上;
位图资源是放在工程resourse.h文件夹中。
5.在使用CStatusBar类创建状态栏时,定义了全局数组UNITIndicator[]={ID_SEPARATOR,ID_INDICATOR_CAPS,ID_INDICATOR_NUM,ID_INDICATOR_SCRL},试说明这一全局数组的作用。
这个全局数组保存了状态栏上各个组件的ID值。
6.工具栏类(CStatusBar)如何和工具栏资源进行链接?
在声明了一个CStatusBar后,在声明之后,调用Creat()函数创建状态栏,再调用SetIndicators()函数,设置指示器的标识符为数组中相应元素指定的值,装载每个标识符指定的字符串资源并将字符串设为提示符文本。