AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Eigene Menuitems in taskbar-popup einschleusen
Thema durchsuchen
Ansicht
Themen-Optionen

Eigene Menuitems in taskbar-popup einschleusen

Ein Thema von helgew · begonnen am 30. Jul 2008 · letzter Beitrag vom 3. Aug 2008
Antwort Antwort
Seite 1 von 2  1 2      
helgew

Registriert seit: 30. Jul 2008
125 Beiträge
 
#1

Eigene Menuitems in taskbar-popup einschleusen

  Alt 30. Jul 2008, 14:18
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
  Mit Zitat antworten Zitat
Benutzerbild von toms
toms
(CodeLib-Manager)

Registriert seit: 10. Jun 2002
4.648 Beiträge
 
Delphi XE Professional
 
#2

Re: Eigene Menuitems in taskbar-popup einschleusen

  Alt 30. Jul 2008, 19:13
Hallo, Tino from DF hat hier eine Möglichkeit veröffentlicht. (Stichworte: AppendMenu, GetSystemMenu, Taskbar)
Thomas
  Mit Zitat antworten Zitat
axellang

Registriert seit: 3. Mai 2003
Ort: München
138 Beiträge
 
Delphi XE2 Enterprise
 
#3

Re: Eigene Menuitems in taskbar-popup einschleusen

  Alt 30. Jul 2008, 19:42
Versuche es mal damit: Windows TaskBar Custom Menu

Axel
Alexander Lang
  Mit Zitat antworten Zitat
helgew

Registriert seit: 30. Jul 2008
125 Beiträge
 
#4

Re: Eigene Menuitems in taskbar-popup einschleusen

  Alt 30. Jul 2008, 23:19
mein aktueller Stand ist nun folgender :

Delphi-Quellcode:
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.
dll:
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...
  Mit Zitat antworten Zitat
Crazy Ivan
(Gast)

n/a Beiträge
 
#5

Re: Eigene Menuitems in taskbar-popup einschleusen

  Alt 30. Jul 2008, 23:39
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
Miniaturansicht angehängter Grafiken
dm2_112.png  
  Mit Zitat antworten Zitat
helgew

Registriert seit: 30. Jul 2008
125 Beiträge
 
#6

Re: Eigene Menuitems in taskbar-popup einschleusen

  Alt 30. Jul 2008, 23:42
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
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#7

Re: Eigene Menuitems in taskbar-popup einschleusen

  Alt 30. Jul 2008, 23:47
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?
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
helgew

Registriert seit: 30. Jul 2008
125 Beiträge
 
#8

Re: Eigene Menuitems in taskbar-popup einschleusen

  Alt 31. Jul 2008, 00:10
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 ...
  Mit Zitat antworten Zitat
helgew

Registriert seit: 30. Jul 2008
125 Beiträge
 
#9

Re: Eigene Menuitems in taskbar-popup einschleusen

  Alt 31. Jul 2008, 01:27
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.
  Mit Zitat antworten Zitat
helgew

Registriert seit: 30. Jul 2008
125 Beiträge
 
#10

Re: Eigene Menuitems in taskbar-popup einschleusen

  Alt 31. Jul 2008, 12:08
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
Miniaturansicht angehängter Grafiken
menu_864.png  
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:25 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