在 Delphi 中获取自定义 DPI 百分比
尝试在 Windows 7 的高 DPI 模式下让我的 Delphi 2010 应用程序对用户更友好,我一直在尝试几种方法来检索 PixelsPerInch 并与 96 进行比较。唉,无论我尝试什么,我总是得到 96。我的问题是:
- 什么是最好的练习获得自定义 DPI 模式?
- 无论我的认知度是多少,我始终得到 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:
- What is the best practice to get custom DPI mode?
- 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
我认为您需要通过将其包含在应用程序清单中来将您的应用程序标记为高 DPI 感知:
给出了有关声明 DPI 感知的详细信息 此处。
您目前似乎正在退回到所谓的 DPI 虚拟化。
I think you need to mark your application as being high DPI aware by including this in your application manifest:
Details on declaring DPI awareness are given here.
It seems like you are currently falling back to what is called DPI Virtualization.
您可以查看注册表值 AppliedDPI 。
感谢 Andreas Rejbrand,
You could have a look at the Registry value AppliedDPI at
Thanks to Andreas Rejbrand.
您的应用程序是否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.
因为 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.
不响应用户的 DPI 设置。
响应用户的字体偏好。
如果您只响应用户的 DPI 设置,那么如果用户使用比您在设计时使用的字体更大的字体,您的表单将不会变大,例如,
通过响应字体大小(以像素为单位),您可以免费获得高 DPI 支持(并且您正在成为优秀的开发人员!):
13px
Windows 2000/XP(您设计的内容)15px
(比例您设计的表单 115%)15px
Windows Vista/7 (将您设计的表单缩放115%)16px
我的家用机器(将表单缩放 123%)16px
>我的工作机器(将您设计的表单缩放123%)您想要关闭所有表单的
Scaled
属性;所以他们不会尝试响应 dpi 设置。您需要相当于AutoScaleMode 的 .NET WinForms。字体
。是的,一旦您缴纳了税款,并且可以处理不同的 DPI 设置,请使用清单声明您的应用程序支持 highDpi - 正如其他答案所给出的那样。
不要使用
SetProcessDPIAware
,因为对于您所依赖的已读取当前 DPI 的 DLL: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.
By responding to font size (in pixels), you get high-DPI support for free (and you're being a good developer!):
13px
Windows 2000/XP (what you designed with)15px
(scale your designed form by 115%)15px
Windows Vista/7 (scale your designed form by 115%)16px
my home machine (scale your form by 123%)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 ofAutoScaleMode.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:如果它对某人有帮助,
我注意到 Screen->PrimaryMonitor->PixelsPerInch 确实根据显示缩放而变化。
In case it helps someone,
I have noticed that Screen->PrimaryMonitor->PixelsPerInch DOES change according to the display scaling.
我着手修复这个 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!