2016-11-19 911 views
1

我的一些客户希望能够手动缩放我的应用程序(当Windows dpi设置为96时),所以我必须实现缩放。不幸的是,这些客户无法将Windows DPI设置为其他值,并让WIndows扩展我的应用程序,因为他们使用的一些非常重要的应用程序在分辨率为<> 96 DPI时表现不佳。Delphi自己的缩放和Windows缩放之间的高DPI切换

我设法让我的Delphi 10.1应用程序的规模在200%的情况下仍然很好,但因子越高,一些比例就越“变得不那么好看”。许多第三方组件需要特殊的缩放处理,即使这样也不能100%准确地进行缩放。虽然窗口缩放的应用程序在高分辨率下看起来有点模糊,但所有比例都是100%准确的,而且应用程序看起来更专业。

所以我问自己是否有可能创建一个设置,允许告诉Windows将缩放比作为默认设置,并且只有当客户需要与当前Windows缩放比例不同的缩放比例时才可以自行缩放。此设置位于在应用程序启动时读取的可执行文件的Windows清单中。有没有办法在运行时更改它(应用程序的早期启动)?用不同清单创建两个可执行文件当然不是好的解决方案。

感谢所有帮助

+0

您提到的设置是“”吗?如果是这样,请参见[SetProcessDpiAwareness](https://msdn.microsoft.com/en-us/library/dn302122(v = vs.85).aspx)中的注释。 –

+0

谢谢,我会尽力的! – MichaSchumann

+1

为什么我的问题被拒绝? – MichaSchumann

回答

6

感谢Sertac Akyuz我找到了解决我的问题。在包含缩放代码的单元的初始化部分中,我可以在DPI感知和非DPI感知之间切换。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> 
<dependency> 
    <dependentAssembly> 
    <assemblyIdentity 
     type="win32" 
     name="Microsoft.Windows.Common-Controls" 
     version="6.0.0.0" 
     publicKeyToken="6595b64144ccf1df" 
     language="*" 
     processorArchitecture="*"/> 
    </dependentAssembly> 
</dependency> 
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> 
    <security> 
    <requestedPrivileges> 
     <requestedExecutionLevel 
     level="asInvoker" 
     uiAccess="false"/> 
     </requestedPrivileges> 
    </security> 
</trustInfo> 
</assembly> 

这是实际的代码转换:不要在应用程序清单,可以通过这样提供一个定制清单来实现此设置(使用控制装修,并与当前用户的权限运行)是非常重要的根据注册表项:

// Set DPI Awareness depending on a registry setting 
with TRegIniFile.create('SOFTWARE\' + SRegName) do 
begin 
    setting := readInteger('SETTINGS', 'scale', 0); 
    Free; 
end; 
handle := LoadLibrary('shcore.dll'); 
if handle <> 0 then 
begin 
    setProcessDPIAwareness := GetProcAddress(handle, 'SetProcessDpiAwareness'); 
    if Assigned(setProcessDPIAwareness) then 
    begin 
    if setting < 2 then 
     // setting <2 means no scaling vs Windows 
     setProcessDPIAwareness(0) 
    else 
     // setting 2: 120%, 3: 140% vs. Windows 
     // The actual used scaling factor multiplies by windows DPI/96 
     setProcessDPIAwareness(1); 
    end; 
    FreeLibrary(handle); 
    // Get windows scaling as Screen.PixelsPerInch was read before swiching DPI awareness 
    // Our scaling routines now work with WinDPI instead of Screen.PixelsPerInch 
    WinDPI:= Screen.MonitorFromWindow(application.handle).PixelsPerInch; 
end; 

这个片段的最后一行检索当前监视器的当前DPI为screen.pixelsperinch好像之前被初始化,并始终返回96作为非DPI感知的应用程序。我在随后的所有缩放计算中使用winDPI的值,并且它非常完美。

+0

经过一遍又一遍的思考后,我得出结论:我的方法比必要的复杂得多。如果用户请求,我认为我可以将应用程序设置为不识别dpi,并将其放在顶部。这样可以避免在Surface或我的Lenovo 900s等设备上出现高比例因子,如果我按比例缩放140%,并且设备需要其他200%,导致280%的e。 G。表面亲。 – MichaSchumann

+0

我的解决方案可能有助于某人搜索在运行时识别非dpi识别和dpi识别的可能性。 I(= blockhead)忽略了将Windows缩放比例(非dpi分辨率)和我自己的缩放比例(例如用于轻微可见的受损人群)的可能性。它现在运行良好,比例很好,因为我的最大比例为140%。 – MichaSchumann