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 3 - by Delax

Jetzt steigen wir tiefer in die Windows-Programmierung ein und schauen uns die Fensterklassen (Window Classes)an.

Jedes Fenster egal ob Dialog Box, Message Box oder Vollbild benötigt eine Fensterklasse. 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) Standardklassen, aber im wirklichen Leben werdet ihr wohl für jede Applikation eine eigene Klasse definieren.

Ich will jetzt nicht lang und breit über Fensterklassen und deren Möglichkeiten reden. Zum ersten ist das Thema sehr umfangreich und zum zweiten braucht ihr nicht wirklich alles über sie zu wissen. Im Grunde werden wir nur kurz darauf eingehen, damit ihr einen Überblick bekommt. Alles andere könnt ihr in der Windows SDK Help nachschlagen.

Wir hatten das letzte Mal ein kurzes und kleines "Hello World" Programm - bei FPC liegt ein etwas umfangreicheres "Hello World" bei und das schauen wir uns jetzt einmal genauer an:

{
  $Id: winhello.pp,v 1.1 1998/12/20 22:23:54 peter Exp $
  Copyright (c) 1996 by Charlie Calvert
  Modifications by Florian Klaempfl

  Standard Windows API application written in Object Pascal.
  No VCL code included. This is all done on the Windows API
  level.
}

{$APPTYPE GUI}
{$MODE DELPHI}
program WinHello;

uses
  Strings, Windows;

const
  AppName = 'WinHello';

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

  var
     dc : hdc;
     ps : paintstruct;
     r : rect;

begin
  WindowProc := 0;

  case AMessage of
    wm_paint:
      begin
         dc:=BeginPaint(Window,@ps);
         GetClientRect(Window,@r);
         DrawText(dc,'Hello world by Free Pascal',-1,@r,
           DT_SINGLELINE or DT_CENTER or DT_VCENTER);
         EndPaint(Window,ps);
         Exit;
      end;
    wm_Destroy:
      begin
         PostQuitMessage(0);
         Exit;
      end;
  end;

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

 { Register the Window Class }
function WinRegister: Boolean;
var
  WindowClass: WndClass;
begin
  WindowClass.Style := cs_hRedraw or cs_vRedraw;
  WindowClass.lpfnWndProc := WndProc(@WindowProc);
  WindowClass.cbClsExtra := 0;
  WindowClass.cbWndExtra := 0;
  WindowClass.hInstance := system.MainInstance;
  WindowClass.hIcon := LoadIcon(0, idi_Application);
  WindowClass.hCursor := LoadCursor(0, idc_Arrow);
  WindowClass.hbrBackground := GetStockObject(WHITE_BRUSH);
  WindowClass.lpszMenuName := nil;
  WindowClass.lpszClassName := AppName;

  Result := RegisterClass(WindowClass) <> 0;
end;

 { Create the Window Class }
function WinCreate: HWnd;
var
  hWindow: HWnd;
begin
  hWindow := CreateWindow(AppName, 'Hello world program',
              ws_OverlappedWindow, cw_UseDefault, cw_UseDefault,
              cw_UseDefault, cw_UseDefault, 0, 0, system.MainInstance, nil);

  if hWindow <> 0 then begin
    ShowWindow(hWindow, CmdShow);
    UpdateWindow(hWindow);
  end;

  Result := hWindow;
end;


var
  AMessage: Msg;
  hWindow: HWnd;

begin
  if not WinRegister then begin
    MessageBox(0, 'Register failed', nil, mb_Ok);
    Exit;
  end;
  hWindow := WinCreate;
  if longint(hWindow) = 0 then begin
    MessageBox(0, 'WinCreate failed', nil, mb_Ok);
    Exit;
  end;

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

{
  $Log: winhello.pp,v $
  Revision 1.1  1998/12/20 22:23:54  peter
    * new name

}

Hier als Datei zum download

So. Keine Panik, schaut euch erst einmal nur den Part mit der Überschrift "Register the Windows Class" an. Dort seht ihr wie die Struktur "WindowClass" mit Werten versorgt wird. Gehen wir die einzelnen Punkte einmal durch:

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 (bindet einen eigenen Device Context an unser Fenster); 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.

lpfnWndProc: Das ist ein Pointer zu der "WndProc" Funktion. Erinnert ihr euch noch? Im zweiten Teil sagte ich Windows hätte Schnittstellen für Nachrichten. Nun, diese Schnittstelle ist die "WndProc". Dort werdet ihr auf alle Nachrichten Events reagieren, doch dazu später mehr. Im Moment genügt es zu wissen, daß man hier folgendes einträgt: WindowClass.lpfnWndProc := WndProc(@WindowProc);

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

hInstance: Hier tragen wir das Windows Handle (hwnd) ein. Das ist das Handle unseres Fensters. Wann immer wir mit unserem Fenster arbeiten ist dies die anzugebende Adresse. WindowClass.hInstance := system.MainInstance;

hIcon: Juchu, unser Icon ;) Wir nehmen erst mal das 0815 Icon: WindowClass.hIcon := LoadIcon(0, idi_Application);

hCursor: Unser Cursor. Auch hier Standart WindowClass.hCursor := LoadCursor(0, idc_Arrow);

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

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

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

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

  WindowClass.Style := cs_hRedraw or cs_vRedraw;
  WindowClass.lpfnWndProc := WndProc(@WindowProc);
  WindowClass.cbClsExtra := 0;
  WindowClass.cbWndExtra := 0;
  WindowClass.hInstance := system.MainInstance;
  WindowClass.hIcon := LoadIcon(0, idi_Application);
  WindowClass.hCursor := LoadCursor(0, idc_Arrow);
  WindowClass.hbrBackground := GetStockObject(WHITE_BRUSH);
  WindowClass.lpszMenuName := nil;
  WindowClass.lpszClassName := AppName;

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 erfahrt ihr, was ihr mit der eben definierten Struktur anfangen könnt.

Bis done!

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

Back to previous page

Useful Links









Link to us