Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Win32 API Verständnisfrage (https://www.delphipraxis.net/168366-win32-api-verstaendnisfrage.html)

Nintendo 17. Mai 2012 14:44

Win32 API Verständnisfrage
 
Hallo,

momentan beschäftige ich mich grad mit dem Windows API. Ich habe Luckies Tutorials hierzu.

So muss ich also zunächst eine Datenstruktur wndClass oder wndClassEx mit Daten füllen:

Dann schreibt man eine WindowProzedur, in der verschiedene Messages verarbeitet werden, zum Beispiel WM_PAINT


Aber was bedeuten nun die verschiedenen Handles:

wndClass.hInstance -> Handle auf mit Programm - Modul verbundenem Fenster. Für Delphi also unser Hauptfenster

Aber CreateWIndow(ex) gibt HWnd zurück, der auch ein Handle auf das neue Fenster zurück. Auch auf ebendieses Hauptfenster? So zu sagen geleiche Adresse im Speicher???

Oder ist das Kontextabhängig? So zu sagen beim Zeichnen des gesamten Fensters der gesamte Bereich, später der Clientbereich?
Oder leitet BeginPaint generell das Zeichnen des gesamten Feensters ein? Dann wäre HDC der Handle auf den Clientbereich?

Irgendwann will ich das Fenster zeichnen und rufe zuerst die Funktion

BeginPaint( hwnd, lpPaintStruct) auf, die einen HDC zurück gibt, einen Device Kontext.

Wohin zeigt dieser? Auf den Clientbereich des Fensters, wo später Anwenderausgaben landen?

Hinzu kommen dann noch hIcon, hCursor, hMenu. Aber die letzteren, wenn definiert gehören doch zum Fenster. Warum dann aber ein Handle? Was zeigt dieser hier an. Ich muss doch mit LoadIcon() oder LoadCursor() oder LoadMenu die Menüs laden. Sind die Handles dann Zeiger auf die zugehörigen Datenbereiche (Anfangsadresse)?


.

Zacherl 17. Mai 2012 15:30

AW: Win32 API Verständnisfrage
 
hInstance ist in den meisten Fällen ein Handle des eigenen Modules. Wenn du dich innerhalb deiner .EXE befindest, dann enthält der Wert meistens 0x00400000, was der Standard Imagebase entspricht. Schaust du dir den Wert innerhalb einer .DLL an, ändert er sich entsprechend der aktuellen Modul ImageBase.

Generell gesehen sind Handles keine Zeiger, sondern eher sowas wie "pseudo eindeutige" IDs. hInstance wäre zwar hier sowas in der Art wie ein Zeiger auf die ImageBase, bei hModule ist dies auch der Fall, aber das kann man generell so nicht sagen.

Wenn du beispielsweise den hDC bekommst, dann ist das einfach eine Nummer. Intern merkt sich die Windows API aber mit welchem Zeichenkontext diese Nummer verknüpft ist (und bei manchen Handles auch noch erweiterte Informationen, wie z.b. Zugriffsberechtigungen, etc). Willst du dann beispielsweise ein Rechteck zeichnen, rufst du die entsprechende API auf, übergibst das Handle und Windows führt dann die Nummer wieder auf den eigentlichen Zeichenkontext zurück.

Siehe auch:
http://de.wikipedia.org/wiki/Handle

NickelM 23. Mai 2012 10:36

AW: Win32 API Verständnisfrage
 
Um deine Frage dezüglich der BeginPaint-Prozedur zubeantworten:

Die BeginPaint kann nur bei der Message WM_PAINT ausgeführt werden.
BeginPaint leitet das Zeichnen des Fenster "inneren" ein, d.h. der Bereich, der in den Rändern liegt, also die Fläche, wo du bei der VCL immer die Komponenten reinsetzt. Nach BeginPaint kannst du alle deine Zeichnungs-Befehle ausführen. Wenn du alles hast rufst du EndPaint auf. Wenn du vorhast ein Fenster selber "zuzeichnen", solltest du keine Ränder haben. Der Nachteil ist, du musst diese Windows-Fenster-Bar selber zeichnen und die Buttons sowie die Befehle selber einbinden, z.b. das Minimieren, Schliessen und Maximieren. Die WM_PAINT Message sollte man nur abfangen und selber behandeln, wenn man sein Fenster oder Controls selber gestallten will.

Nintendo 26. Mai 2012 21:36

AW: Win32 API Verständnisfrage
 
Zitat:

Zitat von NickelM (Beitrag 1167693)
Um deine Frage dezüglich der BeginPaint-Prozedur zubeantworten:

Die BeginPaint kann nur bei der Message WM_PAINT ausgeführt werden.
BeginPaint leitet das Zeichnen des Fenster "inneren" ein, d.h. der Bereich, der in den Rändern liegt, also die Fläche, wo du bei der VCL immer die Komponenten reinsetzt. Nach BeginPaint kannst du alle deine Zeichnungs-Befehle ausführen. Wenn du alles hast rufst du EndPaint auf. Wenn du vorhast ein Fenster selber "zuzeichnen", solltest du keine Ränder haben. Der Nachteil ist, du musst diese Windows-Fenster-Bar selber zeichnen und die Buttons sowie die Befehle selber einbinden, z.b. das Minimieren, Schliessen und Maximieren. Die WM_PAINT Message sollte man nur abfangen und selber behandeln, wenn man sein Fenster oder Controls selber gestallten will.

Sorry, das ich erst heute wieder auftauche. Aber ich hatte Arbeit. Danke aber erst mal für Eure Antworten.

Ok, da sind mit Ausnahme von hModule und Hinstance die Handles also interne Nummern, die wahrscheinlich dann intern als Indizes auf die Zeichenfunktionen fungieren. Wie bei einem Array, das dann die richtigen API Funktionen enthält. Der Handle wäre also dann ein Index inb das Array.

Ich nehme an, hInstance zeigt in meinem Hauptprogramm auf die Steartadresse meines Hauptprogrammes und be .dll-s auf die die Ladeadresse derselben. Oder kommt bei .dll-s hModule für die gleiche Aufgabe, Startadresse zu speichern, infrage?

Das mit BeginPaint()/EndPaint() habe ich soweit verstanden. Allerdings, wo wird dann der Fensterrand und der Titelbar eigentlich gezeichnet?

.

Luckie 26. Mai 2012 22:02

AW: Win32 API Verständnisfrage
 
Den Rahmen und dein Fenstertitel zeichnet Windows. Deswegen wird das auch immer noch gezeichnet während der Inhalt des Fensters weiß bleibt, wenn es sich nicht zeichnen kann, weil es gerade was anderes macht.

Zacherl 27. Mai 2012 15:00

AW: Win32 API Verständnisfrage
 
Zitat:

Zitat von Nintendo (Beitrag 1168254)
Ich nehme an, hInstance zeigt in meinem Hauptprogramm auf die Steartadresse meines Hauptprogrammes und be .dll-s auf die die Ladeadresse derselben. Oder kommt bei .dll-s hModule für die gleiche Aufgabe, Startadresse zu speichern, infrage?

Nein, mit dem Prozedureinsprungspunkt (EP) deiner Binaries hat das Wert von hInstance nichts zu tun. Der Wert wird innerhalb der System.pas automatisch von Delphi initialisiert und zeigt auf die ImageBase, also Ladeadresse des aktuellen Moduls. Hierbei kann dein Modul sowohl deine EXE sein (normalerweise ImageBase 0x00400000) oder gegebenenfalls deine DLL (normalerweise zufällige ImageBase).

himitsu 27. Mai 2012 16:00

AW: Win32 API Verständnisfrage
 
Zitat:

Zitat von Zacherl (Beitrag 1168303)
(normalerweise zufällige ImageBase).

Weil normalerweise alle vergessen die ImageBase zu setzen.

Zacherl 27. Mai 2012 17:02

AW: Win32 API Verständnisfrage
 
Zitat:

Zitat von himitsu (Beitrag 1168306)
Zitat:

Zitat von Zacherl (Beitrag 1168303)
(normalerweise zufällige ImageBase).

Weil normalerweise alle vergessen die ImageBase zu setzen.

Macht ja eigentlich auch durchaus Sinn. Sichergehen, dass die eigene DLL an die gesetzte ImageBase geladen wird, kann man eh nie zu 100% sein. Aber dafür gibts ja auch Relocations :)


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:04 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