在狀態條中顯示進程狀態
發表于:2007-07-14來源:作者:點擊數:
標簽:
菡 冰 在利用MFC編寫應用程序尤其是涉及到數值分析與模擬程序時,要進行大量的數值運算,如在屏幕上顯示三維、二維圖形圖像就需要進行數據擬合、樣條以及插值等算法,而且為了保證精度,運算時數據點一般還采用浮點甚至雙精度浮點數,這樣應用程序就需要占用
菡 冰
在利用MFC編寫應用程序尤其是涉及到數值分析與模擬程序時,要進行大量的數值運算,如在屏幕上顯示三維、二維圖形圖像就需要進行數據擬合、樣條以及插值等算法,而且為了保證精度,運算時數據點一般還采用浮點甚至雙精度浮點數,這樣應用程序就需要占用大量的CPU時間來完成相應的工作,一般持續幾分鐘、幾十分鐘甚至更多的時間。如果應用程序不輸出一些信息的話,則常常會讓人誤認為系統是否已經當掉。因此
Windows系統提供了一個函數:
LoadCursor(UINT nIDResource) const;
通過這個函數可以把鼠標的形狀改為沙漏來表明系統正處于一個耗時的過程。但是一般而言,這種改變很容易讓人忽略,并且不知道當前進程完成了多少,還剩下多少。
在MFC中提供了進程條控件CProgressCtrl類,利用該類可以很方便地顯示進程的完成狀況。關于進程條控件CProgressCtrl類的用法以及說明,具體可以參見Visual C++的聯機幫助。顯示當前進程的完成狀況,可以有很多種方法用進程條控件CProgressCtrl類來實現,如采用多線程編程方法,通過線程通信來顯示,也可以在同一線程中采用含進程條控件CProgressCtrl類的無模式對話框來顯示。但是這幾種方法都比較復雜且不方便,并需要占用一定的系統資源,狀態顯示響應也不太迅捷。
Windows應用程序一般在其底部有一個小條通稱狀態條。狀態條的右邊是幾個可以動態增加或刪除的狀態格。MFC中提供了狀態條控件CStatusBar類來完成狀態格的管理。因此我們可以在應用程序的狀態條中增加一個進程條狀態格來顯示當前進程任務的完成狀態。顯然,相對前面所述的方法,這種方法比較方便且容易實現,不占用系統資源,狀態顯示響應非常迅捷。下面闡述具體實現方法:
1、用AppWizard創建一個工程文件pBar,單文檔應用或者多文檔應用皆可。其他選項均可采用缺省。
2、在Visual Studio的工作臺中,選擇"View"菜單下的"Resource Symbols"菜單命令,彈出對話框后點擊"New"按鈕,增加一條新的符號ID_ INDICATOR_PROGRESS_PANE并采用系統分配的缺省ID值。如圖1所示。
(圖注ZHUANG-1) 圖1 增加一條符號ID_INDICATOR_PROGRESS_PANE
3、在MainFrm.cpp文件的狀態格指示數組(緊接在消息映射代碼段后)中增加資源符號ID_INDI-CATOR_PROGRESS_PANE或者其ID值。注意,如果將符號ID_INDI-CATOR_PROGRESS_PANE放在數組的最后,則表明進程條狀態格將在狀態條的最右邊;如果你將符號ID_INDICATOR_PROGRESS _PANE放在數組的前面,則表明進程條狀態格將在狀態條的最左邊;如果將符號ID_INDICATOR_PROGRESS _PANE放在數組的中間,則表明進程條狀態格將在狀態條的中間。具體參見如下代碼:
static UINT indicators[] =
{
ID_SEPARATOR, //
status line indicator
ID_INDICATOR_PROGRESS_PANE, //
means the progress pane in
far left.
ID_INDICATOR_CAPS,
ID_INDICATOR_NUM,
ID_INDICATOR_SCRL,
};
4、打開資源編輯器,選擇字符串表,單擊鼠標右鍵,選擇"New String"命令(或者通過工作臺的"Insert"菜單選擇"New String"命令),彈出字符串屬性編輯對話框如圖2所示。在String prorties對話框的ID欄中鍵入符號ID_INDICATOR_PROGRESS_ PANE,在Caption編輯欄鍵入空格。注意空格的多少將決定狀態條中進程狀態格的長度。具體見圖2。
(圖注ZHUANG-2) 圖2 增加符號ID_INDICATOR_PROGRESS_PANE的字符串
5、在頭文件MainFrm.h中,增加兩個變量,一個為CProgressCtrl控件,設為m_Progress;另一個為邏輯布爾變量,設為m_bCreated,該變量用來標志CProgressCtrl控件是否成功進行創建。
6、在源文件MainFrm.cpp的OnCreate()函數中,初始化m_bCreated 為 FALSE,如下所示:
m_bCreated = FALSE;
7、模擬一個耗時過程函數OnSomeLongProcess()來演示狀態條中的進程狀態格。這里簡單地采用睡眠函數來模擬一個耗時過程。函數代碼見程序1。
void CMainFrame::OnSomeLongProcess()
{
RECT MyRect;
// substitute 1 with the zero-based index of your status bar pane. For example, if you put your
// pane first in the indicators array, you put 0, second you put 1, etc.
m_wndStatusBar.GetItemRect(1, &MyRect);
if (m_bCreated == FALSE)
{
//Create the progress control
m_Progress.Create(WS_VISIBLE|WS_CHILD, MyRect, &m_wndStatusBar, 1);
m_Progress.SetRange(0,100); //Set the range to between 0 and 100
m_Progress.SetStep(1); // Set the step amount
m_bCreated = TRUE;
}
// Now we'll simulate a long process:
for (int I = 0; I <100; I++)
{
Sleep(20);
m_Progress.StepIt();
}
}
8、狀態條中的進程狀態格創建成功后,如果應用程序主窗口尺寸發生變化,則進程狀態格的大小不會自動適應主窗口的變化,因此需要重載主窗口的OnSize()函數。通過 ClassWizard在主窗口中增加WM_SIZE消息映射函數,如圖3所示。
(圖注ZHUANG-3) 圖3 利用ClassWizard在CmainFrame中增加WM_SIZE消息映射函數
具體的源代碼見程序2。
void CMainFrame::OnSize(UINT nType, int cx, int cy)
{
CFrameWnd::OnSize(nType, cx, cy);
// TODO: Add your message handler code here
if(m_bCreated == TRUE){
RECT rc;
m_wndStatusBar.GetItemRect(1, &rc);
// Reposition the progress control correctly!
m_Progress.SetWindowPos(&wndTop, rc.left, rc.top, rc.right -
rc.left,
rc.bottom - rc.top, SWP_SHOWWINDOW);
}
}
9、打開資源編輯器,在“查看”菜單下增加"Test"菜單命令,ID設為ID_TEST。然后利用ClassWizard增加一條消息映射函數OnTest(),代碼如下:
void CMainFrame::OnTest()
{
// TODO: Add your command
handler code here
OnSomeLongProcess();
在完成所有上述步驟后,編譯并運行程序。選擇“查看”菜單下的"Test"菜單命令就會看到狀態條中的進程狀態格的進程顯示情況,如圖4所示。
(圖注ZHUANG-4) 圖4 狀態條中的進程狀態格的進程顯示
上面我們用一個簡單的睡眠函數模擬了耗時過程中狀態條的進程狀態格的顯示情況。在實際應用中我們只需將源碼中的OnSomeLongProcess()函數替換成相應的耗時過程函數即可。
?。ㄗ髡叩刂罚何錆h華中理工大學電子科學與技術系 430074 收稿日期:1999.5.28)
原文轉自:http://www.anti-gravitydesign.com