02界面编程2控制条.docx
- 文档编号:26501823
- 上传时间:2023-06-20
- 格式:DOCX
- 页数:15
- 大小:133.58KB
02界面编程2控制条.docx
《02界面编程2控制条.docx》由会员分享,可在线阅读,更多相关《02界面编程2控制条.docx(15页珍藏版)》请在冰豆网上搜索。
02界面编程2控制条
2.2工具条与状态条设计
工具条/栏(toolbar)和状态条/栏(statusbar)是构建友好GUI程序的通用标准,但它们并不是WindowsAPI的标准部件,而是由应用程序框架(MFC)增加的一类控件。
工具条是CToolBar类的对象,状态条是CStatusBar类的对象,这两个类都是控制条(栏)CControlBar的派生类,而CControlBar类又是从CWnd类派生的:
CObject→CCmdTarget→CWnd→CControlBar→CToolBar/CStatusBar
控制条的类层次图
工具条和状态条都是放置在框架窗口内部的特殊控制栏窗口,前者一般位于框架窗口顶部的菜单条之下,后者一般位于框架窗口的底部,它们随其父框架窗口的移动和大小改变而调整自己的长短与位置。
在MFC应用程序中,可以通过其“视图”菜单中的对应菜单项来启用(显示)/禁止(隐藏)工具条和状态条。
而且从MFC4.0开始,工具条由Windows提供的工具栏通用控件来建立,是完全可停靠的(所以工具条应该改称为工具栏)。
由应用程序框架负责管理控制栏对象的构造、析构、及其窗口的创建与显示。
MFC应用程序向导为框架窗口类产生的控制栏代码位于MainFrm.h/MainFrm.cpp中。
1.工具条
工具条由若干可分组的图形按钮组成,这些按钮的图像属于同一个横条状位图,存储在一个位图资源文件(*.bmp)中。
其中,按钮的分组,完全由编程接口(源程序)决定,而与该位图无关。
在应用程序中单击一个按钮后,会像菜单项和快捷键一样发送一个命令消息(一般对应于一个菜单项消息)。
可以响应UI消息来改变按钮状态和图形。
1)缺省工具条
缺省工具条包含“新建”、“打开”、“保存”,“剪切”、“复制”、“粘贴”,“打印”,“关于”等3组8个图形按钮,它们在同一个位图文件(res\Toolbar.bmp)中,每一个按钮按顺序对应于位图中一个16*15(即16像素宽*15像素高)位图片断。
应用程序框架为每个按钮提供一个边框,并通过改变其边框和按钮图片的颜色来表示按钮的状态。
缺省工具条及其位图
可用VS的工具栏编辑器窗口和对应的属性窗口等,来修改缺省的工具条(资源标识为IDR_MAINFRAME)。
MFC应用程序向导生成的缺省工具条资源文本为:
(位于资源文件Student.rc中)
IDR_MAINFRAMETOOLBAR16,15
BEGIN
BUTTONID_FILE_NEW
BUTTONID_FILE_OPEN
BUTTONID_FILE_SAVE
SEPARATOR
BUTTONID_EDIT_CUT
BUTTONID_EDIT_COPY
BUTTONID_EDIT_PASTE
SEPARATOR
BUTTONID_FILE_PRINT
BUTTONID_APP_ABOUT
END
2)编辑工具条
下面仍以Student程序为例,说明如何向工具条中添加按钮、设置响应、及添加新的工具条。
下面是编辑工具条的若干操作于步骤:
●在VC项目工作区的资源视图页中展开“Student\Student.rc”中的“Toolbar”资源列表,双击IDR_MAINFRAME打开工具栏编辑器(见下图)
工具条编辑器
●选择当前按钮:
单击位于VS窗口中部的工具条编辑窗口上部工具条栏中的所需按钮;
●修改位图:
对当前按钮,可以利用“图像”菜单、图像编辑器工具条和(位于属性窗口上部的)颜色窗口,在中部的图像编辑器窗口中绘制和修改当前按钮的位图;
●修改属性:
在属性窗口中可以
⏹选择该按钮所对应的(菜单项)ID
⏹修改该按钮位图的宽和高
⏹键入/修改该按钮所对应的提示文本(\n后的为按钮的浮动提示文本)
●删除按钮:
将按钮拖离工具条即可
●添加按钮:
⏹将工具条最右边的空白按钮拖到你想加入按钮的位置
⏹用“图像”菜单、图像编辑器工具条和颜色窗口来绘制按钮的位图(在空白按钮上绘图后,VS会自动在其右边添加一个新的空白按钮)
⏹在属性窗口中选择该按钮所对应的(菜单项)ID
⏹还可以修改该按钮位图的宽和高、键入/修改该按钮所对应的提示文本
●分组:
左/右拖动按钮半个按钮宽度,可将其
⏹与右边/左边的按钮分开成不同的组
⏹与左边/右边的按钮合并成同一个组
例如,在Student程序的工具条中,在问号按钮前加入分别用“Z”与“L”字符表示的“张三”菜单项(ID_NAME_ZS)与“李四”菜单项(ID_NAME_LS)按钮。
3)添加新工具条
如果:
1在使用应用程序向导创建程序时,在“MFC应用程序向导”对话框的“用户界面功能”页的“工具栏”选项中,没有选“标准停靠”单选钮,则需要自己加入工具条;
2或者原有的工具条不够用,需要加入第2个工具条;
3或者在程序运行当中需要在多个工具条中切换;
对这些情况都需要自己创建新的工具条,并且自己写代码将它装入框架窗口。
(1)创建工具条资源
●在项目工作区的“资源视图”页中的Toolbar资源表项上单击鼠标右键,在弹出的浮动菜单中选“插入Toolbar”菜单项,VS会自动创建一个ID为IDR_TOOLBAR1的空工具条
●可在该工具条中加入若干图形按钮(如W)
●在属性窗口中修改工具条的ID(如IDR_MYTB),选择按钮对应的ID(如ID_NAME_WW)
(2)创建、装入、显示工具条
针对前面所讲的3种情况,分别采用下列不同的方法来装入工具条:
1在没有工具条的框架窗口中加入工具条:
●创建新工具条资源
●打开头文件MainFrm.h,在CMainFrame类中加入工具条类CToolBar的对象m_ToolBar作为公共数据成员:
(缺省的工具条对象为CToolBarm_wndToolBar;)
CToolBarm_ToolBar;
●在CMainFrame类中WM_CREATE消息响应函数OnCreate(若无该函数则创建它)中的return0;语句之前加入下列代码:
if(!
m_ToolBar.CreateEx(this,TBSTYLE_FLAT,WS_CHILD|WS_VISIBLE|
CBRS_TOP|CBRS_GRIPPER|CBRS_TOOLTIPS|CBRS_FLYBY|
CBRS_SIZE_DYNAMIC)||!
m_ToolBar.LoadToolBar(IDR_MYTB))
{
TRACE0("未能创建工具栏\n");
return-1;//未能创建
}
m_ToolBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_ToolBar);
其中的CreateEx函数代替了下列三个函数的功能:
if(!
m_ToolBar.Create(this)){//创建工具条
TRACE0("未能创建工具栏\n");
return-1;//创建失败
}
if(!
m_ToolBar.LoadToolBar(IDR_MYTB)){//装入工具条
TRACE0("未能创建工具栏\n");
return-1;//装入失败
}
m_ToolBar.SetBarStyle(m_ToolBar.GetBarStyle()|CBRS_GRIPPER|CBRS_TOOLTIPS|
CBRS_FLYBY);
//CBRS_GRIPPER:
在工具条的左边加一个夹条
//CBRS_TOOLTIPS:
激活工具条提示;
//CBRS_FLYBY:
允许在鼠标滑过图形按钮时在显示提示(缺省只有在按下按钮时才提示,且无浮动式提示)
2在框架窗口中加入多个工具条:
●创建新工具条资源
●打开头文件MainFrm.h,在CMainFrame类中加入工具条类CToolBar的对象m_ToolBar作为公共数据成员:
CToolBarm_ToolBar;
●在原有的OnCreate函数内加入似①的创建与装入工具条的代码,但要注意代码的顺序,且不需重复语句EnableDocking(CBRS_ALIGN_ANY);参见下面代码的红色部分(其余部分为自动生成的缺省代码):
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("未能创建工具栏\n");
return-1;//未能创建
}
if(!
m_ToolBar.CreateEx(this,TBSTYLE_FLAT,WS_CHILD|WS_VISIBLE|
CBRS_TOP|CBRS_GRIPPER|CBRS_TOOLTIPS|CBRS_FLYBY|
CBRS_SIZE_DYNAMIC)||!
m_ToolBar.LoadToolBar(IDR_MYTB))
{
TRACE0("未能创建工具栏\n");
return-1;//未能创建
}
if(!
m_wndStatusBar.Create(this)||
!
m_wndStatusBar.SetIndicators(indicators,
sizeof(indicators)/sizeof(UINT)))
{
TRACE0("未能创建状态栏\n");
return-1;//未能创建
}
//TODO:
如果不需要工具栏可停靠,则删除这三行
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar);
m_ToolBar.EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_ToolBar);
return0;
}
3显示/隐藏/切换工具条:
●似②创建若干工具条资源
●在OnCreate函数内加入相应代码,来创建与装入工具条
●在这些代码后面,加上隐藏暂不显示的工具条的代码,如
ShowControlBar(&m_ToolBar,FALSE,FALSE);
这里用了框架窗口类的ShowControlBar成员函数,其原型为:
voidShowControlBar(CControlBar*pBar,BOOLbShow,BOOLbDelay);
●在菜单资源中添加显示/隐藏/切换工具条的菜单项(如“视图\切换工具栏”ID_CHANGE_TB),在某一窗口派生类(如视图类CStudentView)中创建该菜单项的消息响应函数(如OnChangeTb),在该函数中隐藏/显示/切换工具条,例如:
voidCStudentView:
:
OnChangeTb()
{
CMainFrame*pFrmWnd=(CMainFrame*)GetTopLevelFrame();
if(m_bTBar){
pFrmWnd->ShowControlBar(&pFrmWnd->m_wndToolBar,FALSE,FALSE);
pFrmWnd->ShowControlBar(&pFrmWnd->m_ToolBar,TRUE,FALSE);
m_bTBar=false;
}
else{
pFrmWnd->ShowControlBar(&pFrmWnd->m_ToolBar,FALSE,FALSE);
pFrmWnd->ShowControlBar(&pFrmWnd->m_wndToolBar,TRUE,FALSE);
m_bTBar=true;
}
}
其中m_bTBar为bool型类变量,可在视图类的头文件中定义,在视图类的代码文件中的构造函数中设置初始值为true。
这里需要修改CMainFrame类中原为保护的类变量m_wndToolBar为公共的类变量,还需要在CStudentView类的代码文件CStudentView.cpp中包含CMainFrame类的头文件:
#include"MainFrm.h"
4)修改工具条的位图与ID
除了可装入和切换整个工具条(包括位图与ID),也可只装入位图而不改其原来的ID,这需要使用CToolBar类的成员函数LoadBitmap或SetBitmap,其原型分别为
BOOLLoadBitmap(LPCTSTRlpszResourceName);
BOOLLoadBitmap(UINTnIDResource);
与
BOOLSetBitmap(HBITMAPhbmImageWell);
其中的按钮图片个数必须原来的按钮数相同。
也可不改变按钮的图片,而只是改变其ID、风格和位置:
voidSetButtonInfo(intnIndex,UINTnID,UINTnStyle,intiImage);
5)设置按钮状态
(1)禁止与激活
工具条上图形按钮的禁止与激活是与其对应菜单项同步的,并不需要另外处理。
注意:
禁止与激活状态对直接位于菜单条中的菜单项是无效的,但对于位于下拉式或浮动式弹出菜单中菜单项则是有效的。
(2)是否按下
工具条上图形按钮是否被按下是与其对应菜单项是否已被选中(带有√)同步的,也不需要另外处理。
如在Student程序中,可单击按钮Z让其在按下与还原之间切换。
具体步骤如下:
●可在CStudenView类中设置一个布尔型数据成员m_bZs(boolm_bZs;)
●在类的构造函数中将该变量初始化为假(m_bZs=false;)
●在消息响应函数OnNameZs中,切换该变量的真假(m_bZs=!
m_bZs;)
●在Z按钮(ID_NAME_ZS)UI更新响应函数OnUpdateNameZs中,根据m_bZs的值来设置按钮是否按下:
voidCStudentView:
:
OnUpdateNameZs(CCmdUI*pCmdUI){
pCmdUI->SetCheck(m_bZs);
}
2.状态条
状态条既不接受用户输入,也不产生命令消息,只能显示提示/状态信息和其他文本串。
状态条窗口由若干文本窗格(pane)组成,窗格分成两类:
消息行窗格和状态指示窗格。
若想在状态条中显示应用程序数据,则必须禁用标准的状态条。
1)缺省状态条
缺省状态条用于显示菜单提示和键盘状态。
缺省状态条在CMainFrame类中对应于保护型数据成员CStatusBarm_wndStatusBar;在MainFrm.cpp文件的前面部分中有数组:
staticUINTindicators[]=
{
ID_SEPARATOR,//状态行指示器
ID_INDICATOR_CAPS,//CapsLock指示符
ID_INDICATOR_NUM,//NumLock指示符
ID_INDICATOR_SCRL,//ScrollLock指示符
};
在CMainFrame类的消息响应函数OnCreate内有相应的创建代码:
if(!
m_wndStatusBar.Create(this)||
!
m_wndStatusBar.SetIndicators(indicators,
sizeof(indicators)/sizeof(UINT)))
{
TRACE0("未能创建状态栏\n");
return-1;//未能创建
}
可用状态条类的成员函数SetPaneText在状态条中显示提示信息。
例如
m_wndStatusBar.SetPaneText(0,L"Messagelineforfirstpane");
其函数原型为
BOOLSetPaneText(intnIndex,LPCTSTRlpszNewText,BOOLbUpdate=TRUE);
其中的nIndex可取不同的值,对应于不同的窗格。
2)定制状态条/显示应用程序数据
●将CMainFrame类中的保护数据成员m_wndStatusBar改为公共的
●在头文件MainFrm.h中加入窗格ID的枚举变量。
如
enumSBID{prompt,xName,xVal,yName,yVal};
●去掉原indicators数组中的三个状态指示窗格的ID,加入若干(n个)消息行窗格ID(ID_SEPARATOR),其中第1个(nIndex=0)用于显示提示信息,其余的(n个)用作应用程序的数据显示。
如
staticUINTindicators[]=
{
ID_SEPARATOR,//提示nIndex=0
ID_SEPARATOR,//"x:
"nIndex=1
ID_SEPARATOR,//x值nIndex=2
ID_SEPARATOR,//"y:
"nIndex=3
ID_SEPARATOR,//y值nIndex=4
};
●在创建状态条的代码后(如在CMainFrame:
:
OnCreate函数的尾部),用状态条的成员函数SetPaneInfo来设置每个窗格的ID、风格和宽度(单位似对话框,为1/4英文字母),其函数原型为
voidSetPaneInfo(intnIndex,UINTnID,UINTnStyle,intcxWidth);
其中nStyle可取值:
⏹SBPS_NOBORDERS窗格周围无三维边框
⏹SBPS_POPOUT窗格突出显示
⏹SBPS_DISABLED不画文本
⏹SBPS_STRETCH伸缩窗格以填满空间(每个状态条中只能有一个窗格可以被设置成伸缩的)
⏹SBPS_NORMAL不伸缩、无边框、不凸显
还可以用状态条类的另一成员函数SetPaneText在窗格中显示文本信息。
如
m_wndStatusBar.SetPaneInfo(0,prompt,SBPS_STRETCH,0);//提示
m_wndStatusBar.SetPaneInfo(1,xName,SBPS_NOBORDERS,8);//"x:
"
m_wndStatusBar.SetPaneText(xName,L"x:
");
m_wndStatusBar.SetPaneInfo(2,xVal,SBPS_NORMAL,24);//x值
m_wndStatusBar.SetPaneInfo(3,yName,SBPS_NOBORDERS,8);//"y:
"
m_wndStatusBar.SetPaneText(yName,L"y:
");
m_wndStatusBar.SetPaneInfo(4,yVal,SBPS_NORMAL,24);//y值
●在应用程序中用函数SetPaneText动态修改窗格中的文本串。
如
voidCStudentView:
:
OnMouseMove(UINTnFlags,CPointpoint){
wchar_tbuf[20];
CMainFrame*pFrmWnd=(CMainFrame*)GetTopLevelFrame();
_itow_s(point.x,buf,20,10);
pFrmWnd->m_wndStatusBar.SetPaneText(pFrmWnd->xVal,buf);
_itow_s(point.y,buf,20,10);
pFrmWnd->m_wndStatusBar.SetPaneText(pFrmWnd->yVal,buf);
CView:
:
OnMouseMove(nFlags,point);
}
这里可能需要在视图代码文件的开始处包含主框架类的头文件(#include"MainFrm.h");而且需要在视图类中,为WM_MOUSEMOVE消息添加响应函数OnMouseMove。
作业
2.(控制条)进一步完善Student程序,包括添加/设置/修改工具条按钮、创建/装入/显示/隐藏工具条、动态设置按钮状态;定制状态条、动态显示鼠标的当前位置。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 02 界面 编程 控制