AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Einführung in die Grundlagen der Win32API Programmierung
Thema durchsuchen
Ansicht
Themen-Optionen

Einführung in die Grundlagen der Win32API Programmierung

Ein Thema von Luckie · begonnen am 7. Aug 2003 · letzter Beitrag vom 5. Nov 2015
Antwort Antwort
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#1

Einführung in die Grundlagen der Win32API Programmierung

  Alt 7. Aug 2003, 02:56
Bungeebug hatte mich gefragt, ob ich ihm mal eine persönliche Einführung in die Win32-API Programmierung unter Delphi per ICQ geben könnte. Da es auch andere interesssiert, wie es scheint, habe ich mich dazu entschlossen, mit der Genehmigung von Bungeebug, das ICQ-Log in leicht überarbeiteter Form hier zu veröffentlichen.

Es kann in dieser Form als eine erweiterete Einführung zu meinen nonVCL-Tutorials auf meiner Seite gesehen werden.

Zitat:
BungeeBug (11:28 PM) :
so dann gib mir mal saures ich brauch sowas wie nen 10 min schnell kurs ... ich hab so ungefair verstanden wie das ganze geht nur bin ich nich ganz durch gestiegen wie ich so ne Unit aufbaun muss

Luckie (11:29 PM) :
Als Grundgerüst könnte man das erste Tutorial nehmen ("Fenster").

Luckie (11:33 PM) :
Also Windows basiert auf Messages.

Luckie (11:33 PM) :
Windows kommuniziert über Messages mit den Programmen/Fenstern.

Luckie (11:34 PM) :
Beispiel:

Luckie (11:34 PM) :
Zwei Fenster. Fenster A überdeckt Fenster B.

Luckie (11:34 PM) :
Fenster A wird geschlossen oder verschoben und Fenster B wird sichtbar.

Luckie (11:35 PM) :
Jetzt muß der Bereich, der von B eingenommen wird neu gezeichnet werden.

Luckie (11:35 PM) :
Klar?

BungeeBug (11:35 PM) :
jup

BungeeBug (11:35 PM) :
klingt logisch

Luckie (11:35 PM) :
OK. Da Windows aber nicht weiß, was auf dem Fenster ist, kann es das nicht selber machen. Das weiß eben nur Fenster B.

BungeeBug (11:36 PM) :
also sendet win ne nachricht "mach neu" an Fenser B?!

Luckie (11:36 PM) :
Also schickt Windows an Fenster B eine Nachricht, die B sagt. "Sorg bitte dafür, dass der Bereich

deines Fensters wieder stimmt."

Luckie (11:37 PM) :
Die Nachricht heißt: WM_PAINT.

BungeeBug (11:37 PM) :
ok

Luckie (11:38 PM) :
Damit dieser Mechanismus funktioniert brauchen wir zwei Dinge: auf der einen Seite etwas wo Windows die Nachrichten plazieren kann und auf der anderen Seite etwas, das die Nachrichten abholt.

Luckie (11:38 PM) :
Auch klar?

BungeeBug (11:38 PM) :
sowas wie nen postkasten ?!

Luckie (11:38 PM) :
Jupp.

BungeeBug (11:39 PM) :
dann hab ichs verstanden

Luckie (11:39 PM) :
Der Postkasten heißt Messagequeue.

Luckie (11:39 PM) :
Un der Idiot der städig hinrennt und nachkuckt heißt Messageloop.

Luckie (11:40 PM) :
Die Messagequeue wird von Windows gestellt und die Messageloop vom Prozess des Fensters.

Luckie (11:40 PM) :
Die Messageloop ist eine Endlosschleife, die solange läuft bis eine bestimmte Nachricht kommt.

Luckie (11:41 PM) :
So bald in der Messagequeue ein WM_QUIT auftaucht, wird die Messageloop beendet und das Programm geschlossen.

Luckie (11:43 PM) :
So. Wie sieht die Umsetztung dieses Teils in Delphi aus?

Luckie (11:44 PM) :
Also die Messageloop befindet sich im Hauptprogramm, das ist die DPR-Datei.

Luckie (11:45 PM) :
while true do
begin
if not GetMessage(msg, 0, 0, 0) then
break;
TranslateMessage(msg);
DispatchMessage(msg);
end;

