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/)
-   -   GetWindowLong versus GetWindowLongPtr (https://www.delphipraxis.net/168077-getwindowlong-versus-getwindowlongptr.html)

Delphi-Laie 3. Mai 2012 21:49

GetWindowLong versus GetWindowLongPtr
 
Hallo Delphifreunde!

In der MSDN-Beschreibung zur Funktion "GetWindowLong" findet sich folgender bemerkenswerter Satz: "To write code that is compatible with both 32-bit and 64-bit versions of Windows, use GetWindowLongPtr." In der parallelen Beschreibung der Funktion "GetWindowLongPtr" findet sich neben erstgenanntem Satz zusätzlich noch: "When compiling for 32-bit Windows, GetWindowLongPtr is defined as a call to the GetWindowLong function."

Das ist insofern erst einmal irreführend, weil suggeriert wird, daß man die GetWindowLongPtr-Funktion mit nur einem universellen Quelltext für beide Plattformen benutzen kann, doch unter Win32 gibt es sie nicht. Man muß mithin mit Compilerschaltern arbeiten. Doch nun stellt sich (mir) die Frage, ob das überhaupt nötig ist. Mit anderen Worten: Was macht GetWindowLongPtr unter 64 Bit der dort auch verfügbaren GetWindowLong-Funktion überlegen?

Ich benutzte, ohne dieses Detail zu kennen, GetWindowLong nämlich auch schon unter 64 Bit und konnte keinerlei Funktionseinbußen gegenüber 32 Bit erkennen.

jaenicke 3. Mai 2012 22:01

AW: GetWindowLong versus GetWindowLongPtr
 
Zitat:

Zitat von Delphi-Laie (Beitrag 1164778)
Das ist insofern erst einmal irreführend, weil suggeriert wird, daß man die GetWindowLongPtr-Funktion mit nur einem universellen Quelltext für beide Plattformen benutzen kann, doch unter Win32 gibt es sie nicht. Man muß mithin mit Compilerschaltern arbeiten.

GetWindowLongPtr ist in Delphi (zumindest ab XE) bereits so deklariert, dass es für Win32 genauso benutzbar ist wie für Win64. ;-)

// EDIT:
Ach ja, der Satz in der MSDN Bibliothek bezog sich logischerweise auf die Headerdateien, die im SDK zur Einbindung der Funktionen zur Verfügung stehen. Und dort ist es ebenso definiert (in der winuser.h).

Delphi-Laie 3. Mai 2012 22:07

AW: GetWindowLong versus GetWindowLongPtr
 
Zitat:

Zitat von jaenicke (Beitrag 1164780)
GetWindowLongPtr ist in Delphi (zumindest ab XE) bereits so deklariert, dass es für Win32 genauso benutzbar ist wie für Win64. ;-)

Danke!

Das ist dann aber geschummelt / gemogelt: GetWindowLongPtr gibt es erst ab 64 Bit, und wenn man GetWindowLongPtr in XE einsetzt (das ja noch keine 64 Bit beherrscht), dann wird in Wirklichkeit, also intern GetWindowLong verwendet. Steht sozusagen etwas anderes drauf, als verpackt ist.

Ob das in XE 2 und Lazarus auch so ist, weiß ich nicht, zur Not könnte man das ja über externe DLL-Routineaufrufe deklarieren. Nur, welchen Vorteil es bringt oder ob es gar nötig ist (vermutlich eher nicht), das geht aus der MS-Beschreibung leider nicht hervor.

Ergänzung: GetWindowLongPtr kennt Lazarus auch in 32 Bit. Ich werde einfach GetWindowLongPtr für die Lazarus- und XE2-Quelltexte benutzen, um 32- und 64-Bit-Compilate zu erzeugen. Sollen sich doch Lazarus und XE 2 darum kümmern, daß das richtige verwendet wird...

Ergänzung 2: Komfortabel wäre es, wenn es auch umgekehrt funktionieren würde, d.h., wenn man GetWindowLong schreibt und auch das geprüft würde, so daß intern auf GetWindowLongPtr bei der Erzeugung von 64-Bit-Compilaten verwendet würde.

jaenicke 3. Mai 2012 22:15

AW: GetWindowLong versus GetWindowLongPtr
 
Zitat:

Zitat von Delphi-Laie (Beitrag 1164781)
Ergänzung: GetWindowLongPtr kennt Lazarus auch in 32 Bit. Ich werde einfach GetWindowLongPtr für die Lazarus- und XE2-Quelltexte benutzen, um 32- und 64-Bit-Compilate zu erzeugen. Sollen sich doch Lazarus und XE 2 darum kümmern, daß das richtige verwendet wird...

Wenn die Headerdateien des SDK in Delphi und Lazarus umgesetzt werden, muss das ja auch so sein um kompatibel zu sein. In den Headerdateien für C++ hat MS das erledigt und wer die für andere Sprachen umsetzt, muss das eben nachbauen. Das ist also genau so gedacht. ;-)

Zitat:

Zitat von Delphi-Laie (Beitrag 1164781)
Das ist dann aber geschummelt / gemogelt: GetWindowLongPtr gibt es erst ab 64 Bit, und wenn man GetWindowLongPtr in XE einsetzt (das ja noch keine 64 Bit beherrscht), dann wird in Wirklichkeit, also intern GetWindowLong verwendet. Steht sozusagen etwas anderes drauf, als verpackt ist.

