状态栏介绍
一般情况下,应用程序的最下方就是状态栏,主要应用于信息提示,如图1所示。
状态栏分为两部分,第一部分是左边最长的那部分就是提示行,当我们把鼠标移动到某个工具栏按钮或者菜单项时,这个部分就会显示对应的提示信息。这个提示信息是在菜单项或者工具栏按钮的Prompt属性中完成的。
第二部分是其右边的三个窗格,主要用来显示Caps Lock,Num Lock和Scroll Lock键的状态,称为状态指示器。我们可以自由的删增状态指示器,指示器标题在资源栏的String Table中进行修改,修改过程下面再详细介绍,如图2所示:
创建状态栏
创建步骤:
1. 构造CStatusBar对象,做为主框架类的成员函数。
2. 调用Create(或CreateEx)函数来创建状态条窗口并将它连接到CStatusBar对象,需要在主框架窗口创建之后调用
3. 调用SetIndicators函数将字符串ID与每一个指示器联系起来。
具体代码:
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
...
//创建状态栏窗口,m_wndStatusBar是CMainFrame类的成员函数
if (!m_wndStatusBar.Create(this))
{
return -1;
}
//设置指示器ID
if (!m_wndStatusBar.SetIndicators(indicators,sizeof(indicators)/sizeof(UINT)))
{
return -1; // 未能创建
}
return 0;
}
其中 indicators是指示器数组ID,是个静态的变量,其
数组元素的顺序就决定了指示器窗格属性,我们可以在这个静态数组中删增或调整数组元素,以完成相应的用户个性化需求,默认的代码如下:
static UINT indicators[] =
{
ID_SEPARATOR, // 状态行指示器
ID_INDICATOR_NUM,
ID_INDICATOR_CAPS,
ID_INDICATOR_SCRL,
};
新增指示器
现在我们在原有基础上增加两个指示器,用于指示“时间”和“进度”信息,其新增的ID分别是ID_INDICATOR_TIMER和ID_INDICATOR_PROGRESS,具体代码如下:
static UINT indicators[] =
{
ID_SEPARATOR, // 状态行指示器
ID_INDICATOR_TIMER, //时间指示器,新增
ID_INDICATOR_PROGRESS, //进度指示器,新增
ID_INDICATOR_NUM,
ID_INDICATOR_CAPS,
ID_INDICATOR_SCRL,
};
运行效果:
函数详解
Create函数用于创建状态栏并和状态类对象相绑定,其函数声明和注解如下:
BOOL Create( CWnd* pParentWnd, DWORD dwStyle = WS_CHILD | WS_VISIBLE | CBRS_BOTTOM, UINT nID = AFX_IDW_STATUS_BAR );
返回值:
如果成功则返回非零值;否则返回0。
参数:
pParentWnd
指向一个CWnd对象的指针,该对象的Windows窗口是此状态条的父窗口。
dwStyle
状态条风格。除标准的Windows风格之外,还支持下列风格:
· CBRS_TOP 控制条在框架窗口的顶部。
· CBRS_BOTTOM 控制条在框架窗口的底部。
· BRS_NOALIGN 当父窗口的尺寸发生变化时不重新定位控制条。
nID
工具条的子窗口ID。
说明:
此成员函数用来创建一个状态条(一个子窗口)并将它与CStatusBar对象连接。还将状态条的初始字体和高度设置为缺省值。
SetIndicators用于指定指示器ID,其函数声明和注解如下:
BOOL SetIndicators( const UINT* lpIDArray, int nIDCount );
返回值:如果成功则返回非零值;否则返回0。
参数: lpIDArray 指向一个ID数组的指针。
nIDCount 由lpIDArray指向的数组的元素数目。
说明:
此成员函数用来将每一个指示器的ID设置为由数组lpIDArray的相应元素指定的值
加载由每一个ID指定的字符串资源,并将这个字符串设置为此指示器的文本。
SetPaneText主要用来设置窗格信息,其函数声明如下:
BOOL SetPaneText( int nIndex, LPCTSTR lpszNewText, BOOL bUpdate = TRUE );
返回值:
如果成功则返回非零值;否则返回0。
参数:
nIndex 要设置其文本的窗格的索引。
lpszNewText 指向新的窗格文本的指针。
bUpdate 如果是TRUE,则在文本被设置之后,窗格是无效的。
说明:
此成员函数用来将窗格文本设置为由lpszNewText指定的字符串。
SetPaneInfo可以用来设置指示器窗格的新ID,风格和宽度信息,其函数声明如下:
void SetPaneInfo( int nIndex, UINT nID, UINT nStyle, int cxWidth );
参数:
nIndex 要设置其风格的指示器窗格的索引。
nID 该指示器窗格的新ID。
nStyle 该指示器窗格的新风格。
cxWidth 该指示器窗格的新宽度。
显示系统时间
现在我们在状态栏的时间窗格上显示系统当前时间,最小精度为秒,为了达到实时刷新的效果,我们需要引入定时器功能,代码步骤如下:
1.主框架的OnCreate函数return之前第一次设置时间窗格信息
2.OnCreate函数中启动定时器开关,频率是1s
3.在WM_TIMER消息函数中再次设置时间窗格信息,用于实时刷系统时间
具体代码如下:
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
...
if (!m_wndStatusBar.Create(this) ||
!m_wndStatusBar.SetIndicators(indicators,
sizeof(indicators)/sizeof(UINT)))
{
TRACE0("未能创建状态栏\n");
return -1; // 未能创建
}
...
//窗口创建时的时间
SetTimerPaneInfo();
//设置定时器,用于实时显示
SetTimer(ENUM_INDICATOR_TIMER_ID,1000, NULL);
return 0;
}
刷新时间定时器
void CMainFrame::OnTimer(UINT_PTR nIDEvent)
{
// TODO: 在此添加消息处理程序代码和/或调用默认
if (ENUM_INDICATOR_TIMER_ID == nIDEvent)
{
SetTimerPaneInfo();
}
CFrameWnd::OnTimer(nIDEvent);
}
主要功能实现代码
/****************************************************************
*函数名称:SetTimerPaneInfo
*功 能:设置状态栏的系统当前时间
*作 者:Jin
*日 期:2016年11月27日
****************************************************************/
void CMainFrame::SetTimerPaneInfo()
{
CClientDC dc(this);
CTime Time = CTime::GetCurrentTime();
CString strTime = Time.Format("%H:%M:%S");
//确保时间指示器的足够容纳下时间字符串
CSize sz = dc.GetTextExtent(strTime);
int nTimerIndex = m_wndStatusBar.CommandToIndex(ID_INDICATOR_TIMER);
if (nTimerIndex != -1)
{
m_wndStatusBar.SetPaneInfo(nTimerIndex, //指示器索引
ID_INDICATOR_TIMER,//指示器ID
SBPS_NOBORDERS, //指示器风格
sz.cx); //指示器宽度
//显示系统时间
m_wndStatusBar.SetPaneText(nTimerIndex,strTime);
}
}
运行效果:
CStatusBar类成员
构造
CStatusBar | 构造一个CStatusBar对象 |
Create | 创建状态条,并将它与CStatusBar对象连接,且设置初始字体和条高度 |
CreateEx | 创建一个具有嵌入CStatusBarCtrl对象附加风格的CStatusBar对象 |
SetIndicators | 设置指示器ID |
属性
CommandToIndex | 获取给定指示器ID的索引 |
GetItemID | 获取给定索引的指示器ID |
GetItemRect | 获取给定索引值的显示矩形 |
GetPaneInfo | 获取一个给定索引的指示器ID,风格和宽度 |
SetPaneInfo | 设置一个给定索引的指示器ID,风格和宽度 |
GetPaneStyle | 获取一个给定索引的指示器风格 |
SetPaneStyle | 设置一个给定索引的指示器风格 |
GetPaneText | 获取一个给定索引的指示器文本 |
SetPaneText | 设置一个给定索引的指示器文本 |
GetStatusBarCtrl | 允许直接访问基础通用控件 |
可重载
DrawItem | 当一个属主绘制的状态条控件的外观改变时,此函数被调用 |