歷史
在數字運算機發明之前,就已經有了進度條的概念。1896 年,Karol Adamiecki(波蘭人;經濟學家,工程師和管理研究人員),發明了一種叫做harmonogram(波蘭語,時間表)的圖表;1903年,他的理論在俄羅斯技術界引起了轟動。他在波蘭雜誌《 Przegląd Techniczny 》發表了一些文章(1909)。 1931年,他發表了一篇更廣為人知的文章《armonogram or harmonograf.》(波蘭語,日程或時間表),描述他的圖。Adamiecki只是在波蘭和俄羅斯發表這些文章,較少被英語國家了解。
同一時間,亨利·甘特(Henry Gantt)提出類似的方法已在西方普及,他在1910年和1915年都發表過文章。算是以訛傳訛吧,Adamiecki的圖表就被叫做為甘特圖。這個概念後來被用於計算領域。
處理方法
以檔案處理為例
單個檔案的進度處理方法:
使用CopyFileEx進行檔案複製,這個函式專門提供了一個
回調函式用來處理你的進度條,詳細參見MSDN。
總體進度的處理方法:
如果一批檔案,首先獲得檔案的數量count = 檔案數量
設定進條的範圍為0至count,每完成一個檔案,就向前進一步。
C語言
(來自網路)
C檔案
#include <windows.h>
#include <commctrl.h> //InitCommonControls
//過程函式的返回值都是LRESULT,類型都是CALLBACK
LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR lpszCmdLine,int nCmdShow)
{
HWND hwnd; //主視窗句柄,在CreateWindow中賦值
MSG msg; //訊息變數,在GetMessage中使用
WNDCLASS wndclass; //視窗類
TCHAR* szAppName = TEXT("ProgressBar"); //類名和視窗名
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); //視窗背景
wndclass.hCursor = LoadCursor(NULL,IDC_ARROW); //滑鼠
wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATION); //圖示
wndclass.lpszClassName = szAppName; //類名
wndclass.cbClsExtra = 0; //類的額外參數
wndclass.cbWndExtra = 0; //視窗的額外參數.用於基於同一視窗類的視窗各自區分.
//在自定義對話框類時必須指定為DLGWINDOWEXTRA的大小
wndclass.lpszMenuName = NULL; //選單名.可以用作子視窗的id
wndclass.style = CS_HREDRAW | CS_VREDRAW; //視窗風格
wndclass.lpfnWndProc = WndProc; //視窗過程
wndclass.hInstance = hInstance; //包含視窗過程的實例句柄
if( !RegisterClass(&wndclass) ) //註冊視窗類
return 0;
hwnd = CreateWindow( //創建視窗
szAppName, //視窗類名
szAppName, //視窗標題
WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX, //視窗風格
CW_USEDEFAULT, //初始的x坐標
CW_USEDEFAULT, //初始的y坐標
480, //初始的寬度
200, //初始的高度
NULL, //父視窗
NULL, //選單
hInstance, //和視窗相關的實例句柄
NULL //額外參數
);
ShowWindow( hwnd,nCmdShow ); //顯示視窗
UpdateWindow( hwnd ); //更新視窗
while( GetMessage(&msg,NULL,0,0) ) //訊息循環
{
TranslateMessage(&msg); //將WM_XXXKEYXXX訊息翻譯為WM_CHAR訊息
DispatchMessage(&msg); //傳遞訊息到視窗過程
}
return msg.wParam; //返回
}
DWORD WINAPI PBThreadProc( LPVOID lpParameter )
{
HWND hwndPB = (HWND) lpParameter; //進度條的視窗句柄
PBRANGE range; //進度條的範圍
SendMessage( hwndPB, PBM_SETRANGE, //設定進度條的範圍
(WPARAM)0, (LPARAM)(MAKELPARAM(0,100)) );
SendMessage( hwndPB, PBM_GETRANGE, //獲取進度條的範圍
(WPARAM)TRUE, //TRUE 表示返回值為範圍的最小值,FALSE表示返回最大值
(LPARAM)&range );
while(TRUE)
{
SendMessage( hwndPB, PBM_DELTAPOS, //設定進度條的新位置為當前位置加上範圍的1/40
(WPARAM)((range.iHigh-range.iLow)/40), (LPARAM)0 );
if( SendMessage( hwndPB, PBM_GETPOS, (WPARAM)0, (LPARAM)0 ) //取得進度條當前位置
== range.iHigh )
{
SendMessage( hwndPB, PBM_SETPOS, (WPARAM)range.iLow, (LPARAM)0 ); //將進度條復位
}
Sleep(1000); //每1秒更新一次進度條
}
}
LRESULT WINAPI WndProc( HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam )
{
static HWND hwndPB;
switch( message )
{
case WM_CREATE:
{
InitCommonControls(); //確保已註冊了進度條類PROGRESS_CLASS
hwndPB = CreateWindowEx(
0,
PROGRESS_CLASS,
NULL,
WS_CHILD | WS_VISIBLE,
0,0,0,0, //位置和大小在WM_SIZE中設定
hwnd,
(HMENU)0,
((LPCREATESTRUCT)lParam)->hInstance,
NULL);
CreateThread( //操作進度條的執行緒
NULL,
0,
(LPTHREAD_START_ROUTINE)PBThreadProc,
hwndPB,
0,
0
);
return 0;
}
case WM_SIZE:
{
RECT rc;
GetClientRect(hwnd, &rc);
MoveWindow(
hwndPB,
rc.left,
(rc.bottom - rc.top )/4,
rc.right - rc.left,
(rc.bottom - rc.top )/10,
TRUE
);
return 0;
}
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc( hwnd,message,wParam,lParam );
}
樣式的修改
可以用到資源檔案(.rc)
//
// SUPPORT FOR WINDOWS XP THEMES:
// THIS WILL MAKE THE PROGRAM USE THE COMMON CONTROLS
// LIBRARY VERSION 6.0 (IF IT IS AVAILABLE)
//
1 24 "CtrlProgressBar.exe.Manifest"