当主窗体最小化/阻止自动恢复时隐藏fsStayOnTop窗体

Eva*_*man 3 windows delphi delphi-2007

我有一个主要表格和状态表格,类似于这里提出问题.但是,我的状态窗口的FormStyle是fsStayOnTop,当我尝试在状态窗口显示时最小化主窗体时会导致一些奇怪的行为.

当我最小化主窗体时,两个窗体都按预期隐藏,但是当状态窗体完成其最小化时完成其任务时,主窗体自动恢复自身并且其最小化按钮不再起作用(但最大化/恢复/关闭所有还在工作).使最小化功能再次起作用的唯一方法是重新启动应用程序.如果我将FormStyle设置为其他任何东西,一切正常,但我的应用程序要求状态窗体在可见时保持在顶部.

有没有理由为什么主窗体会自动恢复?有没有办法来解决这个问题?

procedure ButtonClick(sender:TObject);
begin
  //Gather some data

  ShowStatusWindow; // sets status window to visible, does its work, 
                    // then sets invisible. (Usually visible for about 10 seconds)

  //Gather more data

  Windows.SendMessage(self.Handle, WM_SETREDRAW, 0, 0); //Freeze the main form for 
                                                        //flickerless drawing
  // Handle everything that would cause a redraw
  Windows.SendMessage(self.Handle, WM_SETREDRAW, 1, 0);  // thaw form
  RedrawWindow(self.Handle, 0, 0, RDW_ERASE or RDW_FRAME or RDW_INVALIDATE or RDW_ALLCHILDREN);
end;
Run Code Online (Sandbox Code Playgroud)

Ser*_*yuz 5

我能提出的唯一解释是你的应用程序MainFormOnTaskbar被设置为false.

如果是这种情况,当您的应用程序最小化时,主窗体实际上不会被最小化,而是根据VCL的最小化机制隐藏.当您发送WM_SETREDRAW"wParam"设置为True 的消息时,您将强制显示隐藏(未最小化)主窗体的窗口.

在此阶段,应用程序仍然根据VCL最小化,因为它从未被恢复.当您单击主窗体的最小化按钮时,VCL调用TApplication.Minimize并看到应用程序窗口已经最小化,因此返回时无需进一步操作,因此主窗体不会最小化.

这是一个简单的示例,可以复制问题.MainFormOnTaskbar在项目源中设置为false.运行该应用程序,然后单击按钮:

procedure TForm1.Button2Click(Sender: TObject);
begin
  Application.Minimize;
  SendMessage(Handle, WM_SETREDRAW, 1, 0);
  // ShowWindow(Handle, SW_SHOWNORMAL); // this will also do the same
end;
Run Code Online (Sandbox Code Playgroud)

在此之后,您将无法最小化表单.


要解决此问题,您可以在禁用绘图之前检查主窗体是否可见:

  if IsWindowVisible(Handle) then begin
    Windows.SendMessage(self.Handle, WM_SETREDRAW, 0, 0);
    ...
Run Code Online (Sandbox Code Playgroud)