如何隐藏主要表单而不是关闭它?

Ian*_*oyd 2 delphi delphi-xe6

如果用户在我的主窗体上单击X,我希望窗体隐藏,而不是关闭.这听起来像OnClose表单事件的工作:

使用OnClose在表单关闭时执行特殊处理.OnClose事件指定在表单即将关闭时要调用的事件处理程序.例如,OnClose指定的处理程序可能会测试以确保数据输入表单中的所有字段在允许表单关闭之前具有有效内容.

表单由Close方法关闭,或者当用户从表单的系统菜单中选择Close时关闭.

TCloseEvent类型指向处理表单关闭的方法.Action参数的值确定表单是否实际关闭.这些是Action的可能值:

  • caNone:表格不允许关闭,所以没有任何反应.
  • caHide:表单没有关闭,只是隐藏.您的应用程序仍然可以访问隐藏的表单.
  • caFree:表单已关闭,表单的所有已分配内存都将被释放.
  • caMinimize:表单最小化,而不是关闭.这是MDI子窗体的默认操作.

我用一个表单在空应用程序中测试:

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
    Action := caHide;
end;
Run Code Online (Sandbox Code Playgroud)

所以现在当我点击X时,(而不是隐藏)表单关闭,应用程序终止:

在此输入图像描述

...听起来像OnClose活动的工作......

奖金阅读

Vcl.Forms.pas

procedure TCustomForm.Close;
var
   CloseAction: TCloseAction;
begin
   if fsModal in FFormState then
      ModalResult := mrCancel
   else if CloseQuery then
   begin
      if FormStyle = fsMDIChild then
         if biMinimize in BorderIcons then
            CloseAction := caMinimize 
         else
            CloseAction := caNone
      else
         CloseAction := caHide;

      DoClose(CloseAction);
      if CloseAction <> caNone then
      begin
         if Application.MainForm = Self then //Borland doesn't hate developers; it just hates me
            Application.Terminate
         else if CloseAction = caHide then   
            Hide
         else if CloseAction = caMinimize then 
            WindowState := wsMinimized
         else 
            Release;
      end;
   end;
end;
Run Code Online (Sandbox Code Playgroud)

奖金阅读

Rem*_*eau 9

当用户关闭窗口时,它会收到一条WM_CLOSE消息,触发TFormClose()方法调用其自身的方法.调用Close()项目MainForm 总是终止应用程序,因为这是硬编码行为TCustomForm.Close():

procedure TCustomForm.Close;
var
  CloseAction: TCloseAction;
begin
  if fsModal in FFormState then
    ModalResult := mrCancel
  else
    if CloseQuery then
    begin
      if FormStyle = fsMDIChild then
        if biMinimize in BorderIcons then
          CloseAction := caMinimize else
          CloseAction := caNone
      else
        CloseAction := caHide;
      DoClose(CloseAction);
      if CloseAction <> caNone then
        if Application.MainForm = Self then Application.Terminate // <-- HERE
        else if CloseAction = caHide then Hide
        else if CloseAction = caMinimize then WindowState := wsMinimized
        else Release;
    end;
end;
Run Code Online (Sandbox Code Playgroud)

只有辅助TForm对象才会遵循OnClose处理程序的输出.

要做你想要的,你可以:

  • WM_CLOSE直接处理并跳过Close().

    private
      procedure WMClose(var Message: TMessage); message WM_CLOSE;
    
    procedure TForm1.WMClose(var Message: TMessage);
    begin
      Hide;
      // DO NOT call inherited ...
    end;
    
    Run Code Online (Sandbox Code Playgroud)
  • 让您的MainForm的OnClose处理程序Hide()直接调用并返回caNone:

    procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
      Hide;
      Action := caNone;
    end;
    
    Run Code Online (Sandbox Code Playgroud)


小智 6

试试这个OnCloseQuery活动.隐藏表单并设置CanClose为False.你应该好.

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  Hide;
  CanClose := False;
end;
Run Code Online (Sandbox Code Playgroud)