Programowanie Windows

Programowanie aplikacji Windows w Visual C++ jest wprawdzie bardziej pracochłonne niż budowa aplikacji za pomocą narzędzi RAD, ale daje za to kontrolę nad każdym aspektem działania programu, co jest szczególnie istotne, jeśli mamy zamiar napisać grę.

Programowanie aplikacji Windows w Visual C++ jest wprawdzie bardziej pracochłonne niż budowa aplikacji za pomocą narzędzi RAD, ale daje za to kontrolę nad każdym aspektem działania programu, co jest szczególnie istotne, jeśli mamy zamiar napisać grę.

Wykorzystanie ogromnej mocy biblioteki DirectX wymaga umiejętności pisania programów do systemu Windows. Nie oznacza to, że w najbliższym czasie czekają cię tygodnie studiowania książek, analizy programów i pisanie tysięcy wierszy kodu, zanim uda ci się wyświetlić na ekranie pierwszego potwora. Aby rozpocząć zabawę, naprawdę nie trzeba się dużo natrudzić. Wystarczy nauczyć się tworzenia szablonowej aplikacji do Windows i w miarę dobrze poznać mechanizmy sterujące jej pracą. Jeżeli dodamy do tego jeszcze kilka prostych funkcji graficznych GDI, będziesz mógł napisać swoją pierwsza prostą grę. Właśnie tym będziemy się teraz zajmować. Nauką pisania podstawowej aplikacji do Windows. Przekonasz się później, że stanowi ona punkt wyjściowy do napisania każdej gry do tego systemu, korzystającej z biblioteki DirectX. Nawet takiej, jak najnowszy "Doom" czy "Comanche".

Praca programów w Windows

Pracując z Windows, zwykle uruchamiasz wiele aplikacji naraz i masz wrażenie, że wykonują się równocześnie. Jest to możliwe, bo system i aplikacje pracują w specyficzny sposób. Gdy zażądasz uruchomienia programu, system załaduje go do pamięci, przydzieli mu początkowe zasoby i przekaże do wykonywania. Gdy uruchomisz kolejny program, system będzie na zmianę raz jednemu, raz drugiemu przydzielał fragment czasu procesora. Gdy uruchomisz jeszcze jeden program, czas procesora będzie dzielony już pomiędzy trzy aplikacje. Zmiana aplikacji mającej dostęp do procesora odbywa się szybko i dlatego masz wrażenie, że programy pracują jednocześnie. Liczba programów, które możesz uruchomić, zależy od dostępnych w systemie zasobów, takich jak pamięć operacyjna czy wolne miejsce na twardym dysku. Jeżeli system potrafi nadzorować jednocześnie pracę wielu aplikacji, mówimy o wielozadaniowości. Aby mógł dobrze realizować taki tryb pracy, wymaga od aplikacji pewnego rodzaju współpracy. Uruchomiony program powinien co jakiś czas zwracać systemowi sterowanie. Jeżeli tego nie zrobi, może częściowo lub całkowicie zakłócić jego pracę. Windows nie jest w takiej sytuacji bezbronny. Jeżeli program nie odpowiada, potrafi zakończyć jego działanie. W najlepszym wypadku skończy się to dla nas bez przykrych konsekwencji, a w najgorszym możemy utracić dane lub je uszkodzić.

Tym krótkim wstępem chcieliśmy zwrócić uwagę na sposób pisania programów na platformę Windows. Program nie stanowi zamkniętego bloku kodu, który po uruchomieniu żyje własnym życiem i oddaje sterowanie do systemu wtedy, gdy uzna to za stosowne. Musi przez cały czas liczyć się z pozostałymi aplikacjami, które mogą być w danej chwili uruchomione. Jeżeli coś rysujesz, zadbaj, aby rysowanie odbywało się tylko w oknie należącym do aplikacji. Jeżeli przetwarzasz dużo danych, rób to etapami, aby nie zablokować systemu. Nasuwa się zatem pytanie: jak działają gry? Wymagają przecież całej mocy procesora, karty graficznej i muzycznej. Jeżeli gra przełącza się w tryb pełnoekranowy, uzyskuje najpierw wyłączność na korzystanie z urządzeń graficznych i muzycznych, odcinając od nich pozostałe aplikacje. Nie może tylko przejmować kontroli nad procesorem. Musi on być w danej chwili wolny. Osiąga się to, wyłączając przed uruchomieniem gry wszystkie zbędne programy. Gry pracujące w trybie okienkowym powinny działać jak standardowe aplikacje i uwzględniać to, że użytkownik w każdej chwili może chcieć podjąć pracę z innym programem.

Pierwsze okna

Zanim przystąpimy do pisania właściwego programu, utworzymy najpierw w ramach treningu prostą aplikację wyświetlającą okno komunikatu. Dowiesz się dzięki temu, jak przygotować projekt aplikacji graficznej. Poznasz także obowiązkową funkcję WinMain i bardzo przydatną MessageBox. Uruchom Visual C++. Rozwiń menu File i wybierz polecenie New. W wyświetlonym oknie New przejdź do karty Projects. Na liście możliwych do utworzenia projektów zaznacz element Win32 Application.

