vc状态栏的使用

来源:互联网 发布:淘宝网怎么看评价管理 编辑:程序博客网 时间:2024/06/05 08:28

状态栏位于主框架窗口的底部,主要用来显示一些提示信息,可细分为几个窗格。状态栏一般用于简要解释被选中的菜单命令、工具栏按钮命令,以及当前的操作对象的状态。另外,它还会显示 Scroll Lock、Num Lock、Caps Lock和Insert等键盘上特殊按键的状态。
状态栏也是一个窗口,它有几个窗格,每个窗格显示不同的信息。类向导会为应用程序自动创建一个状态栏,该状态栏包括几个窗格,分别用来显示状态栏提示和 Caps Lock、Num Lock、Scroll Lock键的状态。在 MFC中,状态栏的功能由 CStatusBar类实现。
状态栏可以随时为用户提供当前程序状态信息,它既不接受用户输入也不产生命令消息,它的作用只是在程序控制下在状态窗格(pane)中显示一些文本来表示当前程序的状态。
1.状态栏的设计与实现
状态栏支持两种类型的文本窗格:状态指示器窗格和信息行窗格,如图5-58所示。


图5-58  状态栏

状态指示器窗格显示程序当前Scroll Lock、Num Lock和其他的按键状态。
指示器窗格的内容通常与一个字符串相关联,通过更新命令UI消息,调用该字符串的ID将其显示出来。消息行窗格用于动态地显示应用程序的状态信息,如菜单命令或按钮提示等。
通过消息行窗格长度为状态栏全长的四分之一,但如果将其设置为第一个窗格(索引为0),则其长度可伸展,最短为状态栏四分之一长,其他窗格将变为右对齐方式。
当使用AppWizard创建应用程序框架时,将会自动生成标准状态栏,状态栏的格式由“MainFrm.cpp”文件中的静态数组indicators所定义,状态栏类CStatusBar成员函数SetIndicators将调用此数组在应用程序框架中生成状态栏。
为了在应用程序中显示一些特定的数据,可以禁止标准状态上原有的消息行和指示器。按下面的方法可以在标准状态栏基础上定制需要的状态栏。
首先将鼠标放在项目工作区“Resource View”面板中的根文件夹上单击右键,在弹出菜单中选择“Rsource Symbols”命令,在弹出的“Rsource Symbols”对话框中单击“New”按钮,会弹出如图5-59所示的“New Symbols”对话框。输入新的ID标识,并为其指定一个数值,如果不想使用系统提供的默认值,可以指定其他允许的数值。


图5-59  添加新资源符号

然后,在“串表”中添加新的字符串,字符串ID为刚才创建的ID,字符串内容自定。
在indicators数组中插放新的ID标识,插入的顺序决定了它出现在状态栏中的位置,数组下标为0的元素在状态栏最左端,从左向右排列。
2.CStatusBar类
与工具栏相同,状态栏类CStatusBar也是派生于CControlBar类,因此具有一些相关类似的特性。CStatusBar类的成员函数如表5-8、表5-9、表5-10所示。
 
创建一个状态栏可以按照以下步骤完成。
构造CStatusBar对象。
调用Create()或CreateEx()函数来创建状态条窗口并将它连接到CStatusBar对象。
调用SetIndicators()函数将字符串ID与每一个指示器联系起来。
下面将介绍几种常用的状态函数。
(1)Create()
Create()函数用来创建一个状态栏,并将它与CStatusBar对象连接。还将状态条的初始字体和高度设置为默认值。该函数原型如下:
 
其中参数pParentWnd是指向一个CWnd对象的指针,该CWnd对象为状态栏的父窗口,通常为this;dwStyle指定状态风格;nID指定状态栏子窗口ID,除标准的Windows风格之外,状态栏还支持如表5-11所示的风格。
 
(2)CreateEx()
函数CreateEx()也用于创建一个状态栏,并把它与CStatusBar对象连接,与函数Create()相比,它具有更多的风格控制。该函数原型如下:
 
其中,参数pParentWnd是指向一个CWnd对象的指针,该CWnd对象为状态栏的父窗口。dwCtrlStyle用于创建嵌入的CStatusBarCtrl对象的附加风格;dwStyle指定了状态条风格;nID指定状态条子窗口ID。表5-12给出了附加的状态栏风格。
 
(3)SetIndicators()
SetIndicators()函数用来将每一个指示器窗格的ID设置为由数组lpIDArray的相应元素指定的值,加载由每一个ID指定的字符串资源,并将这个字符串设置为此指示器的文本。原型如下:
 
