【问题标题】:SystemParametersInfoForDPI corrupts memorySystemParametersInfoForDPI 损坏内存
【发布时间】:2018-07-23 15:09:30
【问题描述】:

我正在尝试将新的 SystemParametersInfoForDPI 函数用于高 DPI 应用程序。但是,当我返回调用者时,我的应用程序立即崩溃(致命错误)。

尝试执行 00000000 时出现访问冲突。

我要获取的参数是 SPI_GETNONCLIENTMETRICS。

procedure TForm1.Button1Click(Sender: TObject);
var
  SystemParametersInfoForDpi: function(uiAction, uiParam: UINT; pvParam: Pointer; fWinIni, DPI: UINT): BOOL; stdcall;
  Metrics: TNonClientMetrics;
begin
  SystemParametersInfoForDpi := GetProcAddress(GetModuleHandle(user32), 'SystemParametersInfoForDpi');
  Win32Check(Assigned(SystemParametersInfoForDpi));

  FillChar(Metrics, SizeOf(Metrics), 0);
  Metrics.cbSize := SizeOf(Metrics);
  if SystemParametersInfoForDPI(SPI_GETNONCLIENTMETRICS, Metrics.cbSize, @Metrics, 0, 120) then
    Caption := 'OK'
  else
    Caption := 'FAIL'; 
end; // - crashes here; D2007; Win2016

怎么了?

【问题讨论】:

  • 任何这样的问题都需要minimal reproducible example 这样我们才能看到你做错了什么
  • @DavidHeffernan 你没有抓住重点。这个问题只是说明 SystemParametersInfoForDPI 执行缓冲区溢出而不是设置 GetLastError 失败。
  • 我们只有你的话。也许您的代码有问题。通过添加minimal reproducible example,我们可以轻松地验证这一点。这将使您的帖子大大改善。
  • “回答你自己的问题...”当然可以,但关键是问题,正如你自己所说,你还没有问过问题。
  • 这里的规则有点不同。符合规则,一切都很好。

标签: windows delphi debugging highdpi


【解决方案1】:

崩溃部分问题 - 这似乎是某些 Windows 版本中的错误。

有问题的代码不正确。

SystemParametersInfoForDPI 只有在使用最新版本的结构时才能正常工作:它应该是 UNICODE 并为最新的操作系统版本定义(例如,iPaddedBorderWidth 等字段 - 必须存在)。换句话说,它应该在所有可能的定义中具有最大的大小。

这在文档中有所概述,但方式有点奇怪:

  • SystemParametersInfoForDpi 的文档说:“此函数仅支持 Unicode (LOGFONTW) 字符串”
  • SystemParametersInfo 的文档说:“pvParam 参数必须指向包含新参数的 NONCLIENTMETRICS 结构”

虽然这看起来像是从旧 Windows 版本(2000 等)上的文档中清理出来的 - 但它确实告诉您绝对必须使用最新版本的结构。

最后,错误是 SystemParametersInfoForDpi 在看到不受支持的缓冲区大小时不会因“缓冲区不足”或“无效参数”错误而失败 - 正如人们所期望的那样。相反,它会愉快而安静地执行缓冲区溢出。这只发生在某些 Windows 版本上。

因此,如果在堆栈上分配结构 - 缓冲区溢出将擦除返回地址。当你的代码试图返回给调用者时——它会崩溃。

【讨论】:

  • 我猜你假设问题是问为什么会发生这种情况?
  • @SertacAkyuz 我不是在这里问任何问题。我正在分享有关 SystemParametersInfoForDpi 函数中奇怪错误处理的知识。
  • @Alex SO 有一个问答格式。你是用来问问题的。如果您想分享信息,请获取博客。如果您想在此处发帖,请将其表述为问题。
猜你喜欢
  • 1970-01-01
  • 2015-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-04
  • 2012-06-13
  • 1970-01-01
相关资源
最近更新 更多