Kreiranje prozora s Windows API
U prethodnom primjeru prikazano je kako se ispisuje prozor s porukom. Nažalost, ne postoji jedna funkcija za kreiranje forme. Razlog tome je što je Windows forma složen objekt sa puno parametara. Drugi razlog je što je potrebno implementirati upravljanje događajima poput pritisaka tipki, klikanje mišem itd. Kad se dogodi neki događaj poput pritiska neke tipke, Windows šalje poruku aplikaciji koja obrađuje događaje preko WinProc() procedure.
U donjem kodu se vidi način na koji se kreira samo jedna Windows forma. Radi se o priličnom broju linija, ali je ohrabrujuće to što se ovdje samo radi o kostruru tj. ovaj dio ostaje nepromijenjen kasnije kad se u to uključi i Direct3D. U programu se koristi procedura WindowProc() koja se aktivira kad se dogodi neki događaj, odnosno, kad ga Windows detektira. Nakon toga se u switch selekciji ispituje događaj, obavljaju se neke akcije. Ako nije došlo do akcija tada se poziv prosljeđuje Windowsima (ako je potrebno napraviti neke sustavske poslove).
Prozor je kreiran pomoću CreateWindowEx funkcije koja se nalazi u <windowsx.h> datoteci. Prethodno je trebalo registrirati kalsu prozora, postaviti različite parametre (detalje je moguće pogledati u MSDN dokumentacija za Windows API).
// ukljuci headere za windows API
#include <windows.h>
#include <windowsx.h>
// prototip funkcija WindowProc za obradu poruka
LRESULT CALLBACK WindowProc(HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam);
// pocetak glavnog programa
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// handle za prozor
HWND hWnd;
// struktura koja sadrzi opis novog prozora
WNDCLASSEX wc;
// resetiraj podatke u wc
ZeroMemory(&wc, sizeof(WNDCLASSEX));
// popuni opis prozora
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
wc.lpszClassName = L"WindowClass1";
// registriraj klasu prozora
RegisterClassEx(&wc);
// kreiranje prozora
hWnd = CreateWindowEx(NULL,
L"WindowClass1", // naziv klase
L"Novi Win32 prozor", // naslov na prozoru
WS_OVERLAPPEDWINDOW, // stil prozora (ispred svih)
300, // x-pozicija
300, // y-pozicija
500, // duljina prozora
400, // visina prozora
NULL, // nema prozora roditelja, NULL
NULL, // ne koristi se izbornik, NULL
hInstance, // handle za aplikaciju
NULL); // ne koristi se s vise prozora, NULL
// prikazi prozor na ekranu
ShowWindow(hWnd, nCmdShow);
// kreni u glavnu petlju:
// struktura koja sadrzi podatke o poruci
MSG msg;
// cekaj novu poruku, kad stigne spremi je u strukturu msg
while(GetMessage(&msg, NULL, 0, 0))
{
// prevedi poruku koja je stigla s tipkovnice (znakovi)
TranslateMessage(&msg);
// posalji poruku na obradu proceduri WinProc
DispatchMessage(&msg);
}
// vrati poruku o izlazu WM_QUIT windowsima
return msg.wParam;
}
// funkcija koja je glavni upravitelj porukama u programu
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
// saznaj o kakvoj se poruci radi
switch(message)
{
// ako je prozor zatvoren
case WM_DESTROY:
{
// zatvori aplikaciju
PostQuitMessage(0);
return 0;
} break;
}
// upravljanje sistemskim porukama koje switch nije obradio
return DefWindowProc (hWnd, message, wParam, lParam);
}
Za upravljanje događajima se koristi while petlja u kojoj se pomoću funkcije GetMessage() ispituje OS je li stigla nova poruka (u poruci se nalazi opis događaja). Kad je došla nova poruka tada se prosljeđuje proceduri WinProc na obradu.
Kad se malo bolje razmisli, ovakav nađin obrade događaja će predstavljati problem za Direct3D. Slika se u prozoru treba stalno renderirati, ali u ovom slučaju se renderira samo onda kad npr. korisnik pritisne neku tipku ili pomakne miš. Zato su potrebne dodatne promijene da bi se logika prilagodila Direct3d-u.
C++ kod: KreiranjeProzora.cpp
Slijedi: Upravljanje događajima
Sadržaj
Linkovi