W pole Project Name wpisz nazwę projektu, np. Okno komunikatu. W polu Location ustal ścieżkę określającą położenie katalogu projektu. Naciśnij przycisk OK. Na ekranie ukaże się kolejne okno dialogowe, tym razem o nazwie Win32 Application Step 1 of 1. Zaznacz opcję An empty project, która oznacza tworzenie pustego projektu, niezawierającego żadnych plików. Naciśnij przycisk Finish. Kolejne wyświetlone okno to New Project Information. Zawiera podsumowanie dotyczące tworzonego projektu. Zamknij je, naciskając przycisk OK.

W tym momencie masz utworzoną przestrzeń roboczą wraz z projektem. Kolejny etap to dodanie do projektu formularza kodu. Ponownie rozwiń menu File i wybierz polecenie New. W wyświetlonym oknie New przejdź do karty Files. Zaznacz element C++ Source Code. Upewnij się, że opcja Add to project jest zaznaczona. W polu File Name ustal nazwę tworzonego pliku na WinMain. Na koniec naciśnij przycisk OK. To wszystko, możesz zacząć pisać kod programu.

Dla aplikacji graficznych główną funkcją jest WinMain (od niej zaczyna się wykonywanie programu). Deklaracja jej nagłówka znajduje się w pliku Winbase.h. Nie będziemy tego pliku dołączać do kodu bezpośrednio. Użyjemy pliku Windows.h, który włącza plik Winbase.h i wiele innych. Zawierają one nagłówki większości podstawowych funkcji systemu, definicje typów danych oraz przydatnych makr. Przeanalizujmy nagłówek funkcji WinMain.

int WINAPI WinMain(

HINSTANCE hInstance, HINSTANCE hPrevInstance

LPSTR lpCmdLine, int nCmdShow);

Jak widzisz, ma cztery parametry. Pierwszy - hInstance - to 32-bitowa wartość określająca uchwyt aplikacji. Jest numerem identyfikacyjnym programu, ustalanym przez system. Przekazuje go aplikacji, ponieważ trzeba z niego korzystać. Nie musisz go przechowywać w jakieś zmiennej globalnej, w razie konieczności można go łatwo i szybko określić. Powiemy o tym później. Parametr hPrevInstance to pozostałość po systemie Windows w wersji 3.1. Obecnie nie jest używany i zawsze ma wartość NULL. Pierwotnie zawierał uchwyt ostatniej uruchomionej kopii aplikacji. Jeżeli programista nie chciał, żeby użytkownik uruchamiał kilka kopii aplikacji, musiał tylko sprawdzić wartość wspomnianego uchwytu. Jeżeli była różna od NULL, oznaczało to, że jedna kopia programu już jest, zatem należało zakończyć pracę bieżącej. W nowszych wersjach Windows do wykrywania kopii aplikacji, zaleca się stosowanie tzw. muteksów, ale to zagadnienie na razie nas nie interesuje. Z pewnością zastanawiasz się, czym jest wartość NULL. W wypadku programów pisanych w konwencji C++ akurat jest równa zeru. Nie uznawaj tego jednak z pewnik, w przypadku innych kompilatorów może jej odpowiadać inna wartość. Parametr lpCmdLine zawiera adres łańcucha znaków będącego ścieżką wywołania programu. Nie zawiera ona nazwy programu, a wyłącznie poszczególne parametry wywołania. Parametr nCmdShow określa, jak program powinien być wyświetlony zaraz po uruchomieniu - w formie zminimalizowanej lub z zmaksymalizowanej. Jest to tylko pewna sugestia i nie należy się nią przejmować.

Funkcja WinMain zwraca wartość typu int, która powinna wynosić zero. Identyfikator WINAPI określa konwencję wywoływania funkcji używaną do funkcji systemowych.

Jeżeli użyjemy w programie samej funkcji WinMain, to nie wykona on właściwie żadnej pracy. Dlatego dodatkowo zastosujemy funkcję MessageBox do wyświetlenia prostego okna komunikatu. Z oknami tego typu stykasz się za każdym razem, gdy pracujesz w Windows. Służą do interakcji z użytkownikiem, pobierania od niego informacji. Okna komunikatu wyświetlane przez funkcję MessageBox są w rzeczywistości modalnymi oknami dialogowymi, blokującymi dalszą pracę programu do chwili ich zamknięcia. Można tym procesem dowolnie sterować, ale nie będziemy aż tak dokładnie wnikać w możliwości funkcji MessageBox. Przyjrzymy się nagłówkowi nowej funkcji, znajdującym się w pliku winuser.h.

int MessageBox(

HWND hWnd, LPCTSTR lpText

LPCTSTR lpCaption, UINT uType);


Zobacz również