SetWindowLongPtr - ungültiger Index

Antworten
Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 686
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Winux (L 2.0.11 FPC 3.2)
CPU-Target: 32/64Bit
Wohnort: Echzell

SetWindowLongPtr - ungültiger Index

Beitrag von fliegermichl »

Hallo zusammen,

in einem meiner Programme möchte ich mittels

Code: Alles auswählen

 
   PrevWndProc:=windows.WNDPROC(SetWindowLongPtr(Handle,GWL_WNDPROC,PtrUInt(@WndCallback)));
 


eine neue WndProc für mein Formular installieren um darin auf spezielle Messages reagieren zu können. Wenn ich mein Programm mit 32Bit kompiliere klappt das auch einwandfrei. Kompiliere ich es aber mit 64Bit, bekomme ich mit SysErrorMessage(GetLastError) den Fehler "ungültiger Index".

Hat jemand eine Idee was ich da tun kann?

Vielen Dank und schöne Grüße
Michael

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: SetWindowLongPtr - ungültiger Index

Beitrag von mse »

Gibt es in Lazarus keine "Systemevent" Property die vor der internen Verarbeitung aufgerufen wird?
Für mich sieht der Aufruf von windows.WNDPROC() mit dem SetWindowlongPtr() Resultat seltsam aus, habe mich aber nicht näher damit befasst.
Edit:
Aha, windows.WNDPROC() ist eine Typenkonvertierung.
Edit2:
Bei mir funktioniert SetWindowlongPtr() mit GWLP_WNDPROC auf Windows 7 weder in 32 noch 64 bit. Eine neue Sicherheitsmassnahme vielleicht?

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 686
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Winux (L 2.0.11 FPC 3.2)
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: SetWindowLongPtr - ungültiger Index

Beitrag von fliegermichl »

Hmm,

eigentlich will ich nur folgendes erreichen.
Ich habe mit RegisterHotKey einen globalen HotKey registriert auf den ich egal wo meine Anwendung grad ist reagieren will.
In Delphi gab es einen Event Application.OnMessage den es in Lazarus aber nicht gibt.

Ich hab hier Windows 10 64 Bit.

Edit: Meine Vorgehensweise mit SetWindowLongPtr hab ich dem Lazarus Wiki entnommen. Siehe http://wiki.lazarus.freepascal.org/Win32/64_Interface#Processing_non-user_messages_in_your_window

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: SetWindowLongPtr - ungültiger Index

Beitrag von mse »

fliegermichl hat geschrieben:Ich hab hier Windows 10 64 Bit.

Dann funktioniert bei dir ein 32 Bit Kompilat? Wie gesagt, bei mir funktioniert das mit Windows 7 auch in 32 Bit nicht.
MSEgui bietet die Möglichkeit Anwendungsweit auf Shortcuts zu reagieren, es gibt auch tform.onsysevent, welches sich in die System event queue einhängt. Das kann Lazarus sicher alles auch, man muss nur etwas suchen.

Benutzeravatar
theo
Beiträge: 8507
Registriert: Mo 11. Sep 2006, 19:01

Re: SetWindowLongPtr - ungültiger Index

Beitrag von theo »

Bin grade nicht auf Win, aber probiere mal
GWLP_WNDPROC
statt
GWL_WNDPROC

mse hat das zwar implizit angedeutet, aber vielleicht ist der Unterschied nicht aufgefallen.

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: SetWindowLongPtr - ungültiger Index

Beitrag von mse »

Das ist dasselbe. rtl/win/wininc/defines.inc:

Code: Alles auswählen

 
     GWL_WNDPROC = -(4);
[...]
    GWLP_WNDPROC               = -4;
 

Benutzeravatar
theo
Beiträge: 8507
Registriert: Mo 11. Sep 2006, 19:01

Re: SetWindowLongPtr - ungültiger Index

Beitrag von theo »

