W tej lekcji nauczymy się posługiwać paskiem postępu. Używamy go do przedstawienia postępu jakiejś czynności, np. podczas instalacji programów. Ale przejdźmy do rzeczy.

Inicjacja kontrolki

Zakładam, że mamy już gotowe okno w projekcie, dołączone odpowiednie pliki, windows.h i commctrl.h, oraz bibliotekę do obsługi kontrolek.

Aby móc używać tej kontrolki musimy dodatkowo zainicjować klasę pasków, robimy to przy pomocy struktury INITCOMMONCONTROLSEX i funkcji InitCommonControlsEx().

...
INITCOMMONCONTROLSEX cc;
//struktura inicjacyjcna

cc.dwSize=sizeof(INITCOMMONCONTROLSEX);
cc.dwICC=ICC_BAR_CLASSES;
InitCommonControlsEx(&cc);
//funkcja inicjująca

...

Gdybyśmy teraz spróbowali skompilować projekt, kompilator zgłosił by, że nie istnieje struktura INITCOMMONCONTROLSEX. Dzieje się tak dlatego, że jedna ze zmiennych w kompilatore Dev C++, a dokładniej określająca wersję Internet Explorer, jest nie ustawiona. A dla poprawnego działania tej struktury jest postawiony warunek, że wersja Internet Explorer nie może być mniejsza niż 3.0 Oczywiście ta wersja jest już dostępna w Widnows 95, dlatego możemy spokojnie założyć, że użytkowanik ma wersję większą bądź równą 3.0 Robimy to deklarując definicję tej zmiennej dyrektywą define, przed dołączonymi plikami nagłówkowymi! W przykładzie deklaruję, że wersja IE wynosi 6.0 :

#define _WIN32_IE 0x0600
#include <windows.h>
#include <commctrl.h>
...

Tworzenie paska, czyli CreateWindowEx

...
hProgress=CreateWindowEx(
0
,PROGRESS_CLASS,
0
,WS_VISIBLE|WS_CHILD,
5
,
20
,
280
,
20
,hwnd,
0
,*hInst,
0
);
...

Mylę, że wszystko jasne i nic nie trzeba tłumaczyć. Jedynie mogę zaznaczyć, że w drugim parametrze podajemy PROGRESS_CLASS.

Obsługa kontrolki

Tutaj jak zwykle jeżeli chcemy coś ustawiać w kontrolce, wysyłamy odpowiednie komunikaty. Teraz poznamy kilka z nich.

PBM_SETRANGE
Komunikat ten służy do ustawienia zasięgu paska postępu. Trzeci parametr jest ignorowany, zaś czwarty to właśnie zasięg. Tutaj posługujemy się makrem MAKELONG, do stworzenia liczby 32 bitowej, z dwóch 16 bitowych. Pierwsza liczba 16 bitowa, to początek zasięgu pasak, zaś druga to koniec.

SendMessage(hProgress,PBM_SETRANGE,
0
,(LPARAM)MAKELONG(
0
,
100
));

PBM_SETPOS
Ten komunikat służy do ustawiania aktualnej pozycji postępu. Trzeci parametr to numer postępu we wcześniej ustalonym zakresie. Czwarty jest ignorowany.

SendMessage(hProgress,PBM_SETPOS,(WPARAM)
20
,
0
);

PBM_SETSTEP
Tym komunikatem ustawiamy długość pojedynczego kroku postępu paska. Standardowo jest on ustawiony na 10. Wartość kroku podajemy w trzecim parametrze, czwarty ignorujemy.

SendMessage(hProgress,PBM_SETSTEP,(WPARAM)
20
,
0
);

PBM_STEPIT
Służy do wykonywania kroku, czyli dodaniu do aktualnego stanu paska długości kroku, który wczeniej ustaliliśmy. Oba dodatkowe parametry ignorujemy.

SendMessage(hProgress,PBM_STEPIT
,0
,
0
);

Kolory w pasku

PBM_SETBARCOLOR
Tym komunikatem ustawiamy kolor paska postępu. Zmienna na kolor to COLORREF, a makro RGB służy do ustawienia koloru, podajemy w nim 3 kolejne składowe barwy koloru (więcej na ten temat w dziale GDI).

...
COLORREF clr=RGB(
33
,
99
,
256
);
SendMessage(hProgress,PBM_SETBARCOLOR,
0
,(LPARAM)clr);
...

