Artur Poznański
PROGRAMOWANIE
W WINDOWS 95
Kraków 2000
1. WPROWADZENIE
Postanowiłem napisać kolejny tekst o moich przygodach programistycznych, tym razem z systemem Windows 95. Aby skorzystać z zawartych tutaj informacji będziesz potrzebował trzech rzeczy:
· znajomości języka C
· kompilatora tworzącego 32-bitowy kod (np. Visual C++ 5.0 )
· chęci i cierpliwości
Jeżeli nie masz którejś z tych rzeczy, to dalsze czytanie niestety nie ma wielkiego sensu. Napisałem też tekst pt. „Programowanie w języku C dla chętnych” i jeżeli nie spełniasz pierwszego warunku to gorąco zachęcam, aby wpierw go przeczytać. Przedstawione poniżej przykładowe programy będą działały na systemach Windows 95, 98 i NT. Ja używałem kompilatora MS Visual C++ 5.0 firmy Microsoft z pakietu Visual Studio 97 (w skrócie VC++).
2. KOMPILACJA I URUCHAMIANIE
W VC++ wpierw tworzymy projekt wybierając File -> New -> Projects -> Win 32 Application i przed wciśnięciem OK w pole Project name wpisujemy „api” zaś w pole Location wpisujemy „C:\VCPP\API”. W tym momencie powstaną nam pliki api.dsp (projekt) i api.dsw (obszar roboczy). Kolejny krok to stworzenie pliku. Klikamy na File
->New -> Files -> C++ Source File. W polu File name wpisujemy „ap1.c”. Teraz powstanie plik o nazwie ap1.c, do którego można wpisać poniższy kod.
#include <windows.h>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
MessageBox(NULL, "Witaj mistrzu!", "ap1",MB_OK);
return 0;
}
Kompilacja następuje po naciśnięciu klawisza F7. Jeśli nigdzie nie zrobiłeś błędu, to na dole pojawi się tekst „api.exe - 0 error(s), 0 warning(s)” i będzie można nasz program uruchomić kombinacją Ctrl+F5. Ukaże się okienko z jednym przyciskiem OK i tekstem „Witaj mistrzu!”. Okno można zamknąć naciskając przycisk ok, lub kombinacją Alt+F4 jak każdą aplikację Windows 95. Nie zapomnij zapisać pliku (Ctrl+S). Spróbuj teraz zamknąć kompilator i wejść do katalogu z gotowym plikiem. Będzie to api.exe w katalogu C:\VCPP\API\Debug\. Uruchom go i sprawdź jego objętość (ok. 80 kb). Moje gratulacje, właśnie stworzyłeś program pod Windows 95.
3. DEBUG I RELEASE
Kompilator może stworzyć dwie wersje programu. Większą, z informacjami dla debuggera w katalogu Debug lub mniejszą - bez tych informacji - o nazwie Release.
Otwórz jeszcze raz ten sam projekt i plik.(File ->Open Workspace->api.dsw lub File->Recent Workspaces->api). Następnie wybierz Build->Set Active Configuration ->api – Win32 Release i daj na OK. Skompiluj i zajrzyj do powstałego katalogu Release. Będzie tam mniejsza wersja api.exe o wielkości ok. 20 kb. Tak więc sam się przekonałeś, dlaczego gotowy program znajduje się w katalogu Debug bądź Release.
4. FUNKCJA MESSAGEBOX
Przyjrzyjmy się naszemu jedynemu programowi. Ma on zamiast main funkcję WinMain. Na razie całkiem pominę pierwszą linię tej funkcji i omówię MessageBox. Jej pierwszy argument to tzw. uchwyt. Jest to jakby dowód osobisty tej funkcji, który stwierdza do jakiego okna ona przynależy. W związku z tym, że nasza funkcja nie ma właściciela, daliśmy NULL. Drugi i trzeci argument to tekst w okienku i na pasku tytułowym. Ostatni argument określa typ okienka. Nasz następny program pokaże inną stałą MB (MB to skrót od Message Box).
Przykład2 – ap2.c
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
MessageBox(NULL, "Czy chcesz wyjść z programu?","Pytanie",
MB_YESNO|MB_ICONQUESTION);
Po otwarciu poprzedniego projektu, kliknij na zakładkę FlieView, po czym skasuj plik „ap1.c” (Del). Następnie dodaj plik „ap2.c” (Project -> Add To Project ->Files -> ap2.c). Po uruchomieniu pojawiają się dwa przyciski (Tak i Nie) oraz ikona ze znakiem zapytania. Na razie obojętne co naciśniesz, a i tak program się zakończy, ale w przyszłości użyjemy tej funkcji do bardziej praktycznych zastosowań. Jeszcze jedna ważna rzecz. Funkcja MessageBox zwraca nam wartość typu int w zależności od tego, jaki przycisk naciśniemy.
int i;
while(i!=IDYES)
i=MessageBox(NULL, "Czy chcesz wyjść z programu?","Pytanie", MB_YESNO|MB_ICONQUESTION);
Jak widać, tym razem program chodzi w kółko dzięki pętli while i sprawdzaniu zwracanej wartości przez funkcję MessageBox.
5. ŚCIEŻKA POLECEŃ
Jeszcze jedna przeróbka pierwszego programu, która daje ciekawy efekt.
Przykład4 –ap4.c
MessageBox(NULL, szCmdLine,"ap4",MB_OK);
Co program umie? Gdy go uruchomisz, żaden napis się nie pojawi, lecz gdy po skompilowaniu uruchomisz z argumentami, to zostaną one wyświetlone jako tekst w oknie dialogowym . Możesz też wpisać argumenty programu w kompilatorze ( Project -> Settings -> Debug pole Program arguments). Wpisz tam na przykład tekst „ala ma kota” i uruchom program. Podsumowując rozszyfrowaliśmy, że szCmdLine jest to wskaźnik do ścieżki poleceń o typie PSTR (Pointer to STRing = wskaźnik do łańcucha).
6. SZKIELET PROGRAMU
Przejdziemy do rzeczy nieco trudniejszych więc proszę o wyrozumiałość i cierpliwość. Przejdę od razu do przykładu, który mam nadzieję, że Cię nie przerazi.
Przykład 5 - ap5.c
LRESULT CALLBACK ProcOkna(HWND, UINT, WPARAM, LPARAM);
char szNazwaOkna[] = ”Moje okno";
LPSTR lpszArgs, int nWinMode)
HWND hwnd;
MSG msg;
WNDCLASSEX wc;
wc.hInstance = hInstance;
wc.lpszClassName = szNazwaOkna;
wc.lpfnWndProc = ProcOkna;
wc.style = 0;
wc.cbSize = sizeof(WNDCLASSEX);
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); // duża ikona
wc.hIconSm = LoadIcon(NULL, IDI_WINLOGO); // mała ikona
wc.hCursor = LoadCursor(NULL,IDC_ARROW); // styl kursora
wc.lpszMenuName = NULL; // brak menu
wc.cbClsExtra=0;
wc.cbWndExtra=0;
wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); // tło na biało
// rejestracja klasy okna
if (!RegisterClassEx(&wc))
MessageBox(NULL, „Nieudana rejestracja klasy okna”,"Błąd",MB_OK|MB_ICONEXCLAMATION);
hwnd = CreateWindow(
szNazwaOkna, // nazwa okna
"szkielet Windows 95", // tytuł
WS_OVERLAPPEDWINDOW, // styl - normalny
CW_USEDEFAULT, // początkowe x
CW_USEDEFAULT, // początkowe y
CW_USEDEFAULT, // szerokość
CW_USEDEFAULT, // wysokość
HWND_DESKTOP, // brak okien-rodziców
NULL, // brak menu
hInstance, // uchwyt instancji
NULL // brak dodat. argumentów
);
ShowWindow(hwnd, nWinMode); // wyświetlenie okna
UpdateWindow(hwnd);
// pętla komunikatów
while(GetMessage(&msg, NULL, 0, 0))
TranslateMessage(&msg);
DispatchMessage(&msg);
return msg.wParam;
LRESULT CALLBACK ProcOkna(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
switch(message)
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, message, wParam, lParam);
Uff. Po uruchomieniu pojawia się okienko, które można przesuwać, chować do paska, zmieniać rozmiar itp. Teraz będzie minimum wyjaśnień, byśmy mogli ruszyć dalej. Program w Windows 95 jest sterowany zdarzeniami. Zdarzenia to np. naciśnięcie przycisku, przesunięcie myszy itd... Każdemu zdarzeniu odpowiada wysyłany przez system do twojego programu komunikat. Komunikat to pewna struktura typu MSG z sześcioma polami. Zauważ, że w kodzie są dwie funkcje: WinMain i ProcOkna. Ta druga nie jest wywoływana z WinMain, lecz przez system operacyjny. Robi on to prawie bez przerwy przekazując jej jako parametry cztery pola ze struktury MSG. Zatem w ten sposób Windows wysyła do okna komunikaty. Mają one nazwę zaczynającą się WM (np. WM_DESTROY). Oto co się dzieje, gdy uruchomisz program i klikniesz na ikonę X, czyli go zamkniesz.
1. Wywołana jest procedura okna, bo nastąpiło zdarzenie.
2. Parametr stanowi komunikat WM_DESTROY, bo tak działa Windows
3. Wywołana zostaje funkcja PostQuitMessage (wysyła WM_QUIT)
4. Komunikat WM_QUIT sprawia, że GetMess...
Automation_Engineering