将表单设置为WindowState = wsMaximized有时会导致表单最大化,但不会:

长期错误:这是我在2003年在Borland新闻组中首先提出的一个问题:

  • Accepted fix for WindowState = wsMaximized?

  • 然后在2006年再次:
  • wsMaximized breaks it, NOT caused by Position=poScreenCenter, reproducible dfm

  • 然后在2008年再次:
  • Forms not starting maximized

  • 有人在2012年的Embarcadero论坛上问:
  • Thread: Application not starting with maximized window

  • 现在是时候将18年的bug移植到Stackoverflow了。也许有人终于找到了解决方法。

    重现的步骤:

    我的帖子包含了六种失败模式,但最简单的是:
  • 在表单上添加LabelEdit:

  • OnEnter添加一个TEdit事件:
    procedure TForm1.Edit1Enter(Sender: TObject);
    begin
       Label1.Font.Style := Label1.Font.Style + [fsBold];
    end;
    
  • 并设置以下形式:
  • WindowState转换为 ws最大化
  • AutoScroll转换为

  • 而且bazinga,失败了。

    2008年职位发布的另一组步骤之一:



    当然,我不需要的是“已在RadStudio的n版本中修复。只需使用它即可。”我正在寻找一种实际的解决方法(如果有的话);其中可能包括在CodeGear最终修复VCL源时引用对VCL源的相关更改。 (如果它是固定的)。

    注意:Position poDesigned 更改为其他任何方法都无法解决。

    解决方法

    我一直在使用的一种可怕,丑陋,糟糕,令人作呕的解决方法是在OnShow期间启动一个计时器,然后在计时器启动时,最大化该形式:
    procedure TForm1.tmrVclMaximizeHackTimer(Sender: TObject);
    begin
       Self.WindowState := wsMaximized;
    end;
    

    我后来改进了此技巧,以便在OnShow期间发布消息;基本上与计时器消息相同,而不必使用计时器:
    const
      WM_MaximizeWindow = WM_APP + $03;
    
    procedure TForm1.FormShow(Sender: TObject);
    begin
      if (Self.WindowState = wsMaximized) then
      begin
         Self.WindowState := wsNormal;
         PostMessage(Self.Handle, WM_MaximizeWindow , 0, 0);
      end;
    end;
    
    private
       procedure WMMaximizeWindow(var Message: TMessage); message WM_MaximizeWindow;
    
    procedure TForm1.WMMaximizeWindow(var Message: TMessage);
    begin
       Self.WindowState := wsMaximized;
    end;
    

    有时我发明了Delphi从未做过的OnAfterShow事件:
    const
      WM_AfterShow = WM_APP + $02;
    
    procedure TForm1.FormShow(Sender: TObject);
    begin
      PostMessage(Self.Handle, WM_AfterShow, 0, 0);
      if (Self.WindowState = wsMaximized) then
      begin
         Self.WindowState := wsNormal;
         FMaximizeNeeded := True;
      end;
    end;
    
    private
       procedure WMAfterShow(var Message: TMessage); message WM_AfterShow;
    
    procedure TForm1.WMAfterShow(var Message: TMessage);
    begin
       if FMaximizeNeeded then
       begin
          FMaximizeNeeded := False;
          Self.WindowState := wsMaximized;
       end;
    end;
    

    但是,没有什么黑客比黑客更好。

    最佳答案

    我可以用D7 / Win7复制。

    我根本不使用wsMaximized(您所描述的类似随机问题)。

    解决方法:使用OnActivate-> ShowWindow(Handle, SW_MAXIMIZE) 例如:

    procedure TForm1.FormActivate(Sender: TObject);
    begin
      // Maximize only once when the Form is first activated
      if not FMaxsimized then
      begin
        FMaxsimized := True;
        ShowWindow(Handle, SW_MAXIMIZE);
      end;
    end;
    

    此方法在OnShow期间不起作用。

    更好的解决方法:ShowWindowAsyncOnShow期间使用 OnCreate ,例如:
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      ShowWindowAsync(Handle, SW_MAXIMIZE);
    end;
    

    这将设置窗口的显示状态,而无需等待操作完成。

    07-28 03:28