С помощью 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;
Вот и все по работе с системным меню формы нашего приложения.
|
Комментарии
Второй раз приведена функция "btnChangeItemC aptionClick" - которая меняет заголовок пункта меню, а функции замены изображения нет...
RSS лента комментариев этой записи