参数lpIDArray是一个指向ID数组的指针,nIDCount表示lpIDArray指向的数组的元素数目。
(4)SetPaneStyle()
SetPaneStyle()函数用于设置状态栏任一窗格的风格,函数原型如下:
 
参数nIndex是待设置风格的窗格的索引;nStyle是待设置的窗格风格。
(5)SetPaneInfo()
SetPaneInfo()函数用于设置状态栏指示器窗格的风格,还可用于设置状态栏指示器窗格的新ID和宽度,该函数原型如下:
 
参数nIndex是要设置其风格的指示器窗格的索引;nID是为指示器窗格设置的新的ID;nStyle是为指示器窗格设置的风格;cxWidth是设置的指示器窗格的宽度。
表5-13给出了SetPaneStyle()函数和SetPaneInfo()函数中nStyle参数的风格。
 
(6)SetPaneText()
该函数可以更新指定的任何一个窗格中的文本,函数原型如下:
 
参数nIndex是需要设置文本的窗口索引;lpszNewText是指向新的窗格文本的指针;bUpdate为标志位,如果是TURE,则在文本被设置之后,窗格是无效的。
此外,如果需要在程序中更新状态栏窗口中的文字,还可以有以下几种方法。
(1)调用CWnd类的SetWindowText()函数,该函数只更新第一个窗格(索引为0)中的文本,函数原型如下:
 
参数lpszString是指向待设置为本字符串的指针。
(2)在状态栏的ON_UODATE_COMMAND_UI处理程序中调用CCmdUI类的SetText()函数,函数原型如下:
 
参数lpszText是指向待设置文本字符串的指针。
比较特殊的是,AppWizard不能为状态栏的ON_UODATE_COMMAND_UI消息自动生成消息映射和消息处理函数,因此,需要在程序中手工添加这些代码。
相应的代码读者可以在Record工程的CMainFrame::OnCreate成员函数中找到。
 
SetIndicators函数的第一个参数indicators是一个ID数组,在CMainFrame类所在的CPP文件的开头部分可以找到该数组。 
 
 
indicators数组提供了状态栏窗格的分配信息,它的第一项一般为ID_SEPARATOR,该ID对应的窗格用来显示命令提示信息,后三项都是字符串ID,读者可以在String Table字符串资源中找到这三个字符串分别是CAPS、NUM和SCRL。它们对应的三个窗格用来显示键盘的状态。
【实例5-5】  给状态栏添加时间窗格
光盘路径   /05/pane/
实例目的   给状态栏添加时间窗格
本实例演示程序在运行中会在状态栏显示系统时间,鼠标位置及“Insert”按键是否被按下等状态。
1.创建工程
启动Microsoft Visual Studio 6.0,在IDE中依次选择“File”→“New”菜单命令,或直接按快捷键“Ctrl+N”,打开“New”对话框。
在“New”对话框中单击“Projects”选项卡,在列表框中选择“MFC AppWizard(.exe)”项,在“Project name”文本框中输入“pane”,其他使用默认值,单击“OK”按钮,弹出“MFC AppWizard-Step1”对话框。
在“MFC AppWizard-Step1”对话框中,选中“Single Document”单选框,其他使用默认值,然后单击“Finish”按钮,在弹出的“New Project Information”对话框中单击“OK”按钮,就可以完成工程的创建。
2.添加字符串
在工作区中选择Resource View标签,转到资源编辑窗口,双击“String Table”→“String Table”项条目打开打开串表资源的编辑器。
选择最下面的空白项并双击,或选择某个串后按“Insert”键,将弹出“String Properties”对话框。在“ID”框中输入串标识符和值,在“Caption”框内输入标题字符的内容,串值为系统自动设定。要添加的字符串如表5-14所示。添加完字符串后的界面,如图5-60所示。
 


图5-60  添加完字符串

