Карта сайтаСсылкиКонтакты

Изменение системного меню

PDF Печать
Статьи

С помощью API Windows мы можем настраивать системное меню формы. Так, например, мы можем добавить свой пункт меню или удалить уже имеющийся, изменить пункт меню по умолчанию и даже добавить растровое изображение.

Изменение системного меню формы приложения

Для того, чтобы получить доступ к системному меню, нужно использовать функцию GetSystemMenu API Windows. Также далее мы будем использовать AppendMenu, SetMenuItemInfo, а также структуру TMenuItemInfo. После добавления своего пункта меню, нужно добавить ловушку на сообщение WM_SYSCOMMAND, чтобы узнать, когда будет выбран наш пункт меню.

Добавление пункта меню

Следующий код демонстрирует исользование функции AppendMenu для добавления нового пункта в системное меню формы. Для начала, нам нужно определить новую константу SC_MyMenuItem, которая будет идентифицировать наш новый пункт меню.


const
    SC_MyMenuItem = WM_USER + 1;

{ ... } 

procedure TForm1.btnAddItemClick(Sender: TObject);
const
  sItemCaption = 'Новый пункт меню';
var
  sysMenu: HMenu;
begin
  { Получаем идентификатор системного меню }
  sysMenu:= GetSystemMenu(Handle, false);
  { Добавляем разделитель меню }
  AppendMenu(sysMenu, MF_SEPARATOR, 0, '');
  { Добавляем наше меню }
  AppendMenu(sysMenu, MF_STRING, SC_MyMenuItem, sItemCaption);
end;

После добавления пункта меню, мы должны отловить сообщение WM_SYSCOMMAND для обработки щелчка.


private
  { Private declarations }
  procedure WMSysCommand(
      var Msg: TWMSysCommand); message WM_SYSCOMMAND;

{ ... }

procedure TForm1.WMSysCommand(var Msg: TWMSysCommand);
begin
  if Msg.CmdType = SC_MyMenuItem then
    { Здесь идет код для пункта меню }
    ShowMessage('Щелкнули по новому пункту меню!')
  else
    inherited;
end;

Примечание: при сворачивании приложения, значок представляет собой приложение, а не форму. Поэтому, чтобы измененное меню работало и в свернутом виде, нужно использовать Application.Handle, а не просто Handle, когда будете добавлять свой пункт меню.

Удаление системного пункта меню

При удалении пункта системного меню, мы также удаляем возможность выполнения его из системного меню формы. При помощи DeleteMenu давайте удалим пункт Переместить.

Обратите внимание: после удаления этого пункта меню, мы не сможем больше перемещать форму. Это не самый лучший способ удаления меню.


procedure TForm1.btnDeleteItemClick(Sender: TObject);
const
  mnuCommand = SC_MOVE;
var
  sysMenu: HMenu;
begin
  sysMenu:= GetSystemMenu(Handle, false);
  DeleteMenu(sysMenu, mnuCommand, MF_BYCOMMAND);
end;

Изменение заголовка пункта меню

Чтобы изменить заголовок пункта системного меню, мы должны вызвать функцию SetMenuItemInfo и отправить ей структуру TMenuItemInfo, которая содержит информацию о пункте меню.

Давайте изменим заголовок пункта меню Закрыть.


procedure TForm1.btnChangeItemCaptionClick(Sender: TObject);
const
  sCaption = 'Закрыть наше окно';
var
  sysMenu: HMenu;
  menuItemInfo: TMenuItemInfo;
begin
  sysMenu:= GetSystemMenu(Handle, false);

  FillChar(MenuItemInfo, SizeOf(TMenuItemInfo), #0);
  with MenuItemInfo do
  begin
    cbSize:= SizeOf(TMenuItemInfo);
    fMask:= MIIM_TYPE or MIIM_ID or MIIM_STATE;
    fType:= MFT_STRING;

    wID:= SC_CLOSE;
    dwTypeData:= sCaption;
    cch:= Length(sCaption);
  end;
  SetMenuItemInfo(sysMenu, SC_CLOSE, false, MenuItemInfo);
end;

Добавление изображения в пункт меню

Для этого выберите изображение в формате bmp и поместите его в папку с проектом. Я взял изображение, которое идет вместе с Delphi и находится в папке Program Files\Common Files\Borland Shared\Images\Icons и называется CHEM16.BMP.

Запишите следующий код:


private
  { Private declarations }
  myBmp: TBitmap;

 { ... }

procedure TForm1.FormCreate(Sender: TObject);
begin
  myBmp:= TBitmap.Create;
  myBmp.LoadFromFile('CHEM16.BMP');
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  myBmp.Free;
end;

procedure TForm1.btnChangeItemCaptionClick(Sender: TObject);
const
  sCaption = 'Закрыть наше окно';
var
  sysMenu: HMenu;
  menuItemInfo: TMenuItemInfo;
begin
  sysMenu:= GetSystemMenu(Handle, false);

  FillChar(menuItemInfo, SizeOf(TMenuItemInfo), #0);
  with menuItemInfo do
  begin
    cbSize:= SizeOf(TMenuItemInfo);
    fMask:= MIIM_TYPE or MIIM_ID or MIIM_STATE;
    fType:= MFT_STRING;

    wID:= SC_CLOSE;
    dwTypeData:= sCaption;
    cch:= Length(sCaption);
  end;
  SetMenuItemInfo(sysMenu, SC_CLOSE, false, menuItemInfo);
end;

Вот и все по работе с системным меню формы нашего приложения.


 

Добавить комментарий


Защитный код
Обновить