MFC对话框程序添加状态栏动态显示时间,随窗口大小变化

时间:2021-10-30 07:32:55

新建MFC 对话框项目DlgStatusBar,选择基于对话框,选择Use Unicode libraries(否则运行前后界面风格会不同),接下来选择 Minimize box , Maximize box , 去掉About box 然后Finished

首先创建状态栏

首先在string table 里添加两个字串,ID分别为IDS_INDICATOR_MESSAGE IDS_INDICATOR_TIME

把它们的Caption 分别设置为:Msg      星期%d  上午 000000

然后在DlgStatusBar.h中声明一个CStatusBar变量

接着声明int型变量index1,index2 用来保存IDS_INDICATOR_MESSAGE面板 IDS_INDICATOR_TIME面板的索引,另外声明两个int变量nWidth1,nWidth2 用来保存IDS_INDICATOR_MESSAGE面板 IDS_INDICATOR_TIME面板的宽度

接着再声明UINT型变量 nID nStyle 分别用来接收面板ID和面板风格,还要声明一个CString 变量str 用来接收Msg内容

DlgStatusBar.h中的代码如下:

CStatusBar m_wndStatusBar;

 

    int  index1,  

         index2,

          nWidth1, 

         nWidth2;

 

    UINT  nID,   

          nStyle;

Cstring str;

接下来在DlgStatusBar.cpp的开头添加如下数组

static UINT indicators[] =

 

{

 

     IDS_INDICATOR_MESSAGE,

 

     IDS_INDICATOR_TIME

 

};

然后到CDlgStatusBarDlg::OnInitDialog()函数中来创建这个StatusBar

if(!m_wndStatusBar.Create(this)||

  !m_wndStatusBar.SetIndicators(indicators,sizeof(indicators)/sizeof(UINT)))

 {

  TRACE0("Can't create status bar\n");

  return false;

  }

接下来获取IDS_INDICATOR_MESSAGE,IDS_INDICATOR_TIME的索引和对应的宽度

index1 = this->m_wndStatusBar.CommandToIndex(IDS_INDICATOR_MESSAGE);

index2 = this->m_wndStatusBar.CommandToIndex(IDS_INDICATOR_TIME);

m_wndStatusBar.GetPaneInfo(index2,nID,nStyle,nWidth2);

 

然后设置IDS_INDICATOR_MESSAGE面板的宽度

CRect rect;

    GetClientRect(rect);

    this->m_wndStatusBar.SetPaneInfo(index1,nID,nStyle,rect.Width()-nWidth2-15);

然后设置IDS_INDICATOR_TIME面板的宽度

this->m_wndStatusBar.SetPaneInfo(index2,nID,nStyle,rect.Width());

// 重新摆放控件,因为增加状态栏之后,控件相对位置发生变化,重新摆放才能显示出来

    RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,0);

     //使用UNICODE 设置字幕文本,可以做成一个函数动态的改变 滚动字幕的文本

    str=_T("                        欢迎使用本软件..........");

    // 设置IDS_INDICATOR_MESSAGE的内容

    m_wndStatusBar.SetPaneText(0,str);

    //设置定时器

    SetTimer(111,500,NULL);

F5运行 可以看到状态栏已经创建好了,但是这样创建的状态栏有两个问题:

1在状态栏最右边有个可以拉动状态的小三角,一般自定义情况下是不容许通过拉动这个三角来缩放状态栏大小的

2当窗口最大化时,状态栏的位置和大小都不会随着窗口变大而变化

那么怎么办呢?

首先解决小三角的问题:

 要解决这个小三角的问题,必须建立一个没有 SBARS_SIZEGRIP 风格的状态栏。可是,在状态栏建立以后再把这个风格去掉是没有用的。因为 Windows 只会在建立状态栏时才会去认这个风格。MFC 提供 CStatusBar::Create 使你能够传送你自己的风格参数,但是 MFC 包含如下的硬代码(写死的)行:

// in CStatusBar::CreateEx
if (pParentWnd->GetStyle() & WS_THICKFRAME)
 dwStyle |= SBARS_SIZEGRIP;
dwStyle |= dwCtrlStyle;
return CWnd::Create(... dwStyle ...);

这意味着如果你的主框架有 WS_THICKFRAME 风格(就是普通的框架窗口),MFC 会坚持为状态栏设置 SBARS_SIZEGRIP 风格。怎么办?

一个合适的方法是派生一个新的类,CMyStatusBar,重写自己的 Create 函数,并且不使用 SBAR_SIZEGRIP 风格。但是不用那么复杂,用下面简简单单的几行代码也达到了相同的目的:

// 关闭 WS_THICKFRAME
ModifyStyle(WS_THICKFRAME,0);
m_wndStatusBar.Create(this); //
执行完这一行之后再打开
WS_THICKFRAME
ModifyStyle(0,WS_THICKFRAME);

这样使 MFC 以为框架没有厚边框,所以它关闭了SBARS_SIZEGRIP,从而状态栏的手柄被隐藏。这个方法虽然很业余,但效果不错。

具体代码修改如下:

ModifyStyle(WS_THICKFRAME,0); // 关闭可调边框

    if(!m_wndStatusBar.Create(this)||

        !m_wndStatusBar.SetIndicators(indicators,sizeof(indicators)/sizeof(UINT)))

    {

        TRACE0("Can't create status bar\n");

        return false;

    }

    ModifyStyle(0,WS_THICKFRAME); // 打开可调边框

F5 运行 小三角问题解决

下面来解决状态栏随窗口大小变化的问题

窗口大小变化是在WM_ONSIZE消息中进行的,所以先给DlgStatusBarDlg添加一个WM_ONSIZE消息

OnSize()函数中添加如下代码:

CRect rectDlg,

          rectBar;

    GetClientRect(rectDlg);

   

    if(m_wndStatusBar&&(0 != rectDlg.Width()))

    {

        CStatusBar *m_pwndStatusBar = (CStatusBar*)&m_wndStatusBar;  

        m_pwndStatusBar->GetClientRect(&rectBar);

        m_pwndStatusBar->SetPaneInfo(index1,nID,nStyle,rectDlg.Width()-nWidth2-15);

    m_pwndStatusBar->MoveWindow(0,cy-rectBar.Height(),rectDlg.Width(),rectBar.Height());  

    }

 

F5运行 此时状态栏就能随窗口大小变化而变化

下面来设置动态显示时间

DlgStatusBarDlg 添加WM_TIMER响应消息 为了便于操作,我们添加一个时间信息函数

CString GetTimeInfo(); 返回一个CString

GetTimeInfo()函数的代码请参看源代码

然后添加WM_TIMER消息,并在OnTimer函数中添加Msg 消息内容,和设置时间

 

 

 源码下载:http://download.csdn.net/detail/zhaoxiatengkong_1/6295279