www.codeworx.org/directx_tuts/Pre DirectX Tutorial: Teil 2 - Windows Klassen I

Pre DirectX Tutorial: Teil 2 - Windows Klassen I

Hallo Halli!

Ich sehe schon, diese Tutorial wird zu einer Ausrede...jedenfalls setze ich mich immer daran, wenn ich nix mehr "gescheites" machen will. ;)

Egal, das letzte Mal sind wir zum Planeten X aufgebrochen. Zur Zeit durchqueren wir unser Universum namens Windows und nähern uns langsam aber sicher. Wir hatten einen ersten Einblick in dieses Universum und nun steigen wir richtig ein: mit Windows Klassen.

Jedes Fenster egal ob Dialog Box, Message Box oder Vollbild benötigt eine Windows Klasse. Eine Klasse definiert das Fenster und seine Attribute. Also das Aussehen, das Verhalten und sonst alles Mögliche. Natürlich gibt es (wie bei fast allem in Windows) Standard-Klassen, aber im wirklichen Leben werdet ihr wohl für jede Applikation eine eigene Klasse definieren.

Ich will jetzt nicht lang und breit über Windows Klassen und deren Möglichkeiten reden. Erstens Mal ist das Thema sehr umfangreich und zweitens Mal braucht ihr nicht wirklich alles über sie zu wissen. Im Grunde werden wir nur zwei bestimmte Fälle besprechen: DirectX Fenster auf Desktop und DirectX Fenster Vollbild.

Also Leute: DAS ist eine Windows Klasse:

--------------------------------------------------------------------------------

typedef struct _WINDCLASSEX
 {
   UINT cbSize;
   UINT style;
   WNDPROC lpfnWndProc;
   int cbClsExtra;
   int cbWndExtra;
   HANDLE hInstance;
   HICON hIcon;
   HCURSOR hCursor;
   HBRUSH hbrBackground;
   LPCTSTR lpszMenuName;
   LPCTSTR lpszClassName;
   HICON hIconSm;
   } WNDCLASSEX;


--------------------------------------------------------------------------------

Tataa! Schick, oder? Das ist die Struktur einer neuen Windows Klasse. Eine von diesen Dingern müsst ihr erzeugen und dann die Werte eintragen - dann habt ihr eure eigene Windows Klasse. Schritt für Schritt:

WNDCLASSEX winclass; So, hier gehen wir es an. So nebenbei: Es gibt außer WNDCLASSEX noch WNDCLASS, aber jene ist die ältere Datenstruktur von beiden (daher auch das EX - für Extended). Über WNDCLASS solltet ihr euch wenig Gedanken machen, ist so gut wie überholt und vergessen.

cbSize: Sehr wichtiges gleich zum Einstieg. Hier wird die Größe unserer WNDCLASSEX Struktur eingetragen. Ich sehe es anhand eurer Fragezeichen: wozu sollte man da die Größe eintragen, immerhin muß eine Struktur doch nicht ihre eigene Größe wissen!? Mr Petzhold findet dieses Feld unwichtig aber Mr. LaMothe begründet sie so: wenn diese Struktur als Pointer übergeben wird kann der Empfänger anhand dieses Feldes die Größe leichter bestimmen. Deshalb sollte man sie folgendermaßen setzen: winclass.cbSize = sizeof(WNDCLASSEX);.

style: Dieses Feld hat Tonnen von Flags, die durch ein OR verbunden werden können. Ein paar Beispiele: CS_REDRAW (zeichnet das Fenster neu, wenn es der Nutzer bewegt); CS_VREDRAW / CS_HREDRAW (zeichnet das Fenster neu, wenn der Nutzer seine Größe verändert hat); CS_OWNDC (wichtig, bindet einen eigenen Device Context an unser Fenster - mehr dazu später); CS_NOCLOSE (deaktiviert das "schließen" Feld am Fenster); CS_DBLCLKS (sendet eine Nachricht wenn der User in unserem Fenster doppelklickt). Das sind nur einige, wenn ihr mehr wollt: nachschlagen ;). Wir nutzen erst einmal folgende Flags: winclass.style = CS_VREDRAW | CS_HREDRAW | CS_OWNDC | CS_DBLCLICKS;