Luckie (11:46 PM) :
So das entscheidende ist GetMessage. Das PSDK sagt dazu als Rückgabewert:
If the function retrieves a message other than WM_QUIT, the return value is nonzero.
If the function retrieves the WM_QUIT message, the return value is zero.


Luckie (11:47 PM) :
Wenn also WM_QUIT kommt habe ich null als Rückgabewert und das break wird ausgelöst und damit die while-Schleife verlassen. Der Rest des Hauptprogramms wird abgearbeitet und wir landen beim end mit dem Punkt dahinter.

Luckie (11:48 PM) :
Fertig, ende, aus, tot.

Luckie (11:48 PM) :
So das war aber nur die erste Hälfte.

Luckie (11:49 PM) :
Es nützt ja alles nichts, wenn ich zwar die Nachrichten abhole habe nichts damit anfange.

Luckie (11:50 PM) :
In der while-Schleife fallen zwei Funktionen auf:
TranslateMessage(msg);
DispatchMessage(msg);

Luckie (11:50 PM) :
TranslateMessage ist erstmal unwichtig.

Luckie (11:51 PM) :
Eine Rolle spielt hier erstmal nur DispatchMessage.

Luckie (11:52 PM) :
DispatchMessage leitet die Nachrichten an eine Fensterprozedur weiter, die wir in unserem Programm deklarieren müssen.

Luckie (11:52 PM) :
Sie sieht im Grundgerüst so aus.

Luckie (11:53 PM) :
function WndProc(hWnd: HWND; uMsg: UINT; wParam: wParam; lParam: LParam):
lresult; stdcall;
begin
Result := 0;
case uMsg of
WM_CREATE:
begin
end
else
Result := DefWindowProc(hWnd, uMsg, wParam, lParam);
end;
end;

Luckie (11:53 PM) :
Im parameter uMsg steht die Nachricht drin, die wir abgefangen haben.

Luckie (11:54 PM) :
In hWnd das Fensterhandle an das die Nachricht gerichtet ist.

Luckie (11:54 PM) :
wParam und lParam sind weitere messagespezifische Parameter.

BungeeBug (11:55 PM) :
wo bekomme ich das Handle her?

Luckie (11:55 PM) :
Wird dir von Windows mitgeliefert.

BungeeBug (11:55 PM) :
also hab ich damit nix am Hut?

Luckie (11:55 PM) :
Nein.

BungeeBug (11:55 PM) :
ok

Luckie (11:56 PM) :
Richten wir nun unser Augenmerk auf den else Zweig der case-Konstruktion.

Luckie (11:56 PM) :
DefWindowproc.

Luckie (11:57 PM) :
Steht für Default Window Procedure.

Luckie (11:57 PM) :
Alle Nachrichten die mit case nicht abgearbeitet werden landen im else Zweig und werden an die

DefWindowProc weitergereicht.

BungeeBug (11:59 PM) :
wird dann immer der gleiche code ausgeführt oder hat windows da was parat?

Luckie (11:59 PM) :
Dazu komme ich jetzt.

BungeeBug (11:59 PM) :


Luckie (00:00 AM) :
Butons, Listboxen usw. sind auch nur Fenster mit einer eigenen WindowsProcedure.

Luckie (00:00 AM) :
Jetzt ist dir sicherlich aufgefallen, das man sich bei denen nicht um das Neuzeichnen kümmern muß.

BungeeBug (00:01 AM) :
also nur bei der Form?

Luckie (00:01 AM) :
Das liegt daran, weil das die Fensterprozedur von den Kontrols übernimmt.

BungeeBug (00:01 AM) :
ok

Luckie (00:01 AM) :
Zeichen ich jetzt in OnPaint auf das Form, um mal ein VCL Beispiel zu nehmen, existiert keine Fensterprozedur dafür.

Luckie (00:02 AM) :
Klar? Woher soll auch Windows wissen, was du auf deinem Fenster gemalt hast.

BungeeBug (00:02 AM) :
jo

Luckie (00:02 AM) :
Ergo mußt du das selber machen, in dem du WM_PAINT abfängst und dort entsprechend reagierst.

Luckie (00:03 AM) :
Das wären zwei drittel der Grundlagen.

Luckie (00:03 AM) :
Kucken wir uns noch mal den Rest an.

BungeeBug (00:03 AM) :
bis jetzt hab ichs verstanden

