首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >对话框在Windows 8中向左移动并向上移动

对话框在Windows 8中向左移动并向上移动
EN

Stack Overflow用户
提问于 2015-04-11 09:15:27
回答 2查看 407关注 0票数 1

这个对话框正好显示在按钮下面,但是在Windows 8中,对话框被移动到左边和上面。如何在所有Windows版本中获得相同的结果?

代码语言:javascript
复制
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;

更新:如果我们打开表单而不是对话框,如果该表单具有BorderStyle bsSizeable或bsSizeToolWin,那么一切都正常。否则(bsDialog、bsSingle、bsToolWindow),窗体将以对话框形式从上面的示例中移开。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-04-12 02:12:42

运行您在Windows 7上显示的确切代码,我无法再现您在Windows 7剪贴画中显示的相同的对话框位置。MessageDlgPos窗口以与Windows 8截图相同的方式向左偏移:

尽管如此,我注意到您正在将您的MessageDlg窗口相对于按钮的工作区定位

如果希望对话框相对于其实际底部边缘定位,则需要在按钮的Parent上调用Parent,而不是在按钮本身上调用:

代码语言:javascript
复制
p := Button3.Parent.ClientToScreen(Point(Button3.Left, Button3.Top+Button3.Height));

不过,最终的结果几乎是一样的:

现在,为什么重叠首先会发生呢?由于窗口的位置使得其非客户区域的左上角落在指定的坐标处:

您可以调整窗口坐标以解决以下问题:

代码语言:javascript
复制
p := Button3.Parent.ClientToScreen(Point(Button3.Left, Button3.Top + Button3.Height));
Inc(p.X, GetSystemMetrics(SM_CXFIXEDFRAME) + GetSystemMetrics(SM_CXBORDER));
Inc(p.Y, GetSystemMetrics(SM_CYFIXEDFRAME) + GetSystemMetrics(SM_CYBORDER));

这让你更接近你想要的位置:

请注意,Aero“调整”了一些系统度量,因此您可能需要使用诸如DwmGetWindowAttribute(DWMWA_EXTENDED_FRAME_BOUNDS)和/或GetThemeSysSize()之类的方法来获得更精确的度量。

票数 3
EN

Stack Overflow用户

发布于 2015-04-12 17:31:25

在你的回答和评论以及一些额外的研究之后,我找到了这个解决方案。在Windows 8上进行测试,使用Aero测试7次,使用Aero和XP测试7次。我希望有更简单更稳定的东西但是..。

代码语言:javascript
复制
uses DwmApi;

type
  TNonClientMetricsX = packed record
    cbSize: UINT;
    iBorderWidth: Integer;       iScrollWidth: Integer;
    iScrollHeight: Integer;      iCaptionWidth: Integer;
    iCaptionHeight: Integer;     lfCaptionFont: TLogFontA;
    iSmCaptionWidth: Integer;    iSmCaptionHeight: Integer;
    lfSmCaptionFont: TLogFontA;  iMenuWidth: Integer;
    iMenuHeight: Integer;        lfMenuFont: TLogFontA;
    lfStatusFont: TLogFontA;     lfMessageFont: TLogFontA;
    iPaddedBorderWidth: Integer; // not defined in Delphi 2007
  end;

function GetExtendedFrameOffset(BorderStyle: TFormBorderStyle): integer;
var
  IsEnabled: BOOL;
  NCM: TNonClientMetricsX;
begin
  Result := 0;
  if (DwmIsCompositionEnabled(IsEnabled) = S_OK) and IsEnabled and
     (BorderStyle in [bsdialog, bsSingle, bsToolWindow]) then
  begin
    NCM.cbSize := SizeOf(NCM);
    SystemParametersInfo(SPI_GETNONCLIENTMETRICS, SizeOf(NCM), @NCM, 0);
    Result := NCM.iBorderWidth + NCM.iPaddedBorderWidth;
  end;
end;

procedure TForm1.Button3Click(Sender: TObject);
var p: TPoint; offset: integer;
begin
  p := Button3.ClientToScreen(Point(0, Button3.Height));
  offset := GetExtendedFrameOffset(bsDialog);
  MessageDlgPos('', mtInformation, [mbOK], 0, p.X + offset, p.Y + offset);
end;

更新: D2007包括DwmApi,所以不需要复杂的LoadLibrary

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29576140

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档