【发布时间】:2020-04-29 23:01:04
【问题描述】:
我正在尝试“并排”在主表单之后对齐我的子表单,但遇到了一些困难
要重现问题,请创建新的 VCL 应用程序并在表单中添加一个按钮:
procedure TForm1.Button1Click(Sender: TObject);
var
Form: TForm1;
begin
Application.CreateForm(TForm1, Form);
Form.BorderStyle := bsSingle;
Form.Left := Left + Width;
Form.Top := Top;
Form.Show;
end;
结果:
使用Winapi.DwmApi后:
DXR1 := 0;
DXL2 := 0;
if (Win32MajorVersion >= 6) and DwmCompositionEnabled then begin
DwmGetWindowAttribute(Handle, DWMWA_EXTENDED_FRAME_BOUNDS, @R1, SizeOf(R1));
Winapi.Windows.GetWindowRect(Handle, R2);
DXR1 := R2.Right - R1.Right;
DYT1 := R2.Top - R1.Top;
end;
FormJob.Left := Left + Width - DXR1;
FormJob.Top := Top - DYT1;
FormJob.Show;
if (Win32MajorVersion >= 6) and DwmCompositionEnabled then begin
DwmGetWindowAttribute(FormJob.Handle, DWMWA_EXTENDED_FRAME_BOUNDS, @R1, SizeOf(R1));
Winapi.Windows.GetWindowRect(FormJob.Handle, R2);
DXL2 := R1.Left - R2.Left;
DYT2 := R2.Top - R1.Top;
end;
FormJob.Left := FormJob.Left - DXL2;
FormJob.Top := FormJob.Top + DYT2;
现在这在 Windows 7 和 Windows 10 上完全一致
但要做到这一点,我需要先显示子窗体。如果我在显示之前为子(和不可见)表单调用DwmGetWindowAttribute,我会得到与GetWindowRect相同的值。在显示之前不可能得到这个?
【问题讨论】:
-
这是 DWM 的一个怪癖,在显示窗口之前您无法查询框架边界。您可以做的是在显示之前使用 DWMWA_CLOAK 隐藏窗口。
-
我认为这个问题缺少关于为什么表格首先不对齐的上下文。复制案例会很好。
-
@SertacAkyuz,但是第一部分代码已经重现了问题,还是我需要扩展这部分?
-
我向一个新的 VCL 应用程序添加了第二个表单。调用您从主窗体中显示的代码,将 FormJob 替换为 Form2,并且无法重现该问题。表格对齐好了。在 Windows 7 上测试。
-
您是否禁用了主题?另外,尝试设置您的 Form2.BorderStyle := bsSingle;不同风格的窗户有不同的阴影宽度和高度值。