lpfnWndProc: Das ist ein Pointer zu unserer WndProc Routine. Erinnert ihr euch noch? Im ersten Teil sagte ich Windows sei Event Driven und jene Nachrichten würden auch an euer Programm geschickt und ihr bräuchtet eine Schnittstelle? Nun, diese Schnittstelle ist WndProc. Dort werdet ihr auf jene Events reagieren, doch jene Prozedur nehmen wir uns irgendwann vor ;) Im Moment genügt es zu wissen, daß man hier folgendes einträgt: winclass.lpfnWndProc = WinProc;

cbClsExtra und cbWndExtra: brauchen wir nicht, setzen wir auf 0: winclass.cbClsExtra = 0; und winclass.cbWndExtra = 0;.

hInstance: siehe erster Teil. winclass.hInstance = hInstance;

hIcon: Juchu, unser Icon ;) Wir nehmen erst mal das 0815 Icon: winclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);

hCursor: Unser Cursor. Auch hier Standart winclass.hCursor = LoadCursor(NULL, IDC_ARROW);

hbrBackground: Das ist die Hintergrundfarbe eurer Applikation. Wäre aber zu einfach nur eine Farbe zu definieren, nein, da das GDI (Graphics Device Interfae) kompliziert ist, müssen wir auch die Art eintragen mit der wir sie haben wollen. winclass.hbrBackground = GetStockObject(WHITE_BRUSH);

lpszMenuName: Das ist der Name unseres Menus (falls wir eins wollen). Im Moment nicht, also: winclass.lpszMenuName = NULL;

lpszClassName: So, jetzt benennen wir unsere soeben definierte Klasse. winclass.lpszClassName = "WINCLASS1";. Und damit taufe ich dich auf den Namen "Winclass1"...oder so ;)

hIconSmDas ist nichts anderes als ein Handle zu dem Icon in der Titelleiste und der Startleiste. Nett, gell? winclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

Und das ist es! Das ist unsere Windows Klasse! Hier noch einmal im ganzen:

--------------------------------------------------------------------------------

winclass.cbSize = sizeof(WNDCLASSEX);
   winclass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
   winclass.lpfnWndProc = WindowProc;
   winclass.cbClsExtra = 0;
   winclass.cbWndExtra = 0;
   winclass.hInstance = hinstance;
   winclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
   winclass.hCursor = LoadCursor(NULL, IDC_ARROW);
   winclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
   winclass.lpszMenuName = NULL;
   winclass.lpszClassName = WINDOW_CLASS_NAME;
   winclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);


--------------------------------------------------------------------------------

Jaja, schon klar, das ist trockenes Material, man kann nicht damit herumspielen und wenn es alleine da steht kompiliert es sich nicht, aber das ist wichtig zu wissen! Kein Windows Programm ohne diesen Kram! Also, zieht euch eine Fanta 'rein und versucht zumindest zu erahnen worum es hier geht. Das nächste Mal öffnen wir dann endlich mal unser Fenster, dann wird euch sicher einiges klar.

Manche von euch werden sich sicher fragen "Wozu zur Hölle machen wir den Windows Quatsch per Hand und lassen das nicht den Visual Compiler übernehmen?". All diejenigen, die sich diese Frage gestellt haben bitte dort drüben an die Wand...fertig? Schießt Männer! Aber mal ernsthaft: bei DirectX Programmen geht es doch immer um Zeitkritischen Kram. Also warum zur Hölle wollt ihr 0815 Code nehmen anstatt eigenen Code von dem ihr wißt, daß er clean ist? Oder nehmt ihr auch HTML Editoren für eure Homepage? (nein, bitte nicht antworten, ich wäre von der Antwort nur deprimiert...).

Egal! Wir sind echte Coder! Wir packen das! ;)

Bis denne!

Delax
[delax@sundancerinc.de]