今天啥也没干,开会开了一天,回来就搞了一个小模块——在状态栏显示时间。由于工程使用的是CMFCRibbonStatusBar,而网上没有找到这东西该怎么显示时间,索性自己折腾吧。

谢谢lymanghost提醒,我应该说一下这是个什么工程。

VS2010,建立一个基于多文档的MFC Application工程。

既然要显示时间,一个定时器是免不了了,在CMainFrame::OnCreate()函数中添加一个

 
  
  1. SetTimer(1, 1000, NULL); 

1表示的是EventID,可以设置多个Timer,传递不同的EventID便有不同的时间间隔。

1000表示的是1000ms,每隔1000ms执行一次定时器内的代码。

第三个参数是一个DWORD值,包含定时器标识,一般设为NULL即可。

CMFCRibbonStatusBar与基于对话框模式的CStatusBar有诸多不同之处。CMFCRibbonStatusBar 内的所有元素都是通过AddElement()方法添加进去的,也就是说,所有的添加、修改、删除都需要通过操作这些元素来实现。

我想在右下角显示时间,那么在 CMainFrame::OnCreate()函数中,对右边的元素进行初始化如下:

 
  
  1. // 设置要显示的内容 
  2. CString strTitlePane1; 
  3. CString strTitlePane2 = CTime::GetCurrentTime().Format(_T("%Y-%m-%d %H:%M:%S")); 
  4. bNameValid = strTitlePane1.LoadString(IDS_STATUS_PANE1); 
  5. ASSERT(bNameValid); 
  6.  
  7. m_wndStatusBar.AddElement(new CMFCRibbonStatusBarPane(ID_STATUSBAR_PANE1, strTitlePane1, TRUE), strTitlePane1); 
  8. m_wndStatusBar.AddExtendedElement(new CMFCRibbonStatusBarPane(ID_STATUSBAR_PANE2, strTitlePane2, FALSE), strTitlePane2); 

在对CTime进行格式化的时候,"y"代表年份显示12年,"Y"代表年份显示2012年。

m_wndStatusBar就是 CMFCRibbonStatusBar 类型的,这儿用到了这两个方法:

 
  
  1. void AddElement( 
  2.      CMFCRibbonBaseElement* pElement, 
  3.      LPCTSTR lpszLabel, 
  4.      BOOL bIsVisible=TRUE  
  5.   ); 
  6. void AddExtendedElement( 
  7.      CMFCRibbonBaseElement* pElement, 
  8.      LPCTSTR lpszLabel, 
  9.      BOOL bIsVisible=TRUE  
  10.   ); 

AddElement()会在状态栏的左边添加一个元素,内容是"Pane 1"(通过LoadString()方式获得)。

AddExtendElement()会在状态栏的右边添加一个元素,内容是当前时间。在MSDN里,左边的区域被叫做“主区域”,右边的区域被叫做“扩展区域”,这是Extend的由来。

接下来为 CMainFrame类添加一个WM_TIMER事件,加入如下代码:

 
  
  1. void CMainFrame::OnTimer(UINT_PTR nIDEvent)  
  2. {  
  3.     // TODO: Add your message handler code here and/or call default  
  4.     // 设置状态栏显示时间  
  5.     CString strTime; 
  6.     CMFCRibbonBaseElement * pElement;  
  7.   
  8.     strTime = CTime::GetCurrentTime().Format(_T("%Y-%m-%d %H:%M:%S"));  
  9.     pElement = m_wndStatusBar.FindElement(ID_STATUSBAR_PANE2);  
  10.     pElement->SetText(strTime);  
  11.     // 先别加 
  12.     //pElement->Redraw();  
  13.   
  14.     CMDIFrameWndEx::OnTimer(nIDEvent);  
  15. }  

声明一个CMFCRibbonBaseElement类的指针,用来接住从m_wndStatusBar获得的元素。要获得 CMFCRibbonStatusBar的元素有四个方法:

 
  
  1. CMFCRibbonBaseElement* FindByID( 
  2.      UINT uiCmdID, 
  3.       BOOL = TRUE 
  4.   ); 
  5. CMFCRibbonBaseElement* FindElement( 
  6.      UINT uiID  
  7.   ); 
  8. CMFCRibbonBaseElement* GetElement( 
  9.      int nIndex  
  10.   ); 
  11. CMFCRibbonBaseElement* GetExElement( 
  12.      int nIndex  
  13.   ); 

FindByIDFindElement就不解释了,只要传入元素的ID号即可,需要注意的是后两个。GetElement表示获得主区域的元素,以0作为索引号的起始号码。GetExElement表示获得扩展区域的元素,同样以0作为索引号的起始号码。

查阅MSDN的话,会发现还有GetCount(),GetExCount()等方法,不做赘述。

然后通过SetText()方法来更改要显示的内容。按代码里说的,Redraw()先别加,编译运行看一下,你会发现,只显示了OnCreate中第一次加载的时间,后来时间就不刷新了。细心一点,你会发现,当你把鼠标移上去的时候,时间就会更改一次,再移动一下,又会更改。似乎是鼠标不在上面的时候,这个元素就不能刷新。具体的原因不清楚。如果有高手的话,烦请解答一下,谢谢!

那么把pElement->Redraw()这句话加上后,时间就可以正常更新了,至此,状态栏显示时间就完成了。

Redraw()这个函数是个虚函数,它会调用RedrawWindow()来进行窗口的刷新。