3.添加响应消息
在IDE主菜单项中依次选择“View”→“ClassWizard”,打开“MFC ClassWizard”对话框,选择“Member Maps”选项卡。
在“Project”下拉列表框中选择“pane”,在“Class name”栏中选择“CMainFrame”,在“Object IDs”栏中选择“CMainFrame”,在Messages栏中双击“WM_TIMER”项,则ClassWizard会弹出一个对话框询问命令处理函数的名字,使用其提供的函数名即可。单击“OK”按钮后,函数OnTimer就被加入到了Member functions栏中。
利用   的方法再添加另一个消息,“Class name”栏中选择“CPaneView”,在“Object IDs”栏中选择“CPaneView”,在Messages栏中双击“WM_MOUSEMOVE”项,则ClassWizard会弹出一个对话框询问命令处理函数的名字,使用其提供的函数名即可。单击“OK”按钮后,函数OnMouseMove就被加入到了Member functions栏中。
4.添加成员变量
为类CMainFrame添加一个成员变量,在工作区中选择Class View标签,转到类编辑窗口,在类CMainFrame上单击鼠标右键选择“Add Member Variable”命令,弹出添加成员变量的对话框,在Variable Type文本框中输入类型为bool,在Variable Name文本框中输入变量的名称为m_bIns,访问控制权限选择为protected,如图5-61所示。


图5-61  添加变量

单击“OK”按钮就可以完成对变量的添加。
5.添加代码
在MainFrm.cpp文件中修改状态栏indicators静态数组,其代码如下:
 
对indicators静态数组的修改直接对状态栏的构成产生影响,在这里,添加了显示鼠标位置、“Insert”键状态指示器和系统时间指示器,它们在数组中的位置也就是它们在状态栏中的位置。
手工添加状态栏对“Insert”键状态改变的更新命令UI消息。在MainFrm.h文件的CMainFrame类定义中添加消息映射处理函数的原型,其代码如下:
 
在CMainFrame类实现文件MainFrm.cpp的消息映射中添加响应“Insert”键的消息映射,其代码如下:
 
语句“ON_UPDATE_COMMAND_UI(ID_INDICATOR_INSERT,OnUpdateKeyInsert)”中的“ID_INDICATOR_INSERT”表示更新UI消息对映射的对象为状态栏的ID_ INDICATOR_INSERT所对应的窗格,OnUpdateKeyInsert是处理该消息的函数。
在MainFrm.cpp文件中添加消息处理函数OnUpdateKeyInsert的定义,其代码如下:
 
 
这段代码,添加了对ID_INDICATOR_INSERT窗格的ON_UPDATE_COMMAND_UI消息的映射处理,使得“Insert”键的状态可以通过自制的更新命令UI在状态中显示出来。
在CMainFrame类中的OnCreate()函数中添加如下代码:
 
这段代码设置了状态栏前两个窗格的风格和宽度,第一个被设置为凸出状态,宽度为200,第二个窗格被设置为可变宽度,宽度最小为70。
为CMainFrame类的OnTimer()函数添加如下代码:
 
语句“tmCurr=CTime::GetCurrentTime();”用于获取系统当前时间,再通过语句“strTime= tmCurr.Format('%H:%M:%S');”将时间格式化后赋给字符串strTime。最后通过状态栏类CStatusBar成员函数SetPaneText()将字符串strTime显示到ID_INDICATOR_TIME所指示的窗格中。CStatusBar成员函数CommandToIndex()用于获取特定指示器ID的索引值。
添加或修改鼠标位置显示部分的代码。由于鼠标在窗口中的移动是由视图类来处理,而要修改主框架的状态栏就必须要让成员能被视图类成员访问。
首先,将CMainFrame类的状态栏对象m_wndStatusBar由protected改为public,其代码如下:
 
然后,在视图类CPaneView的实现文件头部将CMainFrame类包含进来,在paneView.cpp文件最前面添加如下代码:
 
最后,在视图类CPaneView的OnMouseMove()函数中添加如下代码:
 
对状态栏文本修改的实现首先要取得状态栏的访问权限,而在AppWizard中自动生成的状态栏对象是保护类型的,因此要先将其改为公有类型,再将主框架类包含到要访问的程序文件中,最后才能通过下面语句依次取得主框架窗口对象指针和状态栏对象指针:
 
最后通过“pStatus->SetPaneText(1,strMouse);”实现对状态栏中窗格内容的修改。
6.编辑并运行程序
编辑并运行程序,其结果如图5-62所示。


图5-62  程序运行结果

在图5-62中我们看到,状态栏中添加了系统时间、鼠标位置及“Insert”按键是否被按下等状态。



关于改变状态栏的高度

重载CMFCStatusBar

CSize CMYMFCStatusBar::CalcFixedLayout(BOOL bStretch, BOOL bHorz)
{
CSize sizeScreen (GetSystemMetrics (SM_CXSCREEN),GetSystemMetrics (SM_CYSCREEN));
float SCREEN_T = (float)(sizeScreen.cy/768);
CSize size;
size.cx = sizeScreen.cx;
size.cy = (long)(40*SCREEN_T);
return size;
}

0 0
原创粉丝点击