Ja, habe ich nicht kontrolliert.
Bin nur deshalb darauf gekommen, weil Embarcadero das herausstellt:
Richtig:
SetWindowLongPtr(hWnd, GWLP_WNDPROC, LONG_PTR(@MyWindowProc));
Falsch:
SetWindowLong(hWnd, GWL_WNDPROC, Longint(@MyWindowProc));


http://docwiki.embarcadero.com/RADStudi ... it-Windows

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 686
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Winux (L 2.0.11 FPC 3.2)
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: SetWindowLongPtr - ungültiger Index

Beitrag von fliegermichl »

Ja bei 32 Bit Windows 10 funktioniert es.

Ich hab es jetzt grad nochmal mit einer VMWare Workstation auch mit Windows 7 probiert. Gleiches Ergebnis 64 Bit invalid Index, 32 Bit geht?!?

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: SetWindowLongPtr - ungültiger Index

Beitrag von mse »

fliegermichl hat geschrieben:Ja bei 32 Bit Windows 10 funktioniert es.

Und als 32 Bit Kompilat unter 64 Bit Windows? Das ist was bei mir ebenfalls nicht funktioniert.

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 686
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Winux (L 2.0.11 FPC 3.2)
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: SetWindowLongPtr - ungültiger Index

Beitrag von fliegermichl »

Ja genau, was meinst du mit "funktioniert nicht" auch die gleiche Fehlermeldung mit dem ungueltigen Index oder wird die neue wndproc nicht aufgerufen?

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: SetWindowLongPtr - ungültiger Index

Beitrag von mse »

Auf 64 Bit Windows 7 sowohl als 32 als auch als 64 Bit Kompilat:
getwindowlongptr(<winid>,GWLP_WNDPROC) bringt einen Wert <> 0. Wenn ich diesen Wert mit setwindowlongptr() zurückschreibe, erhalte ich den Rückgabewert 0, getlasterror() liefert ERROR_INVALID_INDEX. Die <winid> wurde im gleichen thread angelegt.

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 686
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Winux (L 2.0.11 FPC 3.2)
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: SetWindowLongPtr - ungültiger Index

Beitrag von fliegermichl »

Aehm ja,

ich wollte eben mal ein Minimalbeispiel machen, damit wir hier nicht Äpfel mit Birnen vergleichen.
Da ist mir folgendes aufgefallen.
1. hatte ich die Unit jwawinuser in der uses Liste. Diese definiert SetWindowLongPtr ebenfalls.
2. hatte ich den Aufruf innerhalb der Methode Loaded des Formulars. Das war zu früh, dann kam die Fehlermeldung "Das Fenster hat keine Bildlaufleisten" ?!?

Jetzt habe ich es im EventHandler OnShow untergebracht und da funktioniert es in beiden Fällen.

Code: Alles auswählen

 
var
  PrevWndProc: WNDPROC = nil;
  PrevWndProcPtr : PtrInt absolute PrevWndProc; // Nur für Fehlermeldung
 
function WndCallback(Ahwnd: HWND; uMsg: UINT; wParam: WParam; lParam: LParam):LRESULT; stdcall;
begin
  result:=CallWindowProc(PrevWndProc,Ahwnd, uMsg, WParam, LParam);
end;
 
{ TForm1 }
 
procedure TForm1.FormShow(Sender: TObject);
var errno : integer;
begin
 SetLastError(0); // Das steht bei MSDN zu SetWindowLongPtr
 PrevWndProc:=windows.WNDPROC(SetWindowLongPtr(Handle,GWLP_WNDPROC,PtrInt(@WndCallback)));
 errno := GetLastError();
 if errno <> 0 then
   MessageDlg(Format('Kann die WndProc nicht setzen. (%d) Fehler: %s', [PrevWndProcPtr, SysErrorMessage(errno)]), mtWarning, [mbOk], 0)
 else
   MessageDlg('wndproc erfolgreich gesetzt', mtInformation, [mbOk], 0);
end;
 

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: SetWindowLongPtr - ungültiger Index

Beitrag von mse »

Bei mir funktioniert es jetzt auch, habe im Test die Parameter verwechselt.

Antworten