Luckie (00:03 AM) :
Guter Schüler.

BungeeBug (00:04 AM) :
ich geb mir mühe

Luckie (00:04 AM) :
Kuck die mal den Source zu dem Fensterdemo an.

BungeeBug (00:04 AM) :
hab ich

Luckie (00:04 AM) :
Hast du?

BungeeBug (00:04 AM) :
was genau?

Luckie (00:04 AM) :
Scroll ganz runter.

Luckie (00:05 AM) :
var
{Struktur der Fensterklasse}
wc: TWndClassEx = (
cbSize : SizeOf(TWndClassEx);
Style : CS_HREDRAW or CS_VREDRAW;
lpfnWndProc : @WndProc;
cbClsExtra : 0;
cbWndExtra : 0;
hbrBackground : COLOR_APPWORKSPACE;
lpszMenuName : nil;
lpszClassName : ClassName;
hIconSm : 0;
);
msg: TMsg;

begin
wc.hInstance := hInstance;
wc.hIcon := LoadIcon(hInstance, MAKEINTRESOURCE(100));
wc.hCursor := LoadCursor(0, IDC_ARROW);
{Fenster registrieren}
RegisterClassEx(wc);

BungeeBug (00:05 AM) :
hab ich

Luckie (00:05 AM) :
Dahin. das ist der einzigste bisher unklare Punkt.

Luckie (00:06 AM) :
So, was passiert da?

Luckie (00:06 AM) :
Bzw. warum machen wir das?

Luckie (00:06 AM) :
Windows unterhält für jedes Fenster eine Messagequeue.

Luckie (00:07 AM) :
Nur müssen wir Windows dazu veranlassen diese einzurichten und entsprechend Speicher für das Fenster bereitzustellen. Mal so vereinfacht gesagt.

Luckie (00:07 AM) :
Dies geschiet mit der Funktion RegisterClassEx.

Luckie (00:08 AM) :
Diese Funktion erwartet eine Zeiger auf eine Struktur vom Typ TWndClassEx.

Luckie (00:09 AM) :
Diese Struktur wird mit Werten vorbelegt, die unser Fenster charackterisieren.

Luckie (00:10 AM) :
Wie zum Beispiel, der Hintergrundfarbe, dem Icon, dem Cursor, dem Menü usw.

Luckie (00:10 AM) :
Und ganz wichtig. Über die Strukturvariable lpfnWndProc wird eine Verknüfung von DispatchMessage zu

unserer Fensterprozedur hergestell.

Luckie (00:12 AM) :
Ist dies geschehen, können wir unser Fenster mit CreateWindowEx erzeugen und anzeigen.

Luckie (00:13 AM) :
Alles klar?

BungeeBug (00:13 AM) :
muss ich die verbindung selbst herstellen oder passiert das von selbst?

Luckie (00:14 AM) :
Die stellst du selber her, in dem du bei lpfnWndProc deine Fensterprozedur angibst.

BungeeBug (00:14 AM) :
also das hier? lpfnWndProc : @WndProc;

Luckie (00:14 AM) :
Genau.

BungeeBug (00:14 AM) :
ok verstanden

Luckie (00:15 AM) :
Das war eigentlich schon alles.

Luckie (00:15 AM) :
Und das alles macht auch die VCL, nur dass sie es vor dir versteckt.

BungeeBug (00:15 AM) :
und jetzt kann ich nen leeres Forumlar erzeugen?

Luckie (00:15 AM) :
nonVCl Grundkenntinsse tragen also auch zum tieferen Verständnis von Windows bei, wie du siehst.

Luckie (00:16 AM) :
Genau. Nur das wir wohl besser von Fenster reden.

BungeeBug (00:16 AM) :
das meiste hab ich davon gewusst nur nich das es so funktioniert

Luckie (00:16 AM) :
Ok. Jetzt machen wir es mal, wie in der Schule. Ich stelle mal ein paar Fragen und du antwortest mir.



BungeeBug (00:17 AM) :
i try

Luckie (00:17 AM) :
Gut. Lange for-Schleife mit irgendwas drin.

Luckie (00:17 AM) :
Dauert 3 Minuten oder so.

Luckie (00:17 AM) :
Warum reagiert mein Fenster nicht mehr?

BungeeBug (00:18 AM) :
weil wärend der schleife keine nachrichten angenommen werden?

