How To add items to the system menu

How to add items to the system menu at the top left of the form.

type
  TForm1 = class(TForm)
  ...
    procedure FormCreate(Sender: TObject);
  private
    procedure WMSYSCOMMAND(var message: TWMSYSCOMMAND); message WM_SYSCOMMAND;

...

procedure TForm1.FormCreate(Sender: TObject);
const
  MenuCaption = '&About...';
var
  i: Integer;
  SystemMenu: HMenu;
  MENUITEMINFO: TMENUITEMINFO;
begin
  SystemMenu := GetSystemMenu(Handle, False);
  i := GetMenuItemCount(SystemMenu);
  FillChar(MENUITEMINFO, SizeOf(MENUITEMINFO), 0);
  { Don't use SizeOf(MENUITEMINFO) because it's required for
   Windows 95 }
  MENUITEMINFO.cbSize := 44;
  // Separator
  MENUITEMINFO.fMask := MIIM_TYPE;
  MENUITEMINFO.fType := MFT_SEPARATOR;
  InsertMenuItem(SystemMenu, i, TRUE, MENUITEMINFO);
  // Adding About now
  MENUITEMINFO.fMask := MIIM_TYPE or MIIM_ID;
  MENUITEMINFO.fType := MFT_STRING;
  MENUITEMINFO.dwTypeData := PChar(MenuCaption);
  MENUITEMINFO.cch := Length(MenuCaption);
  MENUITEMINFO.wID := 1101; // ID must be < $F000
  InsertMenuItem(SystemMenu, i+1, TRUE, MENUITEMINFO);
end;

procedure TForm1.WMSYSCOMMAND(var message: TWMSYSCOMMAND);
begin
  inherited;
  case message.CmdType of
    1101: ShowMessage('About me');
  end;
end;

The previous code doesn't add a menu item to the system menu of the
application button in the taskbar (when you right-click it). It's
because delphi creates a hidden window. You have to do the work
twice in order to add the same menu for that window. Unfortunately,
the object receiving the WM_SYSCOMMAND message is that window too :

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

...

procedure TForm1.FormCreate(Sender: TObject);
const
  MenuCaption = '&About...';
var
  i: Integer;
  SystemMenu: HMenu;
  MENUITEMINFO: TMENUITEMINFO;
begin
  Application.OnMessage := OnAppMessage;
  SystemMenu := GetSystemMenu(Application.Handle, False);
  // same code as before
  ...
end;

procedure TForm1.OnAppMessage(var Msg: TMsg; var Handled: Boolean);
begin
  if (Msg.message = WM_SYSCOMMAND) and (Msg.wParam = 1101) then
  begin
    ShowMessage('About me');
    Handled := True;
  end;
end;

 

Share this article!

Follow us!

Find more helpful articles: