In the system menu (topleft of titlebar), I can add my own menu items.
I can also delete e.g.DeleteMenu(SysMenu, SC_MINIMIZE, MF_BYCOMMAND) ;
However if I delete the standard ones [restore,minimize,maximize,size,close] their functionality is lost (i.e. maximize button no longer works)
Is there a way to hide these menuitems or move them off the first rank of the system menu? a) make them not visible b) move to a submenu c) delete but still get button messages
a) make them not visible
The API has no concept of a hidden/invisible menu item.
b) move to a submenu
You can move (or rather delete and add) items to a submenu without effecting functionality.
E.g. move "minimize" to a submenu:
var
SysMenu, SubMenu: HMENU;
StrMin: string;
StrMinLen: Integer;
begin
SysMenu := GetSystemMenu(Handle, False);
StrMinLen := GetMenuString(SysMenu, SC_MINIMIZE, nil, 0, MF_BYCOMMAND);
if StrMinLen > 0 then begin
Inc(StrMinLen);
SetLength(StrMin, StrMinLen);
GetMenuString(SysMenu, SC_MINIMIZE, PChar(StrMin), StrMinLen, MF_BYCOMMAND);
SubMenu := CreateMenu;
if SubMenu <> 0 then begin
DeleteMenu(SysMenu, SC_MINIMIZE, MF_BYCOMMAND);
AppendMenu(SubMenu, MF_STRING, SC_MINIMIZE, PChar(StrMin));
InsertMenu(SysMenu, 0, MF_BYPOSITION or MF_POPUP, SubMenu, 'Minimize->');
InsertMenu(SysMenu, 1, MF_BYPOSITION or MF_SEPARATOR, 0, nil);
end;
end;
Destroy the submenu before restoring the system menu:
var
Info: TMenuItemInfo;
begin
Info.cbSize := SizeOf(Info);
Info.fMask := MIIM_SUBMENU;
if GetMenuItemInfo(GetSystemMenu(Handle, False), 0, True, Info) then
DestroyMenu(Info.hSubMenu);
GetSystemMenu(Handle, True);
c) delete but still get button messages
If you delete, f.i., the "minimize" item, the system does not send WM_SYSCOMMAND
messages for the minimize command to the window. So there won't be any command to respond to.
You can still listen for button messages, f.i. a left button down. But a button down/up message is not actually the same thing with a button click. A button click consists of three actions, mouse down, capture and up again on the button. If you want to do it anyway an example can be:
procedure TForm1.WMNCLButtonDown(var Message: TWMNCLButtonDown);
begin
inherited;
if (Message.HitTest = HTMINBUTTON) and not IsIconic(Handle) then
ShowWindow(Handle, SW_MINIMIZE);
end;