【发布时间】:2015-04-11 09:15:27
【问题描述】:
此对话框正好显示在按钮下方,但在 Windows 8 中,对话框向左并向上移动。如何在所有 Windows 版本中获得相同的结果?
procedure TForm1.Button3Click(Sender: TObject);
var p: TPoint;
begin
p := Button3.ClientToScreen(Point(0, Button3.Height));
MessageDlgPos('', mtInformation, [mbOK], 0, p.X, p.Y);
end;
更新: 如果我们打开 Form 而不是 Dialog,并且该 Form 具有 BorderStyle bsSizeable 或 bsSizeToolWin,那么一切正常。否则(bsDialog、bsSingle、bsToolWindow),Form 打开时作为上例中的 Dialog 打开。
【问题讨论】:
-
听起来像一个 Delphi 库错误。通过判断 ClientToScreen 是否损坏或 MessageDlgPos 是否损坏来诊断它。通过检查坐标来测试前者。如果 ClientToScreen 有效,则 MessageDlgPos 已损坏。
-
@David,我认为这不是其中任何一个错误。例如,在坐标 (0,0) 的情况下,Dialog 或 Form 以相同的方式移动。似乎问题在于 Windows 8 看到位于窗口框架内几个像素的点作为起点。如果是这样,问题是如何以适当的方式进行必要的更正。
-
哦。好吧,我想你需要在问题中说清楚。一张图片就可以做到这一点。
-
VCL 在 dialogs.pas 中的
TTaskMessageDialog.DoOnDialogCreated中使用正确的坐标调用SetWindowPos。这似乎是一个操作系统问题。使用诸如“GetWindowRect 错误值”之类的内容进行搜索,您将找到诸如 stackoverflow.com/questions/3192232/… 之类的示例。请注意,中间和最右侧图片中的对话框也偏离了“1”像素。我提到 GetWindowRect 是因为据报道按钮和对话框的窗口矩形在 W7 上具有相同的“左侧”。您可以对 W8 进行相同的测试并验证是否是操作系统问题。 -
不仅如此,Aero 还让
GetWindowRect()之类的东西报告“错误”值以说明 DWM 的影响和边界,以免破坏与不考虑 DWM 的代码的向后兼容性。这就是添加DwmGetWindowAttribute(DWMWA_EXTENDED_FRAME_BOUNDS)以获得“实际”窗口矩形的原因。
标签: delphi winapi windows-8 dialog position