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

在Delphi中获取自定义DPI百分比,delphi,windows-7,screen-resolution,Delphi,Windows 7,Screen Resolution,为了让我的Delphi 2010应用程序在Windows7的高DPI模式下更方便用户,我尝试了几种方法来检索PixelsPerInch并与96进行比较。唉,不管我怎么努力,我总是得到96分。我的问题是: 获得定制DPI模式的最佳实践是什么 事实上,我得到了一个常数96,无论我的percebatge是什么,这意味着我错过了一些东西吗 这是我试过的 dpiX := Form1.PixelsPerInch 及 最后: D2DFactoryOptions.DebugLevel := D2D1_DEBU

为了让我的Delphi 2010应用程序在Windows7的高DPI模式下更方便用户,我尝试了几种方法来检索PixelsPerInch并与96进行比较。唉,不管我怎么努力,我总是得到96分。我的问题是:

  • 获得定制DPI模式的最佳实践是什么
  • 事实上,我得到了一个常数96,无论我的percebatge是什么,这意味着我错过了一些东西吗
  • 这是我试过的

    dpiX := Form1.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)
    
    D2DFactoryOptions.DebugLevel:=D2D1\u DEBUG\u LEVEL\u NONE;
    pD2DFactoryOptions:=@D2DFactoryOptions;
    如果D2D1CreateFactory(
    D2D1工厂型单螺纹,
    IID_ID2D1工厂,
    PD2DFactoryOptions,
    D2D工厂
    )S_OK然后退出;
    D2DFactory.GetDesktopDpi(dpiX,dpiY)
    
    想猜猜看吗?是的,dpiX是一个常数,分别为96,100%,125%和150%


    请给出建议。

    我认为您需要在应用程序清单中包含以下内容,从而将您的应用程序标记为具有高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感知)应用程序,其唯一任务就是执行此检测。运行它并将结果传送到主应用程序。或者提供一个启动器,该启动器检测并运行主应用程序,以命令行参数的形式提供设置。当然,只有在没有其他API或“机密”调用的情况下,应用程序才能确定设置,即使在运行DPI虚拟化时也是如此。

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

    如果你的应用程序使用了100%的通用控件,并且你不介意对所有其他控件进行修改,直到它们对你起作用为止,那么就去做吧

    即使是常见的基于控件的控件,如页面控件,在dpi虚拟化关闭后,在高dpi环境中似乎也无法正常工作(至少它们的VCL包装器无法正常工作)


    简短版本:现在的最佳实践是,除非你绝对必须,否则在VCL应用程序中一点也不麻烦,然后,你可以留出时间重写和修复VCL中的每个控件和每个第三方控件,以解决问题。

    不要响应用户的DPI设置

    响应用户的字体首选项

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

    • 您使用8pt MS Sans Serif或Tahoma设计
    • 用户正在运行Windows Vista或Windows 7(9pt Segoe UI)
    • 您正在我的计算机上运行(14pt Segoe UI)
    通过响应字体大小(以像素为单位),您可以免费获得高DPI支持(而且您是一名优秀的开发人员!):

    • 8pt Tahoma@96dpi:
      13px
      windows2000/XP(您使用的设计)
    • 8pt Tahoma@131dpi:
      15px
      (按115%缩放您的设计形状)
    • 9pt Segue UI@96dpi:
      15px
      windowsvista/7(将您设计的表单缩放115%)
    • 9pt塞戈UI@131dp:
      16px
      my home machine(将您的表单缩放123%)
    • 12pt Tahoma@96dpi:
      16px
      my work machine(将您设计的表格缩放123%)
    您想关闭表单的所有
    缩放属性;所以他们不会尝试响应dpi设置。您需要的.NET WinForms等效于


    是的,一旦您缴纳了税款,并且可以处理不同的DPI设置,就可以使用清单声明您的应用程序highDpi aware,正如其他答案所示

    不要使用
    SetProcessDPIAware
    ,因为它可能太晚了,无法:

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


    您可以在下面的位置查看注册表值AppliedDPI

    HKEY_CURRENT_USER\Control Panel\Desktop\WindowMetrics\AppliedDPI
    
    多亏了Andreas Rejbrand.

    如果它能帮助别人,
    我注意到屏幕->PrimaryMonitor->PixelsPerInch确实会随着显示比例的变化而变化。

    谢谢@david heffernan,我完全同意。问题是,意识到DPI意味着我必须自己处理所有的定制,这是一大堆工作。。。有更便宜的方法吗?如果您在每个表单上都将Scaled设置为True,那么VCL框架将扩展您的GUI。这就是我所做的。谢谢,页面是缩放的,但我需要知道我处于高DPI状态,以便我可以自定义控件。一旦你将应用程序标记为DPI感知,然后
    屏幕。PixelsPerInch
    将返回120、144等@Altaveron,那么你为什么对我的不同问题的答案投反对票?编写一个在非常高的DPI下运行良好的应用程序非常容易。你的那个没有。但我的是。那么,为什么要攻击这个答案呢?如果你愿意,我可以帮你。你好,海因里希,打电话给SetProcessDPIAware确实使D2DFactory获得了正确的DPI。唉,Screen.pixelperich仍然保持在96。@asafad您可能无法尽早调用
    SetProcessDPIAware
    。您可能需要在VCL初始化之前运行它。你可以把它放在一个不使用其他单位(我的意思是)的单位的初始化部分,然后把它放在你的.dpr文件中。但显式方法要好得多。遗憾的是,Delphi生成的应用程序清单无法
    HKEY_CURRENT_USER\Control Panel\Desktop\WindowMetrics\AppliedDPI