Eigene Menuitems in taskbar-popup einschleusen
Hallo liebe Forengemeinde,
nachdem ich in der Suche nichts gefunden habe, stelle ich eben nun meine Frage als neuen Thread, die hier hoffentlich richtig ist :) Eine Applikation mit Fenstern bekommt ja zunächst einen tab in der Taskleiste, wenn man es nicht explizit unterbindet. Durch Rechtsklick öffnet sich ein popup fürs wiederherstellen, verschieben, maximieren ... Ich habe gerade bei einem Programm, welches stets mit zu niedriger Priorität startet das Bedürfnis verspürt, dort schnell einen weiteren Menüpunkt "boost priority" einzufügen - oder zumindest ein Untermenü, welches die Prozesspriorität oder die der einelnen Threads einstellen lässt. Das zu tun ist für mich kein Problem, nur habe ich keine Ahnung, wie ich das MenuItem-Problem elegant lösen kann. Ich vermute, dass es dazu bestenfalls eine undokumentierte API gibt, im schlimmsten Fall muss man ein paar Klassen in der registry eintragen. Die schlechte Methode wäre, sich die ChildWindow-Hierarchie entlangzuhangeln und mit etwas Glück den Handle auf ein Element des Menüs zu finden. Hat jemand Ideen? Danke schonmal :) |
Re: Eigene Menuitems in taskbar-popup einschleusen
Hallo, Tino from DF hat hier eine Möglichkeit veröffentlicht. (Stichworte: AppendMenu, GetSystemMenu, Taskbar)
|
Re: Eigene Menuitems in taskbar-popup einschleusen
|
Re: Eigene Menuitems in taskbar-popup einschleusen
mein aktueller Stand ist nun folgender :
Delphi-Quellcode:
dll:
program ppext;
{$APPTYPE CONSOLE} uses Windows; type TChar = {$IFDEF UNICODE} WideChar; {$ELSE} Char; {$ENDIF} const MyMenuItemCaption = 'Set process priority ...'; WH_MOUSE_LL = 14; // NT only? var hMouseHook: HHook; hDLL: hModule; MouseHookProc: Pointer; function CleanUpEnumWindowProc(handle:HWND; param: Pointer):BOOL; StdCall; var hSystemMenu : THandle; bla : Array[0..255] of char; i,n: integer; itemtitle: string; begin zeromemory(@bla[0],256); if IsWindowVisible(handle) then begin hSystemMenu := GetSystemMenu(handle,false); n := windows.GetMenuItemCount(hSystemMenu); for i := n-1 downto 0 do begin Windows.GetMenuString(hSystemMenu,i,@bla[0],256 div SizeOf(TChar)-1,MF_BYPOSITION); itemtitle := PAnsiChar(Pointer(@bla[0])); if itemtitle = MyMenuItemCaption then begin if windows.DeleteMenu(hSystemMenu,i,MF_BYPOSITION) then inc(integer(param^)); end; end; end; result := true; end; function CreatingEnumWindowProc(handle:HWND;param: Pointer):BOOL; StdCall; var hSystemMenu : THandle; bla : Array[0..255] of char; itemtitle: string; m: tagMENUITEMINFO; function HasPPMenuItem ( hMenu: THandle ): Boolean; var i,n: integer; begin result := false; n := windows.GetMenuItemCount(hMenu); for i := n-1 downto 0 do begin zeromemory(@bla[0],256); Windows.GetMenuString(hSystemMenu,i,@bla[0],256 div SizeOf(TChar)-1,MF_BYPOSITION); itemtitle := PAnsiChar(Pointer(@bla[0])); if itemtitle = MyMenuItemCaption then begin result := true; break; end; end; end; begin if IsWindowVisible(handle) then begin hSystemMenu := GetSystemMenu(handle,false); if hSystemMenu <> 0 then if not HasPPMenuItem (hSystemMenu) then begin if InsertMenu( hSystemMenu,0,MF_ENABLED,0,MyMenuItemCaption) then inc(integer(param^)); end; end; result := true; end; // main var count: integer; begin EnumWindows( @CreatingEnumWindowProc,Cardinal(Addr(count))); writeln(count, ' new menu items installed.'); count := 0; hMouseHook := 0; hDLL := LoadLibrary('MouseHookHandler.dll'); if hDLL <> 0 then begin MouseHookProc := GetProcAddress(hDLL,'CallbackProc'); hMouseHook := SetWindowsHookEx( WH_MOUSE_LL,MouseHookProc,hDLL,0); if hMouseHook <> 0 then writeln('Hook set.'); end; readln; EnumWindows( @CleanUpEnumWindowProc,Cardinal(Addr(count))); writeln(count, ' items removed.'); if hMouseHook <> 0 then begin UnhookWindowsHookEx(hMouseHook); writeln('Unhooked.'); end; if hDLL <>0 then windows.FreeLibrary(hDLL); readln; end.
Delphi-Quellcode:
library MouseHookHandler;
uses Windows; {$R *.res} var hMouseHook : hHook; function CallbackProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; begin // custom handling in background result := CallNextHookEx( hMouseHook, nCode, wParam, lParam); end; procedure SetHookHandle(h : HHOOK); stdcall; begin hMouseHook := h; end; exports CallbackProc, SetHookHandle; begin end. mal deinen Link anschauen... |
Re: Eigene Menuitems in taskbar-popup einschleusen
Liste der Anhänge anzeigen (Anzahl: 1)
soll das menü auch für andere anwender sichtbar sein oder reichts auch nur an deinem rechner? in diesem (zweiten) falle kann ich das programm "DM2" (http://dm2.sourceforge.net/, GPL) empfehlen, unter anderem bietet es ein solches menü an
|
Re: Eigene Menuitems in taskbar-popup einschleusen
Mein aktuelles Problem ist: wie komm ich von der Windows-Oberfläche wieder zurück zu meiner Applikation... und da sehe ich gerade keinen anderen Weg, als über Hooks zu gehen, weil wohl allein schon aus Sicherheitsgründen beim Menüklick kein Aufruf in einen anderen Prozess vorgesehen sein wird. Überhaupt, mit ist diese MenuItem-Architektur von Windows sehr suspekt
|
Re: Eigene Menuitems in taskbar-popup einschleusen
Du willst für dein Komsolenprogramm das Systemmenü ändern? Das wird schwierig, weil das Konsolenfenster von Windows kontrolliert wird, während hingegen ein Anwendungsfenster weitgehend von der Anwendung selber kontrolliert wird.
Hinzukommt, wie willst du auf eine Klick auf deinen Menüpunkt reagieren? Du hast keine Nachrichtenschleife und keiner Fensterprozedur. Angesichts dieser Problem, würde ich mir eine andere Lösung überlegen, die einfacher zu implementieren ist. Auch spricht deine Lösung gegen die Benutzerfreundlichkleit. Wer kommt schon auf die Idee, dass im Systemmenü des Konsolenfensters, welches eigentlich nur eine Box für dein Programm ist, Optionen zu finden sind, die sich auf dein Programm beziehen? @helgew: Was ist an der Menüitemstruktur von Windows suspekt? |
Re: Eigene Menuitems in taskbar-popup einschleusen
Guten Abend Luckie,
Das Konsolenprogramm ist nur zu Testzwecken, weil ich es weitestgehend ohne eigenes Message Handling zum Laufen kriegen will. Viele Programme registrieren sich außerdem ein unsichtbares, leeres Fensterchen und nutzen dessen message-Prozedur zur Kommunikation. So etwas könnte ich mir dann auch vorstellen beziehungsweise werde ich nun auch müssen. Suspekt ist mir die Handhabung der Menüs mit der tagMenuItemInfo-Struktur und dass die einzelnen Items keine Fenster im Sinne von Objekt mit Handle sind sondern jeweils vom Menü verwaltet werden, sodass ich an dieser Stelle keinen Zugriff haben kann. Nun versuch ich gerade, den mousehook zum Laufen zu bekommen ( da ich das für einen möglichen Weg von vielen halte ). Nachtrag: ich habe das ganze eben mal ein ein Formular gesteckt, jetzt gibt es auch keine Probleme mehr mit dem Hook. Jetzt muss ich nur noch das Menu wieder finden (vielleicht hätte ich doch lieber die messages abgefangen ... jetzt muss ich wohl das itemrect prüfen ... |
Re: Eigene Menuitems in taskbar-popup einschleusen
So.. nachdem sich jetzt auch noch das Menü nicht wieder erreichen lässt, gönn ich mir mal ne Mütze Schlaf.
Letzter Stand der DLL:
Delphi-Quellcode:
library MouseHookHandler;
uses Windows, Messages; {$R *.res} var hMouseHook : hHook; lasthandle: THandle; type TChar = {$IFDEF UNICODE} WideChar; {$ELSE} Char; {$ENDIF} function CallbackProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; var hWnd : THandle; bla : Array[0..255] of Char; pt:TPoint; text: string; i, n: integer; r : TRect; hMenu: THandle; begin // custom handling in background // lParam : integer(^MOUSEHOOKSTRUCT) pt := PMouseHookStruct(lParam)^.pt; // wParam : mouse message if wParam = WM_MOUSEMOVE then lasthandle := WindowFromPoint(pt); if wParam = WM_LBUTTONDOWN then begin hMenu := GetSystemMenu(lastHandle); if windows.IsMenu(hMenu) then begin //n := GetMenuItemCount(hWnd); //for i := 0 to n - 1 do begin {GetMenuItemRect(0,hWnd,i,r); if (r.Left <= pt.X) and (pt.X <= r.Right) and (r.Top <= pt.Y) and (pt.Y <= r.Bottom) then //} begin windows.MessageBox(0,'Erh... please be patient.','Programmer too lazy',mb_ok); end; end; end; end; // continue hook chain. No exceptions needed result := CallNextHookEx( hMouseHook, nCode, wParam, lParam); end; procedure SetHookHandle(h : HHOOK); stdcall; begin hMouseHook := h; end; exports CallbackProc, SetHookHandle; begin end. |
Re: Eigene Menuitems in taskbar-popup einschleusen
Liste der Anhänge anzeigen (Anzahl: 1)
Und weiter gehts...
Ich hab mittlerweile ein paar andere, globale Hooks durchprobiert und werde nicht schlau daraus. Gehören die Menus etwa zu jedem eigenen Programm? Wenn ja, wieso finde ich nirgends eine WM_COMMAND message? Nachtrag: Mittleweile habe ich die Messages http://msdn.microsoft.com/de-de/library/ms647591(en-us).aspx jedoch kann ich keinen click detektieren... verdammte System Menus |
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:26 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