![]() |
||||||||||||||||||||||
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
||||||||||||||||||||||
tutorial anzeigen
Durch lesen dieses Artikels akzeptieren Sie folgende Nutzungsbedingungen: Dieser Artikel und alle verwendeten Materialien (Bilder, Quelltexte, etc.) unterliegen dem Copyright des Autors, hier Seku. Das kopieren dieses Artikels, Auszügen oder verwendeten Materialien und Einfügen auf anderen Seiten als dieser (seku.info) ist nur mit einer ausdrücklichen, schriftlichen Einverständniserklärung des Autors erlaubt. Weder Autor noch der Betreiber dieser Seite haften für eventuelle Schäden, die durch diesen Artikel oder herunterladbare Objekte ( > Downloads ) verursacht wurden. Die Richtigkeit dieses Textes ist nicht garantiert. EinleitungGuten Tag,In diesem Tutorial will ich euch erklären, wie man bei Windows Fenster erstellt. Leuten, die sich auf diesem Gebiet schon ein bisschen auskennen, sei gesagt, dass wir keine Dialog und auch keine MFC verwenden werden. Ich beginne am besten mit einer Einführung in die GUI (Grafische Benutzerobefläche) von Windows. Zunächst sollte man wissen, dass die komplette WindowsGUI auf Fenster aufgebaut ist. Alles sind Fenster, nicht nur die Fenster wie man sie als Benutzer kennt, sondern auch Knöpfe und Eingabefelder sind Fenster. Dann sollte man wissen, dass die WinApi auf Handles aufgebaut ist. Man erkennt sie am "H" als erstes Zeichen. Als Beispiel wären da HWND, als ein Handle auf ein Fenster, HICON, als Icon, HCURSOR, als Cursor, und viele mehr. Handles sind Variablen auf die Elemente. Nochmal zurück zu den Fenstern; Da Fenster untereinander und auch zu Windows und dem Benutzer kommunizieren müssen, gibt es Nachrichten. Jedes Fenster hat eine Nachrichtenfunktion, welche bei jeder Interaktivität aufgerufen wird. Das kann z.B. sein, dass der Benutzer einen Knopf drückt oder ein anderen Eintrag in einer Liste ausgewählt hat. Der Einfachheit halber werden Nachrichten von den Elementen (also Knöpfe, Checkboxen, etc.) nicht nur an ihre eigene Nachrichtenfunktion, sondern auch an die des zugehörigen Fensters geschickt. Die Nachrichtenfunktion nennt man auch Rückruffunktion Ich denke, jetzt wissen wir schon viel über die GUI von Windows und wir können nun ans Programmieren gehen . Davor aber noch eins. Ich empfehle euch wirklich das Beispiel anzusehen(!)
Die FensterklasseBevor wir ein Fenster erstellen können, müssen wir erstmal seine Fensterklasse bei Windows registrieren. In dieser Klasse stehen Angaben wie das Icon in der oberen linken Ecke, den verwendeten Cursor, die Hintergrundfarbe, usw. Die Struktur einer Fensterklasse heißt WNDCLASS. Wir werden aber die etwas andere Struktur WNDCLASSEX benutzen. Schauen wir uns mal ihre Definition an
Die Variable style beinhaltet diverse Klassenstyles, welche man wie Flags kombinieren kann. Wir werden hier CS_CLASSDC benutzen. Wer sich für dafür interessiert, kann mal ein Blick in die MSDN werfen. Was vielleicht auch nützlich sein könnte ist CS_NOCLOSE, bei welchem kein Schließsymbol oben rechts im Fenster ist. Für hIcon und hCursor gibt es zwei nützliche Funktionen, welche uns die Standardicons /-cursor liefern. Sie heißen LoadIcon() bzw. LoadCursor(). Bei Beiden ist der erste Parameter das Handle auf das Programm (HINSTANCE). Der Zweite ist der Name des gewünschten Icons / Cursors. Mit dem Makro MAKEINTRESOURCE() bekommen wir diesen. Für hbrBackground gibt es auch Standardpinsel. Die Funktion GetStockObject(int iObject); liefert uns diese. Hier sind einige Möglichkeiten für iObject. Am besten man testet alle mal .
Nun gut, jetzt haben wir die Fensterklasse ausgefüllt, aber Windows hat noch keinen blassen Schimmer davon. Wir müssen also die Fensterklasse noch registrieren. Dafür gibt es auch eine Funktion: BOOL RegisterClassEx(WNDCLASSEX* pWindowClass);. Was soll ich hierzu noch sagen .
Das Fenster erstellenJetzt können wir Fensterklasse ausfüllen und registrieren, aber irgendwas fehlt da noch.. hmm, was war das denn? ach ja.. Wir wissen jetzt immer noch nicht, wie man ein Fenster erstellt. Aber keine Angst, dafür gibt es eine Funktion
Kommen wir zu dwStyle. Die Flags, die hier eingegeben werden können, geben Aufschluss über die Möglichkeiten mit denen der Benutzer das Fenster verändern kann. Hier folgen die paar wichtigsten
So, jetzt haben wir ein Fenster erstellt. Damit unser Fenster die Nachrichten aus der Nachrichtenwarteschlange bekommt, müssen wir Windows ständig dazu aufrufen. Die Funktion dafür heißt
Diese Funktion wartet für jedes Fenster der Programminstanz, bis eine Nachricht eintrifft sie zu jenem. Das heißt, dass wir, egal wieviel Fenster, diese Funktion nur einmal einbauen müssen. Die erste Variable ist ein Pointer auf die Nachricht, die das Fenster erhalten soll. Der zweite Parameter ist für uns NULL. Er ist nicht das Handle auf das Fenster, für welches wir Nahrichten wollen! Die letzten beiden sind für uns auch egal und deshalb 0. Nachdem wir die Nachricht erhalten haben, müssen wir sie an das Fenster weiterleiten. Dafür brauchen wir zwei Funktionen: TranslateMessage(MSG* pMessage) und DispatchMessage(MSG* pMessage). Die Variable beider Funktionenen ist der Pointer auf die Nachricht von GetMessage(). Man sollte diese 3 Funktionen in einer Schleife laufen lassen, sodass die Fenster ständig ihre Nachrichten bekommen. Bekommt es diese nämlich nicht, wird es zwangsweise abstürzen, da es auch nicht die Befehle zum Beenden erhält .
Bevor wir zu der Rückruffunktion für die Nachrichten kommen, gibt es noch etwas zu GetMessage. Da diese Funktion wartet bis eine Nachricht eintrifft, ist sie für manche Projekte ungeeignet. Zum Beispiel bei einem Spiel kann es zu rucklern führen, wenn wir ständig warten müssen. Deshalb gibt es noch eine zweite Funktion, die dasselbe macht, mit der Ausnahme, dass sie nicht wartet, sondern guckt ob JETZT GERADE eine Nachricht da ist.
Der letzte Parameter (die anderen sind gleich), entscheidet, ob die Nachrichten nach dem Funktionsaufruf aus der Nachrichtenschleife gelöscht werden. Wir geben hier PM_REMOVE an. Die Struktur MSG Diese Nachrichtstruktur MSG will ich noch schnell erklären.
Die NachrichtenfunktionKommen wir nun zu lpfnWndProc aus der Fensterklasse. Das ist unsere Rückruffunktion. Die Struktur erwartet hier einen Funktionspointer auf folgende Funktion.
hWindow ist das Handle auf das Fenster, für das die Nachrichtenfunktion ist. uiMsg ist die Nachricht. WParam und LParam sind zwei Parameter der Nachricht. Bei WindowProc sollte man eine Nachricht immer an Windows weiterleiten, damit auch es davon erfährt. Das geht mit der Funktion DefWindowProc(). Die Parameter sind die selben wie bei WindowProc, nur dass wir sie aufrufen und wir sie nicht definieren müssen . So könnte also eine WindowProcFunktion aussehen
Kommen wir zum Parameter uiMsg. Das ist, wie bereits gesagt, die Nachricht. Es gibt sehr viele Nachrichten, eigentlich viel zu viele . Für den Anfang aber sollten diese reichen.
Wenn wir diese Funktion aufrufen, bekommt das Fenster die Nachricht WM_QUIT. Wir können in der Schleife immer abfragen, ob diese Nachricht ankommt und dann die Schleife abbrechen. Das Fenster wird automatisch beendet (natürlich kann man auch mit DestroyWindow(HWND); nachhelfen ). Sonst läuft die Schleife weiter und das Programm endet nie. Ich denke, das wird im Beispielprogramm gut erkennbar sein.
Ein zusammenfassendes BeispielprogrammeWas soll ich noch sagen? Es sollte eigentlich alles klar sein. Außer vielleicht, dass man WNDCLASSEX und die Nachricht MSG vor Beginn mit ZeroMemory leeren sollten, da sonst Fehler auftreten können. Aber guckt euch das Beispiel an
Hier könnten vielleicht noch die Funktionen UnregisterClass() und DestroyWindow() auffallen. Aber ich denke, die Parameter und die Funktion dahinter sollten klar sein. AusblickSo, jetzt haben wir ein Fenster. Aber irgendwie sieht es immernoch ein klein wenig leer aus. Das liegt daran, dass es leer ist (ja, wirklich!). Im nächsten Teil kommen wir dann zu den ersten Elementen. Um genauer zu sein kommen wir zu Statischen Objekten wie Bildern, Icons und Texte. Aber am Besten ihr lest es selber durch. cu Seku.
Alle Inhalte stehen, wenn nicht anders angegeben, unter dem Copyright von Seku. Für die Inhalte externer Seiten ist der jeweilige Betreiber verantwortlich. |
||||||||||||||||||||||