Dann schauen wir doch mal wie in Delphi GetWindowLong aussieht. ;-)
Delphi-Quellcode:
function GetWindowLong(hWnd: HWND; nIndex: Integer): NativeInt;
begin
  Result := GetWindowLongPtr(hWnd, nIndex);
end;

Delphi-Laie 3. Mai 2012 22:19

AW: GetWindowLong versus GetWindowLongPtr
 
Zitat:

Zitat von jaenicke (Beitrag 1164782)
Dann schauen wir doch mal wie in Delphi GetWindowLong aussieht. ;-)
Delphi-Quellcode:
function GetWindowLong(hWnd: HWND; nIndex: Integer): NativeInt;
begin
  Result := GetWindowLongPtr(hWnd, nIndex);
end;

Nun, dann ist das für mich unerklärliche Zauberei, wie das auf Win32 laufen soll, denn GetWindowLongPtr soll es erst ab 64 Bit geben, in meinem Windows 2000 gibt es das in der user32.dll laut Dependency Walker jedenfalls nicht. Und XE erzeugt doch nur 32-Bit-Compilate, die ja auch auf Windows 2000 laufen müss(t)en.

jaenicke 3. Mai 2012 22:22

AW: GetWindowLong versus GetWindowLongPtr
 
GetWindowLongPtr wird entsprechend der Headerdateien aus dem SDK und der Doku wiederum auf GetWindowLong gemappt. Wenn du aber direkt GetWindowLong aufrufst, landest du erst über GetWindowLongPtr bei der echten API-Funktion GetWindowLong.

Daher macht es eben Sinn GetWindowLongPtr zu verwenden, weil das der direkteste Weg ist und auch überall funktioniert. ;-)

Delphi-Laie 3. Mai 2012 22:33

AW: GetWindowLong versus GetWindowLongPtr
 
Danke!

Zitat:

Zitat von jaenicke (Beitrag 1164784)
GetWindowLongPtr wird entsprechend der Headerdateien aus dem SDK und der Doku wiederum auf GetWindowLong gemappt. Wenn du aber direkt GetWindowLong aufrufst, landest du erst über GetWindowLongPtr bei der echten API-Funktion GetWindowLong.

Hat man eine Chance, das zu verstehen? ;-) Ergänzung: Nach Himis Quelltext unten ist es mir jetzt klar, was damit gemeint ist.

Zitat:

Zitat von jaenicke (Beitrag 1164784)
Daher macht es eben Sinn GetWindowLongPtr zu verwenden, weil das der direkteste Weg ist und auch überall funktioniert. ;-)

Das versthe ich. Es bleibt also dabei: Universeller Quelltext für 32 und 64 Bit kommt ohne Compilerschalter aus und GetWindowLongPtr ist die Funktion der Wahl. Korrekt?

himitsu 3. Mai 2012 22:34

AW: GetWindowLong versus GetWindowLongPtr
 
Für irgendwas müssen die Quellcodes ja gut sein.
Delphi-Quellcode:
function GetWindowLong(hWnd: HWND; nIndex: Integer): NativeInt;
begin
  Result := GetWindowLongPtr(hWnd, nIndex);
end;
function GetWindowLongA(hWnd: HWND; nIndex: Integer): NativeInt;
begin
  Result := GetWindowLongPtr(hWnd, nIndex);
end;
function GetWindowLongW(hWnd: HWND; nIndex: Integer): NativeInt;
begin
  Result := GetWindowLongPtr(hWnd, nIndex);
end;

{$IFDEF WIN64}
function GetWindowLongPtr; external user32 name 'GetWindowLongPtrW';
function GetWindowLongPtrA; external user32 name 'GetWindowLongPtrA';
function GetWindowLongPtrW; external user32 name 'GetWindowLongPtrW';
...
{$ELSE}
function GetWindowLongPtr; external user32 name 'GetWindowLongW';
function GetWindowLongPtrA; external user32 name 'GetWindowLongA';
function GetWindowLongPtrW; external user32 name 'GetWindowLongW';
...
{$ENDIF}
Aber wer erkennt den Fehler?

Delphi-Laie 3. Mai 2012 22:47

AW: GetWindowLong versus GetWindowLongPtr
 
Müßte es nicht so:

Delphi-Quellcode:
function GetWindowLong(hWnd: HWND; nIndex: Integer): NativeInt;
begin
  Result := GetWindowLongPtr(hWnd, nIndex);
end;
function GetWindowLongA(hWnd: HWND; nIndex: Integer): NativeInt;
begin
  Result := GetWindowLongPtrA(hWnd, nIndex);
end;
function GetWindowLongW(hWnd: HWND; nIndex: Integer): NativeInt;
begin
  Result := GetWindowLongPtrW(hWnd, nIndex);
end;

{$IFDEF WIN64}
function GetWindowLongPtr; external user32 name 'GetWindowLongPtrW';
function GetWindowLongPtrA; external user32 name 'GetWindowLongPtrA';
function GetWindowLongPtrW; external user32 name 'GetWindowLongPtrW';
...
{$ELSE}
function GetWindowLongPtr; external user32 name 'GetWindowLongW';
function GetWindowLongPtrA; external user32 name 'GetWindowLongA';
function GetWindowLongPtrW; external user32 name 'GetWindowLongW';
...
{$ENDIF}
lauten?


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