SetWindowLongPtr - ungültiger Index

SetWindowLongPtr - ungültiger Index

Beitragvon fliegermichl » 12. Okt 2018, 10:05 SetWindowLongPtr - ungültiger Index

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
fliegermichl
 
Beiträge: 213
Registriert: 9. Jun 2011, 08:42

Beitragvon mse » 12. Okt 2018, 13:03 Re: SetWindowLongPtr - ungültiger Index

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?
mse
 
Beiträge: 2012
Registriert: 16. Okt 2008, 09: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
Nach oben

Beitragvon fliegermichl » 13. Okt 2018, 08:55 Re: SetWindowLongPtr - ungültiger Index

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
fliegermichl
 
Beiträge: 213
Registriert: 9. Jun 2011, 08:42

Beitragvon mse » 13. Okt 2018, 09:28 Re: SetWindowLongPtr - ungültiger Index

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.
mse
 
Beiträge: 2012
Registriert: 16. Okt 2008, 09: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
Nach oben

Beitragvon theo » 13. Okt 2018, 10:09 Re: SetWindowLongPtr - ungültiger Index

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.
theo
 
Beiträge: 8064
Registriert: 11. Sep 2006, 18:01

Beitragvon mse » 13. Okt 2018, 10:20 Re: SetWindowLongPtr - ungültiger Index

Das ist dasselbe. rtl/win/wininc/defines.inc:
Code: Alles auswählen
 
     GWL_WNDPROC = -(4);
[...]
    GWLP_WNDPROC               = -4;
 
mse
 
Beiträge: 2012
Registriert: 16. Okt 2008, 09: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
Nach oben

Beitragvon theo » 13. Okt 2018, 10:24 Re: SetWindowLongPtr - ungültiger Index

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
theo
 
Beiträge: 8064
Registriert: 11. Sep 2006, 18:01

Beitragvon fliegermichl » 14. Okt 2018, 11:25 Re: SetWindowLongPtr - ungültiger Index

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?!?
fliegermichl
 
Beiträge: 213
Registriert: 9. Jun 2011, 08:42

Beitragvon mse » 14. Okt 2018, 11:35 Re: SetWindowLongPtr - ungültiger Index

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.
mse
 
Beiträge: 2012
Registriert: 16. Okt 2008, 09: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
Nach oben

Beitragvon fliegermichl » 14. Okt 2018, 12:42 Re: SetWindowLongPtr - ungültiger Index

Ja genau, was meinst du mit "funktioniert nicht" auch die gleiche Fehlermeldung mit dem ungueltigen Index oder wird die neue wndproc nicht aufgerufen?
fliegermichl
 
Beiträge: 213
Registriert: 9. Jun 2011, 08:42

Beitragvon mse » 14. Okt 2018, 15:41 Re: SetWindowLongPtr - ungültiger Index

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.
mse
 
Beiträge: 2012
Registriert: 16. Okt 2008, 09: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
Nach oben

Beitragvon fliegermichl » 15. Okt 2018, 04:37 Re: SetWindowLongPtr - ungültiger Index

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;
 
fliegermichl
 
Beiträge: 213
Registriert: 9. Jun 2011, 08:42

Beitragvon mse » 15. Okt 2018, 13:02 Re: SetWindowLongPtr - ungültiger Index

Bei mir funktioniert es jetzt auch, habe im Test die Parameter verwechselt.
mse
 
Beiträge: 2012
Registriert: 16. Okt 2008, 09: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
Nach oben

• Themenende •

Zurück zu Windows



Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 0 Gäste

cron
porpoises-institution
accuracy-worried