![]() |
WndProc-Hook um WM_GETMINMAXINFO eines fremden Fensters zu verändern
Hallo,
abgelöst von diesem ![]() Ich möchte die Message "WM_GETMINMAXINFO" einer fremden Anwendung abfangen und für das Fenster modifizieren. Ich habe gestern viel im Forum über Hooks gelesen, aber so wirklich dahinter gestiegen, wie das funktioniert bin ich nicht wirklich. Ich kann zwar Nachrichten empfangen, aber anscheindend auch nicht alle. Hier mal die DLL:
Delphi-Quellcode:
Und hier der Code der Anwendung:
library WndProcHook;
uses Windows, Messages; type TMyCallBack = procedure(nCode: Integer; WPARAM: WPARAM; LPARAM: LPARAM); stdcall; var HookHandle: Cardinal = 0; WindowHandle: THandle = 0; FCallBack: TMyCallBack = nil; function CallWndProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; begin // Result := 0; If HookHandle = 0 then exit; //es ist ebenfalls moeglich die Bearbeitung an eine Bedingung zu knüpfen Result := CallNextHookEx(HookHandle, nCode, wParam, lParam); If nCode = HC_ACTION then begin // with Windows.PMsg(lParam)^ do begin // If hWnd = WindowHandle then If Assigned(FCallBack) then FCallBack(nCode, WPARAM, LPARAM); end; end; end; function InstallHook(hWnd: THandle; aCallBack: TMyCallBack): Boolean; stdcall; begin //Rückgabewert vordefinieren Result := false; If HookHandle = 0 then begin //Hook installieren HookHandle := SetWindowsHookEx(WH_CALLWNDPROC, @CallWndProc, HInstance, 0); WindowHandle := hWnd; FCallBack := aCallBack; //Rückgabewert setzen Result := true; end; end; function UninstallHook: Boolean; stdcall; begin //Hook aus der Hookchain entfernen Result := UnhookWindowsHookEx(HookHandle); HookHandle := 0; end; exports //Installations- und Deinstallationsroutine exportieren InstallHook, UninstallHook; end.
Delphi-Quellcode:
"Message" wird nur ins Memo geschrieben, wenn ich die eigene Form verändere. Bei einer fremden aber nicht.
unit Unit2;
interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls; type TMyCallBack = procedure(nCode: Integer; WPARAM: WPARAM; LPARAM: LPARAM); stdcall; TInstallHook = function(hWnd: THandle; aCallBack: TMyCallBack): Boolean; stdcall; TUninstallHook = function: Boolean; stdcall; TForm2 = class(TForm) Label1: TLabel; Memo1: TMemo; Label2: TLabel; Button1: TButton; procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure Button1Click(Sender: TObject); private { Private-Deklarationen } InstallHook: TInstallHook; UninstallHook: TUninstallHook; lib: Cardinal; HotKey1_gesetzt: Boolean; procedure Hooken; // procedure WndProc(var Msg: TMessage); override; public { Public-Deklarationen } protected { Protected-Deklarationen } procedure WMHotKey(var Message: TMessage); message WM_HOTKEY; end; var Form2: TForm2; implementation {$R *.dfm} procedure HookCallWndProc(nCode : Integer; WPARAM : WPARAM; LPARAM : LPARAM); stdcall; var cwps: TCWPStruct; begin If nCode = HC_ACTION then begin CopyMemory(@cwps, Pointer(LPARAM), SizeOf(CWPSTRUCT)); case cwps.message of WM_GETMINMAXINFO: begin Form2.Memo1.Lines.add(Format('Message - %d', [cwps.hwnd])); // TWMGetMinMaxInfo(Msg.message).MinMaxInfo.ptMaxSize.X := 40000; // TWMGetMinMaxInfo(cwps.message).MinMaxInfo.ptMaxSize.Y := 40000; // TWMGetMinMaxInfo(cwps.message).MinMaxInfo.ptMaxTrackSize.X := 40000; // TWMGetMinMaxInfo(cwps.message).MinMaxInfo.ptMaxTrackSize.Y := 40000; end; WM_WINDOWPOSCHANGING: begin // Form2.Memo1.Lines.add(Format('Position - %d', [cwps.hwnd])); end; WM_MOVING: begin Form2.Memo1.Lines.add(Format('Moving - %d', [cwps.hwnd])); end; end; end; end; //----------------------------------------------------------------------------// procedure TForm2.Hooken; var h: THandle; begin //MainForm verstecken Form2.Visible := false; //kurze Zeit Sleep(500); h := GetForeGroundWindow; Label1.Caption := IntToStr(h); Label2.Caption := Format('App: %d - Form: %d', [Application.Handle, Form2.Handle]); If h <> 0 then InstallHook(h, HookCallWndProc); Form2.Visible := true; end; procedure TForm2.Button1Click(Sender: TObject); begin Memo1.Clear; end; procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction); begin UnInstallHook; end; procedure TForm2.FormCreate(Sender: TObject); begin //DLL laden lib := LoadLibrary(PWideChar(ExtractFilePath(Application.ExeName) + '\WndProcHook.dll')); If (lib > 0) and (lib <> INVALID_HANDLE_VALUE) then begin InstallHook := GetProcAddress(lib, 'InstallHook'); UnInstallHook := GetProcAddress(lib, 'UninstallHook'); end else begin ShowMessage('Fehler beim Laden der DLL!'); exit; end; //Hot-Key für "ganzer Bildschirm" setzen (Alt + F1) HotKey1_gesetzt := RegisterHotKey(Self.Handle, 1, MOD_ALT, VK_F1); If not HotKey1_gesetzt then ShowMessage(SysErrorMessage(GetLastError)); end; procedure TForm2.FormDestroy(Sender: TObject); begin //Registrierungen von HotKeys entfernen (nur wenn wirklich vorhanden) If HotKey1_gesetzt then UnRegisterHotKey(Self.Handle, 1); end; procedure TForm2.WMHotKey(var Message: TMessage); begin case Message.WParam of 1: begin //Alt + F1 hooken; end; end; end; end. Anscheinend werden die Messages anderer Anwendungen nicht erkannt. Was muss ich tun, damit dies möglich ist? |
AW: WndProc-Hook um WM_GETMINMAXINFO eines fremden Fensters zu verändern
Du kannst den Callback aus der Dll, die sich im anderen virtuellen Speicherbereich befindet, nicht empfangen! Prozessspeicher sind getrennt - du musst für den Callback IPS (InterProcessCommunication -> MemoryMappedFiles, Files, Pipelines, Sockets, Messages ...) anwenden, welche Methode du da nimmst, ist dir überlassen!
Beim globalen Hook wird die Dll (aus der SetWindowHookEx() mit derartigen Paramtern aufgerufen wird, sodass ein globales Hooken stattfindet (siehe MSDN - letzter param = 0)) nämlich von jedem Prozess geladen! Dh. der Code deiner Dll wird von jedem Prozess in nem eigenen Thread ausgeführt. Deshalb klappt das mit dem Callback ja auch nur, wenn die Dll bei deiner eigenen Testanwendung hookt. Weiters, falls es sich um einen kleinen Hack handelt - dann ist es viel einfacher und effizienter, eine Code-Injektion mit lokalem-Hook zu machen. Das ist an sich weniger Arbeit, verlangt aber einigies an Wissen über das Thema. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:53 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