歷史
在數字運算機發明之前,就已經有了進度條的概念。1896年,KarolAdamiecki(波蘭人;經濟學家,工程師和管理研究人員),發明了一種叫做harmonogram(波蘭語,時間表)的圖表;1903年,他的理論在俄羅斯技術界引起了轟動。他在波蘭雜誌《PrzeglądTechniczny》發表了一些文章(1909)。1931年,他發表了一篇更廣為人知的文章《armonogramorharmonograf.》(波蘭語,日程或時間表),描述他的圖。Adamiecki只是在波蘭和俄羅斯發表這些文章,較少被英語國家了解。同一時間,亨利·甘特(HenryGantt)提出類似的方法已在西方普及,他在1910年和1915年都發表過文章。算是以訛傳訛吧,Adamiecki的圖表就被叫做為甘特圖。這個概念後來被用於計算領域。
處理方法
以檔案處理為例單個檔案的進度處理方法:
使用CopyFileEx進行檔案複製,這個函式專門提供了一個回調函式用來處理你的進度條,詳細參見MSDN。
總體進度的處理方法:
進度條
進度條
如果一批檔案,首先獲得檔案的數量count=檔案數量
設定進條的範圍為0至count,每完成一個檔案,就向前進一步。
C語言
(來自網路)C檔案
#include<windows.h>#include<commctrl.h>//InitCommonControls
//過程函式的返回值都是LRESULT,類型都是CALLBACK
LRESULTCALLBACKWndProc(HWNDhwnd,UINTmessage,WPARAMwParam,LPARAMlParam);
intWINAPIWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,LPTSTRlpszCmdLine,intnCmdShow)
{
HWNDhwnd;//主視窗句柄,在CreateWindow中賦值
MSGmsg;//訊息變數,在GetMessage中使用
WNDCLASSwndclass;//視窗類
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))//註冊視窗類
return0;
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);//傳遞訊息到視窗過程
}
returnmsg.wParam;//返回
}
DWORDWINAPIPBThreadProc(LPVOIDlpParameter)
{
HWNDhwndPB=(HWND)lpParameter;//進度條的視窗句柄
PBRANGErange;//進度條的範圍
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秒更新一次進度條
}
}
LRESULTWINAPIWndProc(HWNDhwnd,UINTmessage,WPARAMwParam,LPARAMlParam)
{
staticHWNDhwndPB;
switch(message)
{
caseWM_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
);
return0;
}
caseWM_SIZE:
{
RECTrc;
GetClientRect(hwnd,&rc);
MoveWindow(
hwndPB,
rc.left,
(rc.bottom-rc.top)/4,
rc.right-rc.left,
(rc.bottom-rc.top)/10,
TRUE
);
return0;
}
caseWM_DESTROY:
PostQuitMessage(0);
return0;
}
returnDefWindowProc(hwnd,message,wParam,lParam);
}
樣式的修改
可以用到資源檔案(.rc)//
//SUPPORTFORWINDOWSXPTHEMES:
//THISWILLMAKETHEPROGRAMUSETHECOMMONCONTROLS
//LIBRARYVERSION6.0(IFITISAVAILABLE)
//
124"CtrlProgressBar.exe.Manifest"