![]() |
Hook / Popupmenu
Hallo Leute,
ich will in einer Anwendung das Popupmenü "abfangen" und verändern. Nehmen wir z. Bsp. mal Notepad. Drücke ich die rechte Maustaste, erscheint das Popup mit Ausschneiden, Einfügen etc. Wie komme ich an dieses Popup? Ich habe bereits einen Hook, der mir "sagt", daß die rechte Maustaste gedrückt wurde, aber das Popup kommt ja erst danach :roll: Das bringt als nicht wirklich was :gruebel: Und die nächste spannende Frage wäre, wenn ich das Popupmenü nun um meine Einträge erweitert habe, wie bekomme ich mit, daß so ein Eintrag ausgwählt wurde? Es wäre nett, wenn mich jemand in die richte Richtung schubsen würde :tongue: Danke bye |
Re: Hook / Popupmenu
Zitat:
Die erste, die ich dir empfehlen würde ist die SetWindowsHookEx-Funktion zu benutzen und damit einen Hook zu "installieren" (welchen typ von hook man dazu braucht steht in der msdn). Dann musst du in der hook-callback-funktion einfach noch auf die WM_CONTEXTMENU-Message warten, dann weißt du, dass ein Kontextmenü aufgerufen wurde. Das kannst du dann nach belieben verändern. Die andere Methode, die ich mal verwendet hab lief über Function-Hooking. Dazu habe ich auch ein Beispiel gepostet: ![]() Allerdings rate ich dir von dieser Methode ab, wenn es nicht unbedingt sein muss, da diese lange nicht so "sauber" ist wie die über SetWindowsHookEx. Zitat:
mfg, Philipp |
Re: Hook / Popupmenu
Hey,
also du könntest, nachdem du die Hook Message erhalten hast, versuchen das Fenster des Popups (google mal nach dem Klassennamen, es sind Ziffern, die ich leider nicht mehr im Kopf habe) zu finden. Die Auswahl wird gewöhnlich an das Parent-Fenster (also Notepad) geschickt. Da müsstest du nun auch versuchen, per Hook an die WM_COMMAND Nachricht zu kommen... Grüße, Lizard Edit: zu lahm... |
Re: Hook / Popupmenu
Hallo Leute,
danke erst mal, für die Antworten... aber irgendwie komme ich noch nicht ganz klar. Mein Msg-Hook sie so aus
Delphi-Quellcode:
Gut, ich gebe zu, daß ich den Code mir "zuammengesucht" habe und nicht unbedigt weiß, was da abgeht, aber "optisch" sieht es doch gut aus, oder? :gruebel: (Keyboard-/Maus-Hooks funktionieren)
function MsgHookProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM):
LRESULT; stdcall; var Scancode : Integer; type PMsg = ^TMsg; var msg: PMsg; begin if ncode = HC_ACTION then with Windows.PMsg(lParam)^ do if message = WM_INITMENUPOPUP then begin showmessage('hab dich!'); end; Result := CallNextHookEx(HookHandleMsg, nCode, wParam, lParam); end; Nochmal, was ich eigentlich machen will: Ein Kontext-/Popup-Menu einer anderen Anwendung abfangen und zusätzliche Menüeinträge anhängen. Das kann doch nicht so schwierig sein.... :coder2: |
Re: Hook / Popupmenu
@golisan:
Ich glaube wir sind alle nicht scharf drauf jetzt den Rest selbst zu schreiben, um auszuprobieren, was an deinem Code nicht funktioniert, daher wäre es besser, wenn du genau sagst, womit du nicht klar kommst, was nicht funktioniert, usw. . Außerdem, ein erster Blick verrät mir, dass das nur schief gehen kann, da du ShowMessage verwendest. Dies ist eine Funktion aus der VCL, und sollte somit nicht in irgendwelchen Threads in irgendwelchen Programmen außerhalb der VCL aufgerufen werden. Es würde mich also nicht wundern, wenn es da AccessViolations hagelt ... Benutze doch bitte lieber MessageBox. mfg, Philipp |
Re: Hook / Popupmenu
@c113plpbr
Sorry, ich habe nur den Teil gepostet, da der Rest funktioniert. Ich dachte, evtl. ist es nur ein kleiner Bug. Also die Hooks sind in einer DLL. Den Tastatur- und Maushook habe ich nur zur Testzwecken, um zu prüfen, ob's überhaupt tut...
Delphi-Quellcode:
In einer Form lade ich den Hook..
library myhook;
uses Windows, Messages, SysUtils; var HookHandleKB : Cardinal = 0; HookHandleM : Cardinal = 0; HookHandleMsg : Cardinal = 0; WindowHandle : Cardinal = 0; // ------------------------------ Keyboard ------------------------------- function KeyboardHookProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; var Scancode : Integer; begin Result := CallNextHookEx(HookHandleKB, nCode, wParam, lParam); case nCode < 0 of TRUE: exit; //wenn code kleiner 0 wird nix gemacht FALSE: begin MessageBox(0,'ok','Info',MB_OK); end; end; end; // ------------------------------ Mouse ------------------------------- function MouseHookProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; var Scancode : Integer; begin Result := CallNextHookEx(HookHandleM, nCode, wParam, lParam); case nCode < 0 of TRUE: exit; //wenn code kleiner 0 wird nix gemacht FALSE: begin end; end; end; // ------------------------------ MSG ------------------------------- function MsgHookProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; var Scancode : Integer; type PMsg = ^TMsg; var msg: PMsg; begin if ncode = HC_ACTION then with Windows.PMsg(lParam)^ do begin if (message = WM_INITDIALOG) or (message = WM_SETFOCUS) then begin MessageBox(0,'ok','Info',MB_OK); end end; Result := CallNextHookEx(HookHandleMsg, nCode, wParam, lParam); end; function InstallHook(Hwnd: Cardinal): Boolean; stdcall; begin Result := False; if HookHandleKB = 0 then begin HookHandleKB := SetWindowsHookEx(WH_KEYBOARD, @KeyboardHookProc, HInstance, 0); WindowHandle := Hwnd; Result := TRUE; end; if HookHandleM = 0 then begin HookHandleM := SetWindowsHookEx(WH_MOUSE, @MouseHookProc, HInstance, 0); WindowHandle := Hwnd; Result := TRUE; end; if HookHandleMSG = 0 then begin HookHandleMsg := SetWindowsHookEx(WH_GETMESSAGE, @MsgHookProc, HInstance, 0); WindowHandle := Hwnd; Result := TRUE; end; end; function UninstallHook: Boolean; stdcall; begin //Hook aus der Hookchain entfernen //Uninstall hook from hook chain Result := UnhookWindowsHookEx(HookHandleKB); Result := UnhookWindowsHookEx(HookHandleM); Result := UnhookWindowsHookEx(HookHandleMsg); HookHandleKB := 0; HookHandleM := 0; HookHandleMsg := 0; end; exports //Installations- und Deinstallationsroutine exportieren //Export the installation and deinstallation routine InstallHook, UninstallHook; end.
Delphi-Quellcode:
und starte dann den Hook..
initialization
begin lib := LoadLibrary('myhook.dll'); if lib <> INVALID_HANDLE_VALUE then begin InstallHook := GetProcAddress(lib, 'InstallHook'); UnInstallHook := GetProcAddress(lib, 'UninstallHook'); end else showmessage('myHook.dll wurde nicht gefunden!'); end;
Delphi-Quellcode:
Wie gesagt, Maus- und Tastatur-Hook funktionieren! Nur der Message-Hook nicht richtig.
installHook(0); // Wozu brauche ich hier ein HWND?? Es geht auch ohne...
Es kommen Messages an, nur nicht WM_INITPOPUPMENU oder WM_CONTEXTMENU, obwohl die laut Winsight/ Winspector "rumschwirren" Und DAS verstehe ich nicht. :wall: Was läuft beim Message-Hook anders als beim Maus- Tastatur-Hook?? Habt ihr eine Idee?? Danke! PS: ShowMessage tut auch in einer nonVCL, hab's aber trotzdem gegen ein MessageBox getauscht. :wink: |
Re: Hook / Popupmenu
Zitat:
So steht in der MSDN z.B. bei WH_SYSMSGFILTER, dass hier menü-messages ankommen ... vielleicht sind da ja deine dabei ... ansonsten könnten sie noch in WH_MSGFILTER auftauchen, und wenns da auch ned geht, werden sie in jedem Fall an die WindowProc geschickt, kannste auch abfangen mit nem WH_CALLWNDPROC-Hook. Zitat:
mfg, Philipp |
Re: Hook / Popupmenu
Hallo,
ich bin jetzt einen (halben?) Schritt weiter! :wink: Der Tipp, statt WH_GETMESSAGE lieber WH_CALLWNDPROC zu verwenden, war genau der richtige! Ich habe jetzt das Kontextmenü im Zugriff... aber irgendwie komme ich mit dem AppendMenu nicht zurecht. Ich möchte folgende Struktur (bestehendes Menü) Punkt 1 Punkt 2 Punkt 3 (jetzt sollen "meine" Einträge angehängt werden. MeinPunkt1 (nur ein Untermenüpukt) UnterMeinpunkt1 (nur ein Untermenüpunkt) UnterMeinpunkt1_1 (der erste "echte" Menüpunkt) UnterMeinpunkt1_2 . . UnterMeinpunkt2 (nur ein Untermenüpunkt) UnterMeinpunkt2_1 (der erste "echte" Menüpunkt) UnterMeinpunkt2_2 . . Die Menüpunkte werden auch erzeugt aber irgendwie "rekursiv". Hier der Code
Delphi-Quellcode:
und so siehts aus:
nse := createPopupMenu;
subs := createPopupMenu; books := createPopupMenu; AppendMenu(subs, MF_STRING or MF_ENABLED, 2000, PChar('UnterMeinpunkt1')); AppendMenu(books, MF_STRING or MF_ENABLED, 3000, PChar('UnterMeinpunkt2')); AppendMenu(nse, MF_STRING or MF_POPUP, subs, PChar('UnterMeinpunkt1')); AppendMenu(nse, MF_STRING or MF_POPUP, books, PChar('UnterMeinpunkt1')); AppendMenu(natmenu, MF_STRING or MF_POPUP, nse, PChar('MeinPunkt1')); (bestehendes Menü) Punkt 1 Punkt 2 Punkt 3 MeinPunkt1 (nur ein Untermenüpukt) ok soweit UnterMeinpunkt1 ok soweit UnterMeinpunkt2 ok soweit MeinPunkt1(und "darunter" wieder UnterMeinPunkt1/2 usw usw Was macht "MeinPunkt1" hier?? Habt ihr einen Tipp? Danke |
Re: Hook / Popupmenu
Naja, dein Resultat klingt logisch, da du vermutlich bei jedem Aufruf deine Menüeinträge hinzufügst, und diese nie wieder löschst. Somit werden es immer mehr ...
Als ich sowas gemacht habe, musste ich außerdem immer nachdem das Menü dann wieder verschwunden war, die Menüeinträge entfernen, sonst gab es verschiedenste Probleme. mfg, Philipp |
Re: Hook / Popupmenu
Hallo Philipp,
danke! Genau das war's :thumb: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:52 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