|

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
|