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/)
-   -   Delphi WM_WINDOWPOSCHANGING abfangen (https://www.delphipraxis.net/52603-wm_windowposchanging-abfangen.html)

MisterNiceGuy 31. Aug 2005 11:38


WM_WINDOWPOSCHANGING abfangen
 
Hi, der Titel sagt eigentlich schon alles. Wie kann ich WM_WINDOWPOSCHANGING des aktuellen Fensters abfangen?

Vielen Dank schonma :)

SirThornberry 31. Aug 2005 11:42

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;

MisterNiceGuy 31. Aug 2005 11:44

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.

SirThornberry 31. Aug 2005 11:45

Re: WM_WINDOWPOSCHANGING abfangen
 
dann musst du dir einen messagehook schreiben

MisterNiceGuy 31. Aug 2005 11:46

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:

SirThornberry 31. Aug 2005 11:56

Re: WM_WINDOWPOSCHANGING abfangen
 
such mal im msdn nach SetWindowsHookEx (bzw. in der Delphihilfe)
MSDN-Library durchsuchenSetWindowsHookEx

Um eine DLL kommst du da wohl nicht herum (steht aber noch genaueres im msdn).

MisterNiceGuy 31. Aug 2005 13:17

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.?

Flocke 31. Aug 2005 13:28

Re: WM_WINDOWPOSCHANGING abfangen
 
Ungefähr so:
Delphi-Quellcode:
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;
[Nachtrag]

DLL kannst du dir sparen wenn's nur um dieselbe Anwendung geht.

[Noch'n Nachtrag]

Mit der Funktion
Delphi-Quellcode:
function FindControl(Handle: HWnd): TWinControl;
aus der Unit Controls kriegst du dann zu dem Fensterhandle das Control/die Form (falls vorhanden).

MisterNiceGuy 31. Aug 2005 13:47

Re: WM_WINDOWPOSCHANGING abfangen
 
Ne es geht ja NICHT um die gleiche Anwendung :) Ich will auch die Messages anderer Fenster abfangen ;)

Flocke 31. Aug 2005 13:53

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.

MisterNiceGuy 31. Aug 2005 14:02

Re: WM_WINDOWPOSCHANGING abfangen
 
öhhm welchen Code?

Die Muhkuh 31. Aug 2005 14:03

Re: WM_WINDOWPOSCHANGING abfangen
 
Den, welchen Volker geposted hat ;)

MisterNiceGuy 31. Aug 2005 14:32

Re: WM_WINDOWPOSCHANGING abfangen
 
Gute Idee :wall: :mrgreen:

MisterNiceGuy 31. Aug 2005 16:49

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... :(

Flocke 31. Aug 2005 17:03

Re: WM_WINDOWPOSCHANGING abfangen
 
Etwa so sollte es aussehen (alles ungetestet).

Delphi-Quellcode:
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.
... und dann in deinem Hauptprogramm:

Delphi-Quellcode:
type
  TMessageHookCallback = procedure(const Msg: Windows.TMsg) of object;

procedure DisableMessageHook; stdcall; external 'SuperMsgHook.dll';
procedure EnableMessageHook(ACallbackProc: TMessageHookCallback); stdcall; external 'SuperMsgHook.dll';
Du brauchst dann eine selbstgeschriebene Methode, die die Informationen entgegennimmt. Die übergibst du an "EnableMessageHook".

MisterNiceGuy 31. Aug 2005 17:26

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:

Du brauchst dann eine selbstgeschriebene Methode, die die Informationen entgegennimmt. Die übergibst du an "EnableMessageHook".
nichts anfangen...

Flocke 31. Aug 2005 21:27

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:
// 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;
In OnMessageHook kannst du jetzt die Nachrichten verarbeiten. Du solltest allerdings nicht zu viel machen, da es sonst auf die Performance geht.

Flocke 1. Sep 2005 07:37

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.

MisterNiceGuy 1. Sep 2005 12:20

Re: WM_WINDOWPOSCHANGING abfangen
 
Hi es funktioniert leider NICHT :( Weder lokal noch global, die Procedure onMessageHook wird garnicht aufgerufen...

Flocke 1. Sep 2005 22:00

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 Ollis Hook-Tutorial geschaut, von dem er schon ein paar Mal geschrieben hat. Er geht da ziemlich ausführlich auf die Inter-Prozess-Kommunikation bei global Hooks ein, um die du auch nicht herumkommen wirst. Also solltest du dir dieses Tutorial mal zu Gemüte führen.

[Nachtrag]

... und natürlich erst mal den Hook finden, mit dem du WM_WINDOWPOSCHANGING abfangen kannst.


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