在 Delphi 中获取自定义 DPI 百分比

发布于 2024-11-28 18:03:41 字数 729 浏览 2 评论 0原文

尝试在 Windows 7 的高 DPI 模式下让我的 Delphi 2010 应用程序对用户更友好,我一直在尝试几种方法来检索 PixelsPerInch 并与 96 进行比较。唉,无论我尝试什么,我总是得到 96。我的问题是:

  1. 什么是最好的练习获得自定义 DPI 模式?
  2. 无论我的认知度是多少,我始终得到 96 的事实是否意味着我错过了一些东西?

这是我尝试过的

dpiX := Form1.PixelsPerInch

dpiX := Screen.PixelsPerInch

最后:

D2DFactoryOptions.DebugLevel := D2D1_DEBUG_LEVEL_NONE;
pD2DFactoryOptions := @D2DFactoryOptions;
if D2D1CreateFactory(
    D2D1_FACTORY_TYPE_SINGLE_THREADED,
    IID_ID2D1Factory,
    PD2DFactoryOptions,
    D2DFactory
    ) <> S_OK then exit;
D2DFactory.GetDesktopDpi(dpiX, dpiY)

想猜一下吗?是的,dpiX在100%、125%和150%时是常数96,

请指教。

Trying to my Delphi 2010 application more user freindly in high DPI modes in Windows 7 I have been trying several methods to retrive PixelsPerInch and compare to 96. Alas, no matter what I tried I always get 96. My questions are:

  1. What is the best practice to get custom DPI mode?
  2. Is the fact I am getting a constant 96 no matter what I what the percebtage is means I missing somthing?

Here is what I had tried

dpiX := Form1.PixelsPerInch

and

dpiX := Screen.PixelsPerInch

and finally:

D2DFactoryOptions.DebugLevel := D2D1_DEBUG_LEVEL_NONE;
pD2DFactoryOptions := @D2DFactoryOptions;
if D2D1CreateFactory(
    D2D1_FACTORY_TYPE_SINGLE_THREADED,
    IID_ID2D1Factory,
    PD2DFactoryOptions,
    D2DFactory
    ) <> S_OK then exit;
D2DFactory.GetDesktopDpi(dpiX, dpiY)

Care to guess? that's right dpiX is a constant 96 in 100%, 125% and 150%

Please advice.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

眼眸里的那抹悲凉 2024-12-05 18:03:41

我认为您需要通过将其包含在应用程序清单中来将您的应用程序标记为高 DPI 感知:

<asmv3:application xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
  <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
    <dpiAware>true</dpiAware>
  </asmv3:windowsSettings>
</asmv3:application>

给出了有关声明 DPI 感知的详细信息 此处

您目前似乎正在退回到所谓的 DPI 虚拟化

I think you need to mark your application as being high DPI aware by including this in your application manifest:

<asmv3:application xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
  <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
    <dpiAware>true</dpiAware>
  </asmv3:windowsSettings>
</asmv3:application>

Details on declaring DPI awareness are given here.

It seems like you are currently falling back to what is called DPI Virtualization.

生来就爱笑 2024-12-05 18:03:41

您可以查看注册表值 AppliedDPI 。

HKEY_CURRENT_USER\Control Panel\Desktop\WindowMetrics\AppliedDPI

感谢 Andreas Rejbrand,

You could have a look at the Registry value AppliedDPI at

HKEY_CURRENT_USER\Control Panel\Desktop\WindowMetrics\AppliedDPI

Thanks to Andreas Rejbrand.

素染倾城色 2024-12-05 18:03:41

您的应用程序是否DPI 感知 ?如果不是,请如此声明。

编辑:

如果您确实只想检测当前设置,但不想为整个应用程序启用 DPI 感知,那么最好的方法可能是编写一个小的(dpi 感知)应用程序,其唯一的工作就是进行此检测。运行它并将结果传输到您的主应用程序。或者提供一个启动器来检测然后运行主应用程序,将设置作为命令行参数提供。当然,只有当您的应用程序没有其他 API 或“秘密”调用来确定设置时,即使在运行 DPI 虚拟化时也是如此。

Is your application DPI aware? If not, declare it so.

Edit:

If you really just want to detect the current setting, but don't want to enable DPI awareness for your whole application then maybe the best approach is to write a small (dpi aware) app whose sole job is to do this detection. Run it and transfer the result over to your main app. Or provide a launcher which detects and then runs the main app providing the setting as command line param. This of course only if there is no other API or "secret" call your application can make to determine the setting even when running DPI virtualized.

无戏配角 2024-12-05 18:03:41

因为 Delphi 的 IDE 甚至没有提供一种方法来将您的应用程序标记为 DPI 感知,正如 David 向您展示的那样,您需要制作自己的清单并向其中添加内容,并且因为进入 DPI 感知模式意味着您将不得不处理很多事情如果你自己工作,你可能会发现这根本不值得。经过大约 100 个小时毫无结果的工作后,我当然放弃了这个尝试。

如果您的应用程序使用 100% 通用控件,并且您不介意重新设计所有其他控件,直到它们适合您为止,那么就去做吧。

一旦关闭 DPI 虚拟化,即使是基于通用控件的控件(例如 Page 控件)似乎也无法在高 dpi 环境中正常工作(至少它们的 VCL 包装器不起作用)。

简短版本:现在的最佳实践是,除非绝对必要,否则根本不要在 VCL 应用程序中打扰,然后,您不妨留出时间来重写和修复 VCL 中的每个控件以及每个第三方控件,以解决问题的小故障。

