【问题标题】:How to hide main form rather than closing it?如何隐藏主窗体而不是关闭它?
【发布时间】:2018-08-24 12:37:17
【问题描述】:

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

在表单关闭时使用 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;

所以现在当我点击 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;

阅读奖励

【问题讨论】:

  • 主要形式不同。任何辅助形式都将遵守。

标签: delphi delphi-xe6


【解决方案1】:

当用户关闭一个窗口时,它会收到一条WM_CLOSE 消息,该消息会触发TForm 对其自身调用其Close() 方法。在项目的MainForm 上调用Close() 总是 会终止应用程序,因为这是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;

只有辅助 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;
    
  • 让您的 MainForm 的 OnClose 处理程序直接调用 Hide() 并返回 caNone

    procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
      Hide;
      Action := caNone;
    end;
    

【讨论】:

    【解决方案2】:

    试试OnCloseQuery 事件。隐藏表单并将CanClose 设置为False。你应该很好。

    procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    begin
      Hide;
      CanClose := False;
    end;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-21
      • 2021-12-19
      • 2012-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多