delphi - 获取表单的大小和边框
问题描述
我试图在主表单“并排”之后对齐我的子表单,但有一些困难
要重现该问题,请创建新的 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
在显示之前调用子(和不可见)表单,我会得到与 for 相同的值。GetWindowRect
在显示之前不可能得到这个?
解决方案
感谢Jonathan Potter的评论,现在我有了这样的代码并且它可以工作:
var
R1, R2: TRect;
DXR1, DXL2, DYT1, DYT2: Integer;
bCloak: BOOL; // Can't use Boolean here
begin
Application.CreateForm(TFormJob, FormJob);
if (Win32MajorVersion >= 6) and DwmCompositionEnabled then begin
DXR1 := 0;
DXL2 := 0;
DYT1 := 0;
DYT2 := 0;
if (DwmGetWindowAttribute(Handle, DWMWA_EXTENDED_FRAME_BOUNDS, @R1, SizeOf(R1)) = S_OK) and
Winapi.Windows.GetWindowRect(Handle, R2) then begin
DXR1 := R2.Right - R1.Right; // Right width of the shadow for parent
DYT1 := R2.Top - R1.Top; // Top height of the shadow for parent
end;
bCloak := True; // Make form invisible
DwmSetWindowAttribute(FormJob.Handle, DWMWA_CLOAK, @bCloak, SizeOf(bCloak));
FormJob.Show; // Draw invisible form
if (DwmGetWindowAttribute(FormJob.Handle, DWMWA_EXTENDED_FRAME_BOUNDS, @R1, SizeOf(R1)) = S_OK) and
Winapi.Windows.GetWindowRect(FormJob.Handle, R2) then begin
DXL2 := R1.Left - R2.Left; // Left width of the shadow for child
DYT2 := R2.Top - R1.Top; // Top height of the shadow for child
end;
FormJob.Left := Left + Width - DXR1 - DXL2;
FormJob.Top := Top - DYT1 + DYT2;
bCloak := False; // Make form visible
DwmSetWindowAttribute(FormJob.Handle, DWMWA_CLOAK, @bCloak, SizeOf(bCloak));
end
else begin
FormJob.Left := Left + Width;
if FormJob.Left + FormJob.Width > Screen.DesktopRect.Right then
FormJob.Left := Screen.DesktopRect.Right - FormJob.Width;
FormJob.Top := Top;
FormJob.Show;
end;
实际上,这段代码的可读性较差,并且包含与原始代码相同的代码,但这可以在将来需要绘制自定义绘图表单时有所帮助。
推荐阅读
- javascript - 按钮在点击时不起作用。我关注了一个 YouTube 视频,但它对我不起作用
- apache - .htaccess 文件的 RewriteRule 不起作用
- java - javassist 从 jar 加载外部类时抛出 ClassNotFoundException
- maven - 尝试使用 JPA 将我的实体类连接到 mySQL 时,javax.persistance 出现异常。我如何解决它?
- ios - Swift - 使用 UITextField 作为 UITableView 的搜索
- sql - 尝试在具有到期日期的 TSQL 中进行分析
- python - 制作 python UI - Tkinter 是最佳选择吗?
- postgresql - 在 Windows (PostGIS) 上启动 shp2pgsql-gui 时找不到 libsqlite3-0.dll 错误
- git - Fedora 33 git pull 或 clone 不再工作和/或 ssh 密钥不再识别
- android - 使用 5 公里附近的查询(经度和纬度)查询 Firebase 实时数据库