状态栏编程实例

状态栏介绍


一般情况下,应用程序的最下方就是状态栏,主要应用于信息提示,如图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("未能创建状态栏
");
        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 当一个属主绘制的状态条控件的外观改变时,此函数被调用 


原文地址:https://www.cnblogs.com/jinxiang1224/p/8468357.html