PBM_SETBKCOLOR
Ten komunikat służy do ustawiania koloru tła w pasku, czyli pola pod paskiem.

...
COLORREF clr=RGB(
255
,
200
,
100
);
SendMessage(hProgress,PBM_SETBKCOLOR,
0
,(LPARAM)clr);
...

Oto przykład programu z paskiem postępu:

#define _WIN32_IE 0x0600
#include <windows.h>
#include <commctrl.h>

HWND hWnd,hProgress,hButton;
CHAR szClassName[]=
"OknoRodzica"
;
HINSTANCE* hInst;

LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);

INT WINAPI WinMain(HINSTANCE hInstance,HINSTANCE,LPSTR lStart,INT nShow)
{
  hInst=&hInstance;
  WNDCLASSEX wc;
  wc.hInstance=*hInst;
  wc.lpszClassName=szClassName;
  wc.lpfnWndProc=WndProc;
  wc.style=
0
;
  wc.cbSize=sizeof(WNDCLASSEX);
  wc.hIcon=LoadIcon(
0
,IDI_APPLICATION);
  wc.hIconSm=LoadIcon(
0
,IDI_APPLICATION);
  wc.hCursor=LoadCursor(
0
,IDC_ARROW);
  wc.lpszMenuName=
0
;
  wc.cbClsExtra=
0
;
  wc.cbWndExtra=
0
;
  wc.hbrBackground=(HBRUSH)COLOR_BACKGROUND;
  if(!RegisterClassEx(&wc)) return
0
;
  hWnd=CreateWindowEx(
0
,szClassName,
"Okno z \"paskiem postępu\""
,
  WS_OVERLAPPEDWINDOW,
20
,
20
,
350
,
130
,
0
,
0
,*hInst,
0
);
  ShowWindow(hWnd,nShow);
  //inicjacja klasy pasków
  INITCOMMONCONTROLSEX cc;
  cc.dwSize=sizeof(INITCOMMONCONTROLSEX);
  cc.dwICC=ICC_BAR_CLASSES;
  InitCommonControlsEx(&cc);
  MSG msgs;
  while(GetMessage(&msgs,
0
,
0
,
0
))
  {
    TranslateMessage(&msgs);
    DispatchMessage(&msgs);
  }
  return msgs.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd,UINT msg,WPARAM wPar,LPARAM lPar)
{
  COLORREF clr;
  switch(msg)
  {
    case WM_CREATE:
      
//tworzenie Progress'a

      hProgress=CreateWindowEx(
0
,PROGRESS_CLASS,
0
,WS_VISIBLE|WS_CHILD,
20
,
20
,
300
,
20
,hwnd,
0
,*hInst,
0
);
      
//zasięg ustawiamy od 0 do 100

      SendMessage(hProgress,PBM_SETRANGE,
0
,(LPARAM)MAKELONG(
0
,
100
));
      
//postęp(aktalny stan) ustawiamy na 5

      SendMessage(hProgress,PBM_SETPOS,(WPARAM)
5
,
0
);
      
//ustawiamy kolor paska

      clr=RGB(33,99,256);
      SendMessage(hProgress,PBM_SETBARCOLOR,
0
,(LPARAM)clr);
      
//kolor tła paska

      clr=RGB(255,200,100);
      SendMessage(hProgress,PBM_SETBKCOLOR,
0
,(LPARAM)clr);
      
//krok ustawiamy na 5

      SendMessage(hProgress,PBM_SETSTEP,(WPARAM)
5
,
0
);
      
//tworzenie przycisku

      hButton=CreateWindowEx(
0
,WC_BUTTON,
"Krok"
,WS_VISIBLE|WS_CHILD,
20
,
50
,
300
,
30
,hwnd,(HMENU)
1
,*hInst,
0
);
      break;
    case WM_COMMAND:
      
//gdy naciśniemy przycisk wykona się krok postępu

      if(wPar==
1
) SendMessage(hProgress,PBM_STEPIT,
0
,
0
);
      break;
    case WM_DESTROY:
      DestroyWindow(hProgress);
      DestroyWindow(hButton);
      PostQuitMessage(
0
);
      break;
    default:
      return DefWindowProc(hwnd,msg,wPar,lPar);
  }
  return
0
;
}