状态栏编程(显示系统时间和进度条)
原文地址:http://welkangm.blog.163.com/blog/static/19065851020127941446182/
顯示系統時間
1、?在狀態欄中設置兩個新的欄位Timer和Progress。首先到ResourceView中編輯String Table,增加IDS_TIMER(時間),PROGRESS(進度)。然后在MainFrame中修改indicators數組,插入IDS_TIMER和IDS_PROGRESS。插入的位置,即為顯示的位置。(添加字符串必須將字符串說明也寫上,不然無法新建)在CMainFrame中添加CProgressCtrl m_Progress;
2、?現在我們讓狀態欄上的IDS_TIMER的位置顯示系統當前的時間。我們只要在MainFrame的OnCreate函數中寫入:
?CTimet=CTime::GetCurrentTime();??????????//獲得當前的系統時間
CClientDC dc(this);
CSizesz=dc.GetTextExtent(str);??????????????//設置一個CClientDC對象來獲取str的長度
CStringstr=t.Format("%H:%M:%S");???????//格式可以參考MSDN中的strftime函數
?int index=0;
?index=m_wndStatusBar.CommandToIndex(IDS_TIMER);?????
//此處也可以直接輸入IDS_TIMER在indicators數組中從0開始的序號。
//設置狀態欄寬度
?m_wndStatusBar.SetPaneInfo(index,IDS_TIMER,SBPS_NORMAL,sz.cx);????
?m_wndStatusBar.SetPaneText(index,str);????????????//設置IDS_TIMER指示器字符串
3、?在OnCreate函數中添加SetTimer(1,1000,NULL);語句,讓后為CMainFrame類添加WM_TIMER消息相應函數,在OnTimer函數中將上述代碼復制進去,就可以實現隨時變化時間的狀態欄。?
添加進度條:
1、?現在我們將狀態欄中的PROGRESS欄位顯示一個50%的進度欄。如果我們只是簡單的在MainFrame的OnCreate函數中寫入以下代碼:
CRect rect;
?/*獲取IDS_PROGRESS欄位的CRect值,付給rect*/
?m_wndStatusBar.GetItemRect(m_wndStatusBar.CommandToIndex(IDS_PROGRESS),&rect);???
/*在IDS_PROGRESS的位置顯示一個50%的進度欄*/
?m_progress.Create(WS_CHILD|WS_VISIBLE,rect,m_wndStatusBar,123);????
?m_progress.SetPos(50);
2、?你會發現IDS_PROGRESS欄位仍然顯示的是“進度”兩個字。這是為什么呢?原因是因為,在OnCreate函數中,窗臺和狀態欄并沒有真正創建完畢,所以GetItemRect函數無法獲取IDS_PROGRESS欄位的CRect值。解決的辦法是,添加一個自定義的消息,把消息放入消息隊列,等窗體和狀態欄創建完畢后,再通過消息響應,創建進度欄。
添加自定義消息
1、?在MainFrame頭文件中添加自定義消息
#define WM_PROGRESS WM_USER+1
2、?然后在頭文件中添加消息響應函數
afx_msg LRESULT OnProgress(WPARAMwParam,LPARAM lParam);
在cpp文件中添加消息映射
ON_MESSAGE(WM_PROGRESS,CMainFrame::OnProgress)
3、?寫消息響應函數:
void CMainFrame::OnProgress()
{
???CRect rect;
???m_wndStatusBar.GetItemRect(m_wndStatusBar.CommandToIndex(IDS_PROGRESS),&rect);
???if(m_Progress.GetSafeHwnd() == nullptr)
?????? m_Progress.Create(WS_CHILD|WS_VISIBLE,rect, &m_wndStatusBar, 123);
??? else m_Progress.ShowWindow(SW_SHOW);
???m_progress.SetPos(50);
}
4、?去掉上一個步驟在OnCreate中添加的語句。
然后在OnCreate函數最后添加如下語句:
PostMessage(WM_PROGRESS);
注意這里要用PostMessage不能用SendMessage,否則系統會先處理OnProgress消息響應,然后再創建窗體,出現仍看不見進度欄的情況。必須用PostMessage先把消息放入消息響應隊列當中,等窗體創建完畢后,系統再處理OnProgress函數。
5、?這時就可以看見進度跳了,但是還有個問題,當窗口大小改變時,進度條會離開IDS_PROGRESS狀態欄的位置。可以使用下面的方法解決。
狀態欄隨窗口改變大小
1、?為MainFrame添加WM_SIZE消息相應函數,并添加如下代碼:
void CMainFrame::OnSize(UINT nType,int cx, int cy)
{
?????? CFrameWndEx::OnSize(nType, cx, cy);
?
?????? // TODO: 在此添加消息處理程序代碼
?????? if(m_wndStatusBar.GetSafeHwnd() != nullptr)
??? {
?????? CRectrect;
?????? m_wndStatusBar.GetItemRect(1,&rect);
?????? if(m_Progress.GetSafeHwnd() != nullptr)
?????? {
?????????? m_Progress.SetWindowPos(&wndTop,rect.left, rect.top,
????????????? rect.right- rect.left, rect.bottom - rect.top, 0);
?????? }
??? }
}
?
顯示鼠標位置
1.??????現在我們要讓狀態欄上顯示鼠標在窗口中的坐標。由于View窗體在MainFrame框架前,所以我們要響應的是View窗體上OnMouseMove事件。
2.??????首先我們在View類中右鍵新建一個window消息響應函數,添加一個WM_MOUSEMOVE的消息響應函數。添加如下代碼:
???????CStringstr;
???????str.Format(_T("x=%d,y=%d"),point.x,point.y);????????????????????/*對鼠標坐標進行格式化*/
?????((CMainFrame*)GetParent())->m_wndStatusBar.SetWindowText(str);??????
/*由于作用的是View窗口的父窗口MainFrame下的m_wndStatusBar對象,所以必須將m_wndStatusBar設置為public,然后用(CMainFrame*)指名其為框架類指針,否則->后面不會出現m_wndStatusBar對象。注意在View程序中必須包含MainFrame的頭文件*/
也可以將最有一句改為:?((CMainFrame*)GetParent())->SetMessageText(str);直接由框架類函數中的SetMessageText實現對狀態欄文字的更改。
3.??????第三種實現方法是:?((CMainFrame*)GetParent())->GetMessageBar()->SetWindowText(str);通過框架類函數GetMessageBar來獲得指向狀態欄窗口的指針。這種方法的好處是,不需要再把MainFrame中的m_wndStatusBar設置為public。
4.??????第四種方法:?GetParent()->GetDescendantWindow(AFX_IDW_STATUS_BAR)->SetWindowText(str);?因為GetDescendantWindow本來就是CWnd的成員函數,所以不需要轉換為框架類對象,并根據ID號,來獲得子孫窗口的對象指針,這里的AFX_IDW_STATUS_BAR,是由CStatusBar::Create默認產生的。
?
?
總結
以上是生活随笔為你收集整理的状态栏编程(显示系统时间和进度条)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用电脑无线网卡分享网络命令
- 下一篇: 键盘布局的改进之道