Luckie (00:19 AM) :
Genau. Dein Programm/Fenster hängt in der for-Schleife und kann demnach mit der Messageloop keine Nachrichten empfangen, an die Fensterprozedur weiterleiten und abarbeiten.

BungeeBug (00:20 AM) :


BungeeBug (00:20 AM) :
*freu*

Luckie (00:20 AM) :
Warum kommen WM_TIMER Nachrichten nicht immer pünktlich bzw. werden nicht immer im Intervall abgearbeitet?

BungeeBug (00:21 AM) :
ich denk mal aus dem gleichen Grund weil irgend ne Schleife mal länger braucht als der Intervall is und tada ne nette verzögerung

Luckie (00:21 AM) :
Also OnTimer wäre das in der VCL.

Luckie (00:21 AM) :
Nicht ganz.

BungeeBug (00:22 AM) :
dann beleher mich

Luckie (00:22 AM) :
Nehmen wir an es kommt ein WM_TIMER - WM_PAINT - WM_TIMER.

Luckie (00:22 AM) :
Intervall 1 Sekunde.

Luckie (00:22 AM) :
Jetzt braucht dein Programm aber 5 Sekunden um den Code in WM_PAINT auszuführen.

Luckie (00:23 AM) :
Und was ist? Käse war es mit dem Intervall von einer Sekunde.

BungeeBug (00:23 AM) :
das is das was ich meinte ...

Luckie (00:24 AM) :
OK. Ist jetzt extrem. Aber es zeigt, was ich meine. Zu dem haben WM_TIMER Messages eine sehr geringe Priorität bei Windows.

Luckie (00:24 AM) :
Nächste Frage.

Luckie (00:24 AM) :
Warum muß ich mich um das Neuzeichnen von Buttons nicht kümmern?

BungeeBug (00:26 AM) :
weil das das Fenster sprich lpfnWndProc : @WndProc; macht?!

Luckie (00:26 AM) :
Mit der Fensterprozedur hat es was zu tun.

BungeeBug (00:27 AM) :
ach ne das gibt nur an wie das Fenster aussieht nicht wo die buttons sind oder?

Luckie (00:27 AM) :
Das gibt nur an welche Fenster zu der Fensterklasse gehört, die du mit RegisterWindowsEx registriert

hast.

Luckie (00:27 AM) :
Du kuckst an der falschen Stelle.

Luckie (00:28 AM) :
Kuck dir mal die Fensterprozedur an.

Luckie (00:28 AM) :
case
...
else
???
end;

Luckie (00:29 AM) :
Der entscheidenede Code steht bei den ???

Luckie (00:30 AM) :
Noch 30 Sekunden.

BungeeBug (00:30 AM) :
hmm ... ich passe ... evl seh ich den wald gard nich

Luckie (00:31 AM) :
Jedes Fenster, auch Buttons, haben eine eigenständige Fensterprozedur.

Luckie (00:31 AM) :
Da Windows weiß, wie ein Button aussieht kann es den Button selber zeichnen.

Luckie (00:32 AM) :
Kuck dir noch mal an, was ich zu DefWindowProc geschrieben habe.

Luckie (00:32 AM) :
So Big Daddy will ins Internet.

Luckie (00:32 AM) :
Kann ich das Log veröffentlichen auf meiner HP und in der DP? Interessiert auch andere wie es scheint.

BungeeBug (00:33 AM) :
jojo
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Assarbad
(Gast)

n/a Beiträge
 
#2

Re: Einführung in die Grundlagen der Win32API Programmierung

  Alt 7. Aug 2003, 03:03
Kommt es ungelegen, wenn ich ein paar Fragen zu obigen Aussagen stelle? ...
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#3

Re: Einführung in die Grundlagen der Win32API Programmierung

  Alt 7. Aug 2003, 03:05
Nur zu verbessere / ergänze wo du kannst und willst.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Assarbad
(Gast)

n/a Beiträge
 
#4