Because Delphi's IDE doesn't even provide a way to mark your application DPI-aware as David has shown you you need to make your own manifest and add stuff to it, and because going into DPI Aware mode means you will have to handle a lot of work yourself, you might find that it's just not worth it. I certainly abandoned the attempt after about 100 fruitless hours of work.

If your app used 100% Common Controls, and you didn't mind reworking all the others until they worked fine for you, then go for it.

Even Common-controls based controls like the Page control don't seem to work (at least their VCL wrappers don't work) well in a high-dpi environment once DPI virtualization is turned off.

Short version: Best practice these days is don't bother at all in VCL apps unless you absolutely must, and then, you may as well set aside time for rewriting and fixing every control in the VCL and every third party control, to work around the glitches.

天涯沦落人 2024-12-05 18:03:41

不响应用户的 DPI 设置。

响应用户的字体偏好。

如果您只响应用户的 DPI 设置,那么如果用户使用比您在设计时使用的字体更大的字体,您的表单将不会变大,例如,

  • 您使用 8pt MS Sans Serif 或 Tahoma 进行设计,
  • 而用户运行的是 Windows Vista 或 Windows 7 (9pt Segoe UI)
  • 您正在我的计算机上运行 (14pt Segoe UI)

通过响应字体大小(以像素为单位),您可以免费获得高 DPI 支持(并且您正在成为优秀的开发人员!):

  • 8pt Tahoma @96dpi:13px Windows 2000/XP(您设计的内容)
  • 8pt Tahoma @131dpi:15px(比例您设计的表单 115%)
  • 9pt Segue UI @96dpi: 15px Windows Vista/7 (将您设计的表单缩放115%)
  • 9pt Segoe UI@131dp: 16px 我的家用机器(将表单缩放 123%)
  • 12pt Tahoma @96dpi: 16px >我的工作机器(将您设计的表单缩放123%)

您想要关闭所有表单的Scaled属性;所以他们不会尝试响应 dpi 设置。您需要相当于 AutoScaleMode 的 .NET WinForms。字体


是的,一旦您缴纳了税款,并且可以处理不同的 DPI 设置,请使用清单声明您的应用程序支持 highDpi - 正如其他答案所给出的那样。

不要使用SetProcessDPIAware,因为对于您所依赖的已读取当前 DPI 的 DLL

注意如果 DLL 在初始化期间缓存 dpi 设置,则 SetProcessDPIAware 可能会出现竞争条件。因此,建议通过应用程序 (.exe) 清单设置 dpi-aware,而不是通过调用 SetProcessDPIAware。

Don't respond to the user's DPI setting.

Respond the user's font preference.

If you only respond to the user's DPI setting, then your form will not get bigger if the user uses a larger font than you used at design time, e.g.

  • you designed with 8pt MS Sans Serif or Tahoma
  • the user is running Windows Vista or Windows 7 (9pt Segoe UI)
  • you're running on my computer (14pt Segoe UI)

By responding to font size (in pixels), you get high-DPI support for free (and you're being a good developer!):

  • 8pt Tahoma @96dpi: 13px Windows 2000/XP (what you designed with)
  • 8pt Tahoma @131dpi: 15px (scale your designed form by 115%)
  • 9pt Segue UI @96dpi: 15px Windows Vista/7 (scale your designed form by 115%)
  • 9pt Segoe UI@131dp: 16px my home machine (scale your form by 123%)
  • 12pt Tahoma @96dpi: 16px my work machine (scale your designed form by 123%)

You want to turn all your form's Scaled property off; so they don't try to respond to dpi settings. You want the .NET WinForms equivalent of AutoScaleMode.Font.


And yes, once you've paid your taxes, and can handle different DPI settings, declare your application highDpi aware using a manifest - as other answers have given.

Don't use SetProcessDPIAware, as it may be too late for DLLs that you depend on who already read the current DPI:

Note SetProcessDPIAware is subject to a possible race condition if a DLL caches dpi settings during initialization. For this reason, it is recommended that dpi-aware be set through the application (.exe) manifest rather than by calling SetProcessDPIAware.

春风十里 2024-12-05 18:03:41

如果它对某人有帮助,
我注意到 Screen->PrimaryMonitor->PixelsPerInch 确实根据显示缩放而变化。

In case it helps someone,
I have noticed that Screen->PrimaryMonitor->PixelsPerInch DOES change according to the display scaling.

留一抹残留的笑 2024-12-05 18:03:41

我着手修复这个 delphi 程序,该程序在 Windows 10 中存在 DPI 问题,在 Windows 7 中则正常 虚拟放大镜 ,在登陆此处并进行故障排除后,我通过右键单击 exe 的属性并摆弄兼容性设置来节省大量时间,底部有一个“更改高 DPI 设置”按钮对话框打开“覆盖高 DPI 缩放”,应用程序现在工作正常。

因此,如果只是个人使用或随身携带,这就不那么令人头疼了!

i set out to fix this delphi program which had DPI troubles in Windows 10, fine in Windows 7 Virtual Magnifying Glass, after landing here and troubleshooting, i ended up saving alot of time by just right clicking properties of the exe and fiddling with Compatibility settings, there's a "Change high DPI settings" button, at the bottom of that dialog turned on "Override high DPI scaling" and app is now working fine.

So if it's just personal use or w/e this will be much less of a headache!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文