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.

Win32 Programmierung mit FPC - Teil 8 - by Delax

TextOut() haben wir im letzten Teil kennen gelernt. Im Grunde war es eine einfache Vorgehensweise zum ausgeben von Text. In Windows gibt es meißtens zwei Methoden zu jedem Thema: eine einfache und eine, die alles erschlägt. Das gute ist aber, das auch die umfangreichen Funktionen sich im Grunde sehr ähnlich sind.

DrawText() baut nun wieder auf der WM_PAINT Nachricht auf. Nochmal zur Wiederholung: wenn ein Fenster (oder auch nur ein Ausschnitt davon) neu gezeichnet werden muß, sendet Windows die WM_PAINT Nachricht an unser Fenster. Außer dieser Tatsache hat uns das letzte Mal nicht viel mehr interessiert. Nun aber müssen wir etwas ins Detail gehen.

Ein Fenster wird neu gezeichnet, wenn es verdeckt, minimiert, verschoben, die Größe verändert wird und so weiter. Anstatt nun mit GetDC einen Device Context zu definieren können wir innerhalb von WM_PAINT ein Device Context mit BeginPaint definieren. Dazu müssen wir einerseits wieder das Window Handle des Fensters angeben in das wir zeichnen wollen und zweitens eine Paintstructure.

Erstens: wo ist der Unterschied zwischen GetDC und BeginPaint? Nun, GetDC liefert einen Device Context für das ganze Fenster, BeginPaint nur für den Bereich, der neu gezeichnet werden muß. Wenn also ein fremdes Fenster eine kleine Ecke von unserem Fenster verdeckt wird bei GetDC der komplette Fensterinhalt neu gezeichnet. Bei BeginPaint jedoch immer nur, was wieder sichtbar wird.

Keine Sorge, wir müssen nicht überlegen was wie an welcher Stelle des Fensters sichtbar ist, das macht Windows automatisch. Wir müssen einfach nur bestimmen wie Windows das machen soll. Und genau das wird mit Hilfe einer Paintstruct erledigt. Sie enthält Informationen, ob z.B. der Hintergrund ebenfalls neu gezeichnet werden soll oder ähnliches. Außerdem bekommt eine Paintstruct übergeben, welcher Bereich genau neu gezeichnet werden soll.

Viel wichtiger als die Möglichkeit nur Teile des Fensters neu zu zeichnen ist, das BeginPaint alle Bereiche des Fensters nach dem zeichnen wieder für gültig erklärt. Somit werden nicht andauernd WM_PAINT Nachrichten verschickt, sondern wirklich nur, wenn das Fenster neu gezeichnet werden muß.

Also sieht die WM_PAINT nun wiefolgt aus.

 WM_PAINT : begin
   dcWindow := BeginPaint(hWindow, @ps);
    ...
   EndPaint(window_hwnd, ps);
 end;

Jetzt können wir etwas in dieses Fenster zeichnen. In unserem Falle wollen wir einen Text ausgeben. Wie bereits angedeutet funktioniert DrawText so, das man einen Bereich definiert, in den der Text gezeichnet werden soll und alles andere erledigt Windows selbst bzw. so, wie wir es ihm auftragen.

Dieser Bereich in den wir den Text ausgeben wollen wird durch ein Rechteck definiert. Windows stellt dafür die Struktur "rect" zur Verfügung. Im Prinzip enthält sie nur vier Angaben: rect.left, rect.top, rect.right und rect.bottom. Damit kann man nun ein Rechteck innerhalb des Fensters definieren, in das wir den Text ausgeben wollen.

Entweder man gibt die Werte direkt ein, oder man nutzt z.B. eine Funktion, die uns das ganze Fenster zur Verfügung stellt. Denkt man an Editoren, so ist das eher der normale Vorgang. Den ganzen Fensterinhalt erhalten wir mit GetClientRect(hWindow,@r); "r" ist in diesem Fall unsere rect-Struktur, in der die Größe gespeichert wird.

Nun können wir in diesen Bereich Text ausgeben. Mit DrawText wird nicht einfach nur der Text übergeben, sondern auch einige Parameter. Eben jene Parameter machen DrawText erst interessant. So kann man zum Beispiel definieren das der auszugebende Text innerhalb des Bereiches zentriert wird, umgebrochen und vieles andere.

  GetClientRect(hWindow,@r);
  DrawText(dcWindow,'DrawText Ausgabe',-1,@r,
   DT_SINGLELINE or DT_CENTER or DT_VCENTER);

Alles in allem sieht unsere WM_PAINT nun so aus:

    WM_PAINT:
      begin
	  dcWindow := BeginPaint(hWindow,@ps);
	  GetClientRect(hWindow,@r);
	  DrawText(dcWindow,'DrawText Ausgabe',-1,@r,
	  DT_SINGLELINE or DT_CENTER or DT_VCENTER);
	  EndPaint(hWindow,ps);
      end;

Als komplettes Programm hier zum download

Hier haben wir also 2 verschiedene Herangehensweisen an ein Problem. Das gute ist: Windows unterstützt sowohl einen schnellen Weg, als auch einen umfangreichen. Als Faustregel könnt ihr euch merken, das der umfangreiche der bessere ist. Im Grunde ist es nicht viel mehr Arbeit und er entspricht mehr dem "Windows way of programming". Wenn ihr aber nur kurz etwas ausgeben wollt straft euch allerdings keiner für TextOut.

Wie ihr merkt spielt sich alles in einer Windows Applikation in der WinProc ab. Dies ist in der Tat die korrekte Art in Windows zu programmieren. Eure Applikation selbst ist nur passiv und reagiert auf Windows. Es gibt eine Alternative, aber die ist bestenfalls etwas für Programme, denen es egal sein kann, das die alle Resourcen aufbrauchen und andere Programme trocken legen. Ein Beispiel wären Bildschirmschoner oder Spiele. Aber selbst hier ist es oft besser gemäß den Windows Richtlinien zu programmieren. Wer sich für "unverschämte" Windowsprogrammierung interessiert möge einen Blick in das OpenGL/ FPC Tutorial werfen.

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

Back to previous page

Useful Links









Link to us