加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

delphi – wsMaximized形式不会出现最大化

发布时间:2020-12-15 05:22:41 所属栏目:大数据 来源:网络整理
导读:将窗体设置为WindowState = wsMaximized有时会导致窗体最大化,但不会: 长期的bug:这是我在2003年Borland新闻组第一次提出的问题: Accepted fix for WindowState = wsMaximized? 然后在2006年再次: wsMaximized breaks it,NOT caused by Position=poScre
将窗体设置为WindowState = wsMaximized有时会导致窗体最大化,但不会:

长期的bug:这是我在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。也许有人最终想出了一个解决方法。

重现步骤:

我的帖子包含六个故障模式,但最简单的是:

>在表单上拖放标签和编辑:

>为TEdit添加OnEnter事件:

procedure TForm1.Edit1Enter(Sender: TObject);
begin
   Label1.Font.Style := Label1.Font.Style + [fsBold];
end;

>并设置形式:

> WindowState to wsMaximized
> AutoScroll为False

和bazinga,失败。

从2008年的帖子开始的另一组步骤之一:

  1. Create a new app and a form.
  2. Set the form to maximized (WindowState = wsMaximized) at design time.
  3. Drop a ListView control on the form
  4. During OnShow,add 20 empty items to the list view:

    06001

  5. Set the form’s AutoScroll property to false (AutoScroll = False) at design time

当然,我不是在“固定在RadStudio的版本n,只是使用”。我正在寻找一个实际的修复(如果有一个);这可能包括引用对VCL源的相关更改,当CodeGear终于修复它。 (如果它甚至固定)。

注意:将位置从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);
  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);
  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,D2007,XE2),并能够复制D7和D2007但不是与XE2的问题。

问题,我看到,是标签,其字体更改,请求其父重新对齐自身。这最终导致在窗体(在TWinControl.AdjustSize)中具有恢复的宽度/高度的SetWindowPos调用,即使窗体已经最大化 – 这导致奇怪的,行为上最大化但是没有在视觉上最大化,形成坐在屏幕上。

我追踪了D2007和XE2中的代码,以便能够想出什么是不同的。 TWinControl.AlignControls中的代码在两个版本之间不同。最重要的是最后一句话。

D2007:

procedure TWinControl.AlignControls(AControl: TControl; var Rect: TRect);

  ..
  { Apply any constraints }
  if Showing then AdjustSize;
end;

XE2:

procedure TWinControl.AlignControls(AControl: TControl; var Rect: TRect);

  ..
    // Apply any constraints
    if FAutoSize and Showing then
      DoAdjustSize;
end;

我希望这可以,不知何故,帮助你设计/决定使用什么解决方法。

解决方法我可以建议(虽然我没有测试它throughly)是强制显示形式最大化早:

procedure TForm1.FormCreate(Sender: TObject);
var
  wplc: TWindowPlacement;
begin
  if not AutoScroll and (WindowState = wsMaximized) then begin
    wplc.length := SizeOf(wplc);
    GetWindowPlacement(Handle,@wplc);
    wplc.rcNormalPosition.Right := wplc.rcNormalPosition.Left + Width;
    wplc.rcNormalPosition.Bottom := wplc.rcNormalPosition.Top + Height;
    wplc.showCmd := SW_MAXIMIZE;
    SetWindowPlacement(Handle,@wplc);
  end;
end;

上面的工作原理是因为它在VCL为表单设置可见标志之前强制将焦点设置为编辑控件(OnEnter事件)。反过来,标签的对齐请求不会导致表单大小调整。另外,由于在VCL调用ShowWindow时窗体的窗口已经可见,它不会导致窗体在任何阶段以恢复的状态显示。

但是,我不知道它是否会帮助不同的复制场景。

最后,虽然我可以看到,在新的Delphi版本中的行为被纠正,我不会认为这是一个错误在VCL。在我看来,用户代码应该负责不导致窗口调整,而窗口显示状态正在改变。我将采取的具体情况的行动的过程将推迟修改标签的字体,直到VCL完成显示窗体。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读