Home » Tutorials » Systemnahe Programmierung » nonVCL

nonVCL

Grundlagen

Um das Fensterprinzip zu verstehen, muss man die TForms erstmal hinter sich lassen. Fenster unter Windows haben dem System den Namen gegeben. Jedes Fenster hat diverse Eigenschaften, die es beschreiben. Windows kennt hierbei zwei grundlegende Varianten. Basisstruktur und erweiterte Struktur.
Betrachten wir die Basisstruktur.

tagWNDCLASSA = packed record
  style: UINT;
  lpfnWndProc: TFNWndProc;
  cbClsExtra: Integer;
  cbWndExtra: Integer;
  hInstance: HINST;
  hIcon: HICON;
  hCursor: HCURSOR;
  hbrBackground: HBRUSH;
  lpszMenuName: PAnsiChar;
  lpszClassName: PAnsiChar;
end;

Der Einfachheit halber hier nur die Ansi-Version. Auf NT-Plattformen finden sich entsprechende Unicode-(Wide-)Pendants. Die Struktur ist ausdeklariert als TWndClass.
Die erweiterte Struktur („…Ex“), in der WINDOWS.PAS als TWndClassEx deklariert, sieht man hier.

tagWNDCLASSEXA = packed record
  cbSize: UINT;
  style: UINT;
  lpfnWndProc: TFNWndProc;
  cbClsExtra: Integer;
  cbWndExtra: Integer;
  hInstance: HINST;
  hIcon: HICON;
  hCursor: HCURSOR;
  hbrBackground: HBRUSH;
  lpszMenuName: PAnsiChar;
  lpszClassName: PAnsiChar;
  hIconSm: HICON;
end;

Wie man sehen kann, unterscheiden sich beide Varianten nur dadurch, dass in der erweiterten Version die Größe der Struktur angegeben werden muss und ein kleines ICON angegeben werden kann.
Beide Strukturen beschreiben eine Fensterklasse (und zwar nicht Klasse im OOP-Sinn) 😉
Um die Klasse benutzen zu können, muss sie mindestens einen Namen [„lpszClassName“] die Instanz des aufrufenden Moduls [üblicherweise „hInstance“ unter Delphi] und in der erweiterten Version die Größe der Struktur erhalten.

procedure initacomctl;
var
  wc: TWndClassEx;
begin
  wc.style := CS_HREDRAW OR CS_VREDRAW OR CS_GLOBALCLASS;
  wc.cbSize := sizeof(TWNDCLASSEX);
  wc.lpfnWndProc := @HyperlinkWndProc;
  wc.cbClsExtra := 0;
  wc.cbWndExtra := 0;
  wc.hInstance := hInstance;
  wc.hbrBackground := COLOR_WINDOW;
  wc.lpszMenuName := NIL;
  wc.lpszClassName := AHyperlink;
  wc.hIcon := 0;
  wc.hIconSm := 0;
  wc.hCursor := 0;
  RegisterClassEx(wc);
end; {HLinkTest Beispiel}

Der abschließende Aufruf von RegisterClassEx() [bzw. RegisterClass()] registriert die Fensterklasse für die Programminstanz und ermöglicht den Aufruf von CreateWindowEx() [bzw. CreateWindow()].
Obige Prozedur ist die Initialisierungsroutine zu einem Demonstrationsprogramm meiner Wenigkeit. Ziel wird es sein zu zeigen, wie man

  1. Dialog-Vorlagen benutzt.
  2. eigene Fensterklassen per Dialog-Vorlage einbindet.
  3. eigene Fensterklassen baut.