Re: Einführung in die Grundlagen der Win32API Programmierung

  Alt 7. Aug 2003, 03:37
  • WndProc ist eine Callback-Funktion und wird von Windows und nicht vom Thread des Programms aufgerufen! Deshalb muß auch immer die Aufrufkonvention stimmen!
  • SendMessage, PostMessage, PostThreadmessage und Konsorten fehlen.
  • WM_PAINT und WM_ERASEBKGND gehören zusammen. Besonders wenn man selber Controls zeichnet
  • DefWindowProc() ruft die Standardfensterfunktion eines Fensters auf. Das ist dazu da, damit der Programmierer nicht jede einzelne von den dutzenden Fensternachrichten selbst bearbeiten muß. Es hat nicht primär was mit der Fensterfunktion der Controls zu tun!
  • RegisterClassEx registriert wirklich eine "Klasse". Auch wenn Windows intern nicht so OOP-orientiert ist, so kann man dies wirklich mal so betrachten. Eine Klasse besitzt hier ein paar Eigenschaften (siehe Record "wc") und eine "Hauptmethode", die Fensterfunktion. Mit CreateWindow/CreateWindowEx erzeugt man eine neue Instanz der Fensterklasse, eben das Fenster. Das ist wichtig, denn das impliziert auch, daß man mehrere Instanzen (Fenster) der gleichen Klasse (Fensterklasse) erzeugen kann. Hier kann man ruhig mal die Parallele zur OOP und damit auch der VCL ziehen.
  • TranslateMessage ist für Tastatureingabe relevant.
  • Es gab noch Kleinigkeiten, aber ich tippe das hier zum 2ten Male, weil meine Maus 5 Tasten hat und eine davon für den Browser "Zurück" bedeutet :-/ ... der Rest waren aber Bagatellen.

Alles in Allem sehr verständlich rübergebracht! Lob an Luckie

BTW: Eins stimmt nicht, das mit den 2/3 der Grundlagen ... es sind maximal 2/3 der Grundlagen von "wie erstelle ich ein Fenster" ... aber nicht von nonVCL an sich
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#5

Re: Einführung in die Grundlagen der Win32API Programmierung

  Alt 7. Aug 2003, 03:48
Zitat:
  • Es gab noch Kleinigkeiten, aber ich tippe das hier zum 2ten Male, weil meine Maus 5 Tasten hat und eine davon für den Browser "Zurück" bedeutet :-/ ... der Rest waren aber Bagatellen.
Sind anscheinend genau vier Tasten zu viel für unseren Assarbad. Der Hörr scheint etwas überfordert.
Zitat:
Alles in Allem sehr verständlich rübergebracht! Lob an Luckie
Danke.
Zitat:
BTW: Eins stimmt nicht, das mit den 2/3 der Grundlagen ... es sind maximal 2/3 der Grundlagen von "wie erstelle ich ein Fenster" ... aber nicht von nonVCL an sich
Das bezog sich auf die Tatsache, wie weit wir in der heutigen Schulstunde sind.

Hier noch mal das ganze auf meiner HP: http://www.luckie-online.de/artikel/...n32api01.shtml
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
DualCoreCpu
(Gast)

n/a Beiträge
 
#6

AW: Einführung in die Grundlagen der Win32API Programmierung

  Alt 5. Nov 2015, 14:10
Hallo Luckie,

leider funktioniert der Link nicht mehr. Ich finde auf der angezeigten Seite zwar eine Liste mit Delphi Software, HelpDesk, Components, Tutorials, ... aber ich kann nichts runter laden. Ich möchte das Windows-API Grundlagentutorial noch mal runter laden.

Gibt es das noch?

Wenn ja, wo?
  Mit Zitat antworten Zitat
Benutzerbild von Captnemo
Captnemo

Registriert seit: 27. Jan 2003
Ort: Bodenwerder
1.126 Beiträge
 
Delphi XE4 Architect
 
#7

AW: Einführung in die Grundlagen der Win32API Programmierung

  Alt 5. Nov 2015, 14:14
Probiers mal hier

Die alte Domain steht ja zum Verkauf. Was du da siehst ist nicht von Luckie.
Dieter
9 von 10 Stimmen in meinem Kopf sagen ich bin nicht verrückt. Die 10. summt dazu die Melodie von Supermario Bros.
MfG Captnemo

Geändert von Captnemo ( 5. Nov 2015 um 18:18 Uhr)
  Mit Zitat antworten Zitat
DualCoreCpu
(Gast)

n/a Beiträge
 
#8

AW: Einführung in die Grundlagen der Win32API Programmierung

  Alt 5. Nov 2015, 16:35
Danke! Das ist der richtige Link!
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:08 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz