![]() |
WM_WINDOWPOSCHANGING abfangen
Hi, der Titel sagt eigentlich schon alles. Wie kann ich WM_WINDOWPOSCHANGING des aktuellen Fensters abfangen?
Vielen Dank schonma :) |
Re: WM_WINDOWPOSCHANGING abfangen
in dem du einen messagehandler dafür schreibst
Delphi-Quellcode:
private
procedure FWindowPosChanging(var AMsg: TMessage); message WM_WINDOWPOSCHANGING; [...] procedure TForm1.FWindowPosChanging(var AMsg: TMessage); begin //Hier dein Source der was machen soll wenn die Message einfliegt end; |
Re: WM_WINDOWPOSCHANGING abfangen
Hmh das habe ich schon rausbekommen, aber mein Problem ist, dass ich WM_WINDOWPOSCHANGING von ALLEN Fenstern abfangen will, nicht nur die von meinem Programm.
|
Re: WM_WINDOWPOSCHANGING abfangen
dann musst du dir einen messagehook schreiben
|
Re: WM_WINDOWPOSCHANGING abfangen
brauch ich dafür ne extra dll? Haste vielleicht einen Link mit einer Anleitung dazu?
Is nämlich mein erstes mal :mrgreen: |
Re: WM_WINDOWPOSCHANGING abfangen
such mal im msdn nach SetWindowsHookEx (bzw. in der Delphihilfe)
![]() Um eine DLL kommst du da wohl nicht herum (steht aber noch genaueres im msdn). |
Re: WM_WINDOWPOSCHANGING abfangen
Ich verstehe das ganze leider nicht so recht... Auch Assabads Hook Tutorial bringt mich nicht recht weiter. Gibt es denn nicht irgendwo eine Anleitung wie man Messages abfängt und verändert etc.?
|
Re: WM_WINDOWPOSCHANGING abfangen
Ungefähr so:
Delphi-Quellcode:
[Nachtrag]
var
HookHandle: Cardinal; function GetMsgProc(code: integer; wParam: WPARAM; lParam: LPARAM): LResult; stdcall; begin if code = HC_ACTION then with Windows.PMsg(lParam)^ do if message = WM_WINDOWPOSCHANGING then begin end; Result := CallNextHookEx(HookHandle, Code, wParam, lParam); end; ... begin HookHandle := SetWindowsHookEx(WH_GETMESSAGE, GetmsgProc, hInstance, 0); end; DLL kannst du dir sparen wenn's nur um dieselbe Anwendung geht. [Noch'n Nachtrag] Mit der Funktion
Delphi-Quellcode:
aus der Unit Controls kriegst du dann zu dem Fensterhandle das Control/die Form (falls vorhanden).
function FindControl(Handle: HWnd): TWinControl;
|
Re: WM_WINDOWPOSCHANGING abfangen
Ne es geht ja NICHT um die gleiche Anwendung :) Ich will auch die Messages anderer Fenster abfangen ;)
|
Re: WM_WINDOWPOSCHANGING abfangen
Dann musst du den Code in eine DLL packen.
Alternativ zu WH_GETMESSAGE kannst du dir auch mal den Hook WH_CBT ansehen, da gibt's dann vielleicht nicht so viel Message-Traffic. DLL erstellen geht eigentlich ganz einfach - mach einfach ein neues Projekt mit dem "DLL-Experten". Den Code trägst du dann komplett direkt in die Projektdatei ein, ähnlich wie bei einer Konsolenanwendung. |
Re: WM_WINDOWPOSCHANGING abfangen
öhhm welchen Code?
|
Re: WM_WINDOWPOSCHANGING abfangen
Den, welchen Volker geposted hat ;)
|
Re: WM_WINDOWPOSCHANGING abfangen
Gute Idee :wall: :mrgreen:
|
Re: WM_WINDOWPOSCHANGING abfangen
Oh Gott ich bekomme es nicht hin!!! Fehlt da noch irgendwas wenn ich die Function samt Variable einfach in das Unitfenster der dll kopiere? Ich bekomm auf jedefall ne Fehlermeldung... :(
|
Re: WM_WINDOWPOSCHANGING abfangen
Etwa so sollte es aussehen (alles ungetestet).
Delphi-Quellcode:
... und dann in deinem Hauptprogramm:
library SuperMsgHook;
uses Windows, Messages, SysUtils, Classes; type TMessageHookCallback = procedure(const Msg: Windows.TMsg) of object; var HookHandle: Cardinal; CallbackProc: TMessageHookCallback; function GetMsgProc(code: integer; wParam: WPARAM; lParam: LPARAM): LResult; stdcall; begin if (code = HC_ACTION) and Assigned(CallbackProc) then if Windows.PMsg(lParam)^.message = WM_WINDOWPOSCHANGING then CallbackProc(Windows.PMsg(lParam)^); Result := CallNextHookEx(HookHandle, Code, wParam, lParam); end; procedure DisableMessageHook; stdcall; begin CallbackProc := nil; if HookHandle <> 0 then begin UnhookWindowsHookEx(HookHandle); HookHandle := 0; end; end; procedure EnableMessageHook(ACallbackProc: TMessageHookCallback); stdcall; begin DisableMessageHook; CallbackProc := ACallbackProc; HookHandle := SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, hInstance, 0); if HookHandle = 0 then RaiseLastOsError; end; exports GetMsgProc, EnableMessageHook, DisableMessageHook; end.
Delphi-Quellcode:
Du brauchst dann eine selbstgeschriebene Methode, die die Informationen entgegennimmt. Die übergibst du an "EnableMessageHook".
type
TMessageHookCallback = procedure(const Msg: Windows.TMsg) of object; procedure DisableMessageHook; stdcall; external 'SuperMsgHook.dll'; procedure EnableMessageHook(ACallbackProc: TMessageHookCallback); stdcall; external 'SuperMsgHook.dll'; |
Re: WM_WINDOWPOSCHANGING abfangen
Vielen Dank für die Hilfe, ich hatte keine Uses drin... :wall:
Wie erstelle ich daraus nun eine Dll? Sie wird nicht automatisch generiert... Edit: Ahh habs schon hinbekommen ;) Edit2: Waaa aber jetzt kann ich mit Zitat:
|
Re: WM_WINDOWPOSCHANGING abfangen
Als ob ich's gewusst hätte :twisted:
Die DLL compiliert aber richtig, oder? Dann weiter so in deinem Hauptprogramm:
Delphi-Quellcode:
In OnMessageHook kannst du jetzt die Nachrichten verarbeiten. Du solltest allerdings nicht zu viel machen, da es sonst auf die Performance geht.
// das hatten wir schon
type TMessageHookCallback = procedure(const Msg: Windows.TMsg) of object; procedure DisableMessageHook; stdcall; external 'SuperMsgHook.dll'; procedure EnableMessageHook(ACallbackProc: TMessageHookCallback); stdcall; external 'SuperMsgHook.dll'; // Ab jetzt neu, Methode von Form1, also von deinem Hauptformular. // Kann aber auch eine Methode einer beliebigen Klasse sein procedure Form1.OnMessageHook(const Msg: Windows.TMsg); begin // Hier stehen jetzt in Msg alle Parameter der Meldung // Msg.hwnd: HWND; das Fensterhandle // Msg.message: UINT; WM_WINDOWPOSCHANGING // Msg.wParam: WPARAM; wParam zu der Meldung // Msg.lParam: LPARAM; lParam zu der Meldung // Msg.time: DWORD; Zeitpunkt der Nachricht // Msg.pt: TPoint; Mauszeigerstelle zum ang. Zeitpunkt end; procedure Form1.FormShow(Sender: TObject); begin // Hier wird der Hook eingeschaltet EnableMessageHook(OnMessageHook); end; procedure Form1.FormHide(Sender: TObject); begin // ... und hier wieder ausgeschaltet DisableMessageHook; end; |
Re: WM_WINDOWPOSCHANGING abfangen
... wobei mir heute beim Aufwachen eingefallen ist, dass es so ggf. nicht funktioniert.
Die Hook-DLL wird ja per Injection in jeden Prozess eingeschleust, in einem anderen Prozess funktioniert aber der Methoden-Zeiger nicht :gruebel: Oder wird nur ein Stub in den fremden Prozess geschrieben, der dann den Hook in meinem Prozesskontext aufruft :gruebel: Ich habe heute leider keine Zeit mehr mich weiter damit zu befassen, poste mal ob's funktioniert - insbesondere ob's lokal (nur dein Prozess) oder global funktioniert. |
Re: WM_WINDOWPOSCHANGING abfangen
Hi es funktioniert leider NICHT :( Weder lokal noch global, die Procedure onMessageHook wird garnicht aufgerufen...
|
Re: WM_WINDOWPOSCHANGING abfangen
Ich hab's hier jetzt mal getestet - der Hook wird zwar aufgerufen, aber es kommt *NIE* WM_WINDOWPOSCHANGING an. Erschwerend kommt hinzu, dass nur die Meldungen der eigenen Anwendung abgefangen werden und nicht die systemweiten (die Ursache dafür wird wohl die sein, die ich beim letzten Mal beschrieben habe: unterschiedliche Prozesse, unterschiedliche Adressräume).
Ich habe gerade mal in ![]() [Nachtrag] ... und natürlich erst mal den Hook finden, mit dem du WM_WINDOWPOSCHANGING abfangen kannst. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:47 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz