Mirror

How to add a menu item to the Windows Taskbar popup menu (Views: 708)


Problem/Question/Abstract:

I want to add a menu item to the menu, which pops up when you right-click on the taskbar button for your application. I know how to add item to form system menu, but it doesn't change the popup menu on the taskbar.

Answer:

Solve 1:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ExtCtrls;

const
  idSysAbout = 100;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  public
    procedure AppMessage(var Msg: TMsg; var Handled: Boolean);
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.AppMessage(var Msg: TMsg; var Handled: Boolean);
begin
  if (Msg.message = WM_SYSCOMMAND) and (Msg.WParam = idSysAbout) then
  begin
    ShowMessage('This is a test');
    Handled := True;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  AppendMenu(GetSystemMenu(Application.Handle, False), MF_SEPARATOR, 0, '');
  AppendMenu(GetSystemMenu(Application.Handle, False), MF_STRING, idSysAbout, 'Test');
  Application.OnMessage := AppMessage;
end;

end.


Solve 2:

The popup menu for a Taskbar button is the Application windows system menu. To add items to it you need to use API functions.

{ ... }
var
  hSysMenu: HMENU;
begin
  hSysMenu := getSystemMenu(Application.handle, false);
  AppendMenu(hSysmenu, MF_STRING, $100, 'My Item');

The item IDs you use ($100 in this example) need to be multiples of 16, in hex notation that means the last digit is 0. Take care not to conflict with the predefined SC_ menu constants for the system menu. All of these have values above 61000.

To get informed when the user selects your new item you need to hande the WM_SYSCOMMAND message send to the Application window. For this you attach a hook to it, using Application.HookMainWindow.

procedure TForm1.FormCreate(Sender: TObject);
var
  hSysMenu: HMENU;
begin
  hSysMenu := getSystemMenu(application.handle, false);
  AppendMenu(hSysmenu, MF_STRING, $100, 'My Item');
  Application.HookMainWindow(AppHook);
end;

function Tform1.AppHook(var Message: TMessage): Boolean;
begin
  if (message.Msg = WM_SYSCOMMAND) and ((message.WParam and $FFF0) = $100) then
  begin
    Result := true;
    ShowMessage('Hi, folks');
  end
  else
    Result := false;
end;

<< Back to main page