0
votes

I have a question: how I can create FMX window to make it looks like ShowMessage window?

ShowMessage (contain Move and Close items):

enter image description here

FMX window:

BorderIcons := [TBorderIcon.biSystemMenu];
BorderStyle := TFmxFormBorderStyle.Single;

enter image description here

What I need: remove Icon and delete disabled menu items

1

1 Answers

3
votes

On Windows, ShowMessage() displays a system dialog using the Win32 API MessageBoxIndirect() function.

To customize the default system menu of a standard FMX form, you have to drop down to the Win32 API layer and manipulate the system menu directly. That means getting the HWND of the Form (you can use the FormToHWND() function in the FMX.Platform.Win unit) and then use the Win32 API GetMenu() and DeleteMenu() functions.

To remove the Form's icon, use the Win32 API SendMessage() function to send the HWND a WM_SETICON message with the lParam set to 0. Or use SetWindowLongPtr() to enable the WS_EX_DLGMODALFRAME window style.

Override the Form's virtual CreateHandle() method to perform these operations, eg:

interface

...

type
  TForm1 = class(TForm)
    ...
  {$IFDEF MSWINDOWS}
  protected
    procedure CreateHandle; override;
  {$ENDIF}
    ...
  end;

implementation

{$IFDEF MSWINDOWS}
uses
  Windows;
{$ENDIF}

...

{$IFDEF MSWINDOWS}
procedure TForm1.CreateHandle;
var
  Wnd: HWND;     
  Menu: HMENU;
  ExStyle: LONG_PTR;
begin
  inherited;
  Wnd := FormToHWND(Self);

  Menu := GetMenu(Wnd);
  DeleteMenu(Menu, SC_TASKLIST, MF_BYCOMMAND);
  DeleteMenu(Menu, 7, MF_BYPOSITION);
  DeleteMenu(Menu, 5, MF_BYPOSITION);
  DeleteMenu(Menu, SC_MAXIMIZE, MF_BYCOMMAND);
  DeleteMenu(Menu, SC_MINIMIZE, MF_BYCOMMAND);
  DeleteMenu(Menu, SC_SIZE, MF_BYCOMMAND);
  DeleteMenu(Menu, SC_RESTORE, MF_BYCOMMAND);

  SendMessage(Wnd, WM_SETICON, ICON_SMALL, 0);
  SendMessage(Wnd, WM_SETICON, ICON_BIG, 0);

  ExStyle := GetWindowLongPtr(Wnd, GWL_EXSTYLE);
  SetWindowLong(Wnd, GWL_EXSTYLE, ExStyle or WS_EX_DLGMODALFRAME);
  SetWindowPos(Wnd, 0, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE or SWP_NOZORDER or SWP_FRAMECHANGED);
end;
{$ENDIF}

...

end.