Welcome to the new Friends-of-FPC!

Here you can find all kinds of information about the FreePascal Compiler. We have many tutorials and howtos as well as a selection of tools to help you with your programming. We also have some example codes for you. And if you want to contribute some information/ sources/ tools yourself you can do so.
Also we have finally relaunched the FoFPC forum. It's your chance for some Q&A about everything FreePascal.

Friends-of-FPC

Tutorials: Learn how to code with FreePascal.

Source Codes: A collection of examples, miscellaneous source codes and open source stuff.

Tools and Help Files: Intro- duction of some tools that might help you with FPC.

Community

Forum: Ask or answer questions about the FreePascal Compiler, programming or just babble about coding.

Contribute! Contribute your own Tutorial, Source Codes or Tools and send them to us!

Website

About: Information about Friends-of-FPC.org.

Grundlagen der Grafikprogrammierung - Teil 5 - by Delax

Dies wird der letzte Teil mit reinem Win API Zeugs sein. Wir werden einen Blick auf den Event Handler (oder WinProc) werfen. Ein Thema welches schon so manchen harten Programmierer in den Abgrund getrieben hat. Gute Aussichten, oder?

Fangen wir gleich richtig an. Ich sagte in einem früheren Teil das Windows "event driven" ist. Intern werde Nachrichten an Programme verschickt, mit denen das Programm über das System informiert wird: "Wurde eine Taste gedrückt", "Geht gerade der Bildschirmschoner los?", und so weiter. Ich sagte auch jedes Programm brauche so eine Art Schnittstelle zum System, welche diese Nachrichten verwaltet. Und eben dies macht der Event Hanlder unseres Programmes.

Der Event Handler eures Programmes wird von euch geschrieben, aber keine Sorge: ihr müsst euch nicht um alle Nachrichten kümmern, die da ankommen. Was kümmert es eure Demo, wenn eine Mail kommt? Ihr könnt also nur bestimmte Nachrichten aussondern, diese bearbeiten und den Rest Windows überlassen.

Noch mal eine Rückblende. Als ihr euer Fenster registriert habt, kam die Zeile WindowClass.lpfnWndProc := WndProc(@WindowProc); vor. Damit habt ihr eure WinProc angegeben. Die WinProc ist euer Event Handler und euer Fenster nutzt von nun an die angegebene WinProc zum verabreiten von Windows Nachrichten.

In Wirklichkeit kommen diese Nachrichten nicht wild auf euer Programm zu. Es hätte dann auch gar keine Zeit mehr sich um seine eigenen Aufgaben zu kümmern. Windows legt die Nachrichten vielmehr in einer Art Zwischenspeicher ab. Dort bleiben sie dann bis sie verarbeitet werden.

Um es wirklich glasklar zu machen ein Beispiel: Windows hat eine Nachricht, die Nachricht wird auf den Stapel gelegt. Ihr schaut nach was auf dem Stapel liegt. Wenn es euch interessiert, holt es ab und bearbeitet es. Wenn nicht, dann lasst Windows sich darum kümmern.

Schauen wir uns mal eine solche WinProc an.

function WindowProc(
            HWND hwnd,
            UINT msg,
            WPARAM wparam,
            LPARAM lparam)

Ein Blick auf die Parameter:

hwnd: Das ist unser Window Handle. Ist eigentlich nur wichtig, wenn wir mehrere Fenster der gleichen Klasse geöffnet haben. hwnd überprüft in dem Fall welche Nachrichten von welchem Fenster verursacht wurden.

msg: Das ist die eigentliche Nachricht, die WinProc verarbeitet. naja - in Wirklichkeit ist es nur eine ID Nummer, kommt aber nahe dran.

Wparam/ Lparam: Für weitergehende Bearbeitung der Nachrichten.

Wichtig ist LResult Callback. Nicht vergessen. So. Nun läuft die ganze Sache folgendermaßen ab: Wir holen die Nachricht ab. Schauen nach ob die Nachricht ID in msg für uns interessant ist und wenn ja, kommt ein Stück code wie wir weiter damit verfahren wollen. In msg stehen reine IDs, hier mal eine Auswahl:

WM_ACTIVATE - Ein Fenster wird aktiviert.
WM_CLOSE - Ein Fenster wird geschlossen.
WM_CREATE - Ein Fenster wird neu erzeugt.
WM_DESTROY - Ein Fenster wird zerstört.
WM_MOUSEMOVE - Die Maus wird bewegt

Das sind natürlich nur ein paar. Wie immer gilt: schnappt euch ein Windows Buch oder die Win API Hilfe Files von Microsoft um einen kompletten Überblick zu bekommen.

Um es wirklich supereinfach zu machen interessiert uns erst mal nur eine Nachricht: WM_DESTROY. Die brauchen wir um festzustellen ob der User unser Fenster geschlossen hat, damit wir unser Programm daraufhin beenden. Merke: nur weil der User das Fenster zumacht wird unser Programm von Windows nicht automatisch beendet! Das ist unsr Job! Hier also unsere WinProc:

function WindowProc(Window: HWnd; AMessage, WParam,
                     LParam: Longint): Longint; stdcall; export;

begin
   WindowProc := 0;

   case AMessage of
     wm_Destroy:
       begin
          PostQuitMessage(0);
          Exit;
       end;
   end;

   WindowProc := DefWindowProc(Window, AMessage, WParam, LParam);
 end;

In dem "Hello World" Programm sieht die WinProc jedoch ein bischen anders aus - dort malen wir gleich noch Kram ins Fenster. Uns soll das erst einmal nicht interessieren.

Wars das? Naja...ja und nein - die einfache WinProc Routine ist fertig, ja. Aber ist euch aufgefallen das wir nirgendwo die Nachrichten abholen und an die WinProc weiterleiten? Das müssen wir in der WinMain, also unserer Hauptschleife erledigen. Ihr erinnert euch vom allerersten Beispiel? Die WinMain ist die Hauptprozedur unseres Programmes. Da fängts an.

Also los gehts:

  while GetMessage(@AMessage, 0, 0, 0) do begin
     TranslateMessage(AMessage);
     DispatchMessage(AMessage);
   end;

Was tun wir da? GetMessage holt sich die aktuelle Nachricht und speichert sie in AMessage. Dann wird sie übersetzt und wenn wir schließlich verschickt. Einfach, oder?

Und das ist wirklich alles. Hmm...ich sehe schon wie ihr mit Fragezeichen im Gesicht vor eurem Monitor sitzt, aber es ist wirklich einfacher als man denkt - Übung macht hier den Meister. Im nächsten Beispiel fangen wir aber endlich richtig an ;)

Cheers,

Delax/ Sundancer Inc.
[delax@sundancerinc.de]

Back to previous page

Useful Links









Link to us