Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 在Windows Vista和Windows 7中对DPI虚拟化和支持DPI的应用程序进行故障排除_Delphi_Windows 7_Windows Vista_Dpi_Highdpi - Fatal编程技术网

Delphi 在Windows Vista和Windows 7中对DPI虚拟化和支持DPI的应用程序进行故障排除

Delphi 在Windows Vista和Windows 7中对DPI虚拟化和支持DPI的应用程序进行故障排除,delphi,windows-7,windows-vista,dpi,highdpi,Delphi,Windows 7,Windows Vista,Dpi,Highdpi,我有一个问题,应用程序(用Delphi编写)在所有系统上的默认96 DPI设置下运行正常,但在不同系统上的“150%文本大小”(内部144 DPI)设置下运行不一致。似乎在某些系统上,我的应用程序的某些文本/字体部分正在被拉伸,而在其他系统上,它们没有。我本以为我的应用程序,在特定版本的Windows(Win7)上,在特定的DPI下,应该以同样的方式运行 要么我的应用程序会让Windows知道它不需要DPI虚拟化功能,要么它不会。我明白这一点。我不明白的是,DPI更改如何在两台机器上造成不同的外

我有一个问题,应用程序(用Delphi编写)在所有系统上的默认96 DPI设置下运行正常,但在不同系统上的“150%文本大小”(内部144 DPI)设置下运行不一致。似乎在某些系统上,我的应用程序的某些文本/字体部分正在被拉伸,而在其他系统上,它们没有。我本以为我的应用程序,在特定版本的Windows(Win7)上,在特定的DPI下,应该以同样的方式运行

要么我的应用程序会让Windows知道它不需要DPI虚拟化功能,要么它不会。我明白这一点。我不明白的是,DPI更改如何在两台机器上造成不同的外观,这两台机器都运行Windows 7,都是144 DPI,以相同的固定大小显示相同的字体和表单

DPI虚拟化中是否有一些依赖于配置的元素需要在windows(注册表等)中检查?否则,您如何排除故障并知道DPI虚拟化是否正在客户端窗口上进行

在Delphi中,如果不希望缩放,则必须将TForm.Scaled属性设置为false。但我不明白的是,当主窗体的缩放属性为真时,我不能总是预测结果

在我的应用程序中,最让我困惑的是,我有一个控件,它只在我的大型实际应用程序中出现错误,但在我试图调试控件的独立应用程序中却没有出现错误。为了理解独立应用程序中的控制行为,我被迫制作一个演示应用程序,通过清单文件强制输入DPI意识。然后,我可以复制控制绘图故障,尽管形式不同

这是我在演示应用程序中使用的清单文件,它暴露了我的控件在处理windows中的高dpi设置时存在的问题。然而,我发现一件奇怪的事情是,应用程序是可能的

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
 <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>
  <assemblyIdentity version="14.0.3615.26342" processorArchitecture="*"            
   name="TestProject" type="win32"></assemblyIdentity>
  <description>High DPI Controls Test App</description>
</assembly>

真的
高DPI控制测试应用程序
这里有一个例子,当我在我的应用程序中禁用DPI虚拟化时,我的应用程序中有30个地方的控件被弄乱了。通过关闭表单中的“缩放”属性,解决了这个特殊问题。但在其他地方,使用TForm.Scaled=false会导致问题,而在某些形式中,它会修复问题:

更新:事实证明,我的一些控件使用GDI+,GDI+上下文中的字体行为与正常GDI上下文中的字体行为不同,至少对于使用GDI+的某些第三方控件是这样。这是头痛的主要原因。其次,VCL中的DPI意识测试覆盖率参差不齐,要求定义不清。一些VCL控件基于MS Common控件,可以公平地说,底层的Common控件可能在高DPI情况下工作良好,但并非所有VCL控件包装器都能保证正常工作。因此,检查应用程序的所有控件是否具有高DPI感知能力,以及所有可用windows 7主题是否具有正确的行为:

  • aero glass开启,96dpi(大多数现代硬件上的默认Win7外观)
  • 基本主题(aero glass关闭),但xp主题已启用
  • 经典的win2000外观,玻璃关闭,以及xp级主题
  • 高对比度白色
  • 高对比度黑色
  • 除-96-DPI设置外的各种其他设置

  • …还有很多,作为一名应用程序开发人员,你有一个相当沉重的负担。无论你是Delphi用户,还是使用VCL,或者你是MFC/ATL C++开发人员,我认为,支持各种各样古怪的Windows模式是一个负担太重的负担。所以大多数人都不介意。我说的对吗?

    您需要通过以下部分来证明您的应用程序支持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设置”窗口中有一个“使用Windows XP样式的DPI缩放”。这可能解释了不同的行为。

    事实证明,当系统DPI从默认的96 DPI值更改时,我的应用程序中的怪癖有三个方面:

  • 应用程序的一些控件使用GDI,一些控件使用GDI+。GDI和GDI+字体在不同DPI下的呈现方式存在一些差异,至少在我使用的控件中是如此

  • 我在delphi中使用了一个名为VCL的框架。在这个Delphi VCL框架中,有些表单的TForm.Scaled=true,有些表单的TForm.Scaled=false。因为它要求您考虑缩放表单中的每个控件,所以很常见的情况是,作为UI设计师,您会发现缩放表单中的控件“丑陋”或不可接受。关闭缩放功能后,剩下的表单要么由Windows 7本身拉伸,要么在高DPI设置(DPI虚拟化模式)下,要么看起来很小,因此,如果您愿意,可以忽略用户对144 DPI版本的96 DPI UI的“请求”。其他人可能使用其他语言的其他框架,或者甚至使用一些老式的东西,比如VisualC++中的对话框编辑器,在对话框对话框中设计对话框,这是试图将一般对话框布局从1对应到像素的另一种方式。缩放、拉伸和布局控件是UI设计的一般部分,必须以符合平台要求的方式解决。在我的例子中,VCL在让我设计一个96 DPI的支持玻璃的aero应用程序方面做得很好,在其他DPI评级下也很好,但我的大多数自定义控件都没有。所以,这也是坚持VCL附带的控制的另一个原因:如果您关心高DPI支持,当您试图使高DPI支持发挥作用时,您的工作会变得更加困难

  • DPI虚拟化反过来又由清单设置控制,您必须在应用程序中明确包含该清单设置。自从
    scaleFactor = (userFontSize / designedFontSize)
                = 21px / 13px
                = 1.615
    
    9pt Segoe UI,  96dpi = 6.81px x 15px
    9pt Segoe UI, 131dpi = 8.98px x 21px
    
    procedure StandardizeFormFont(Form: TForm);    
    var
       iconTitleFontName: string;
       iconTitleFontSizePixels: Integer;
       currentFontSizePixels: Integer;
    begin
       GetIconTitleFont(iconTitleFontName, iconTitleFontSizePixels);
    
       //Change font face first
       //Some fonts are inheriently taller than others
       //(even at the same point size)
       Form.Font.Name := iconTitleFontName;     
    
       //Get the form's current font height (in pixels)
       currentFontSizePixels := Form.Font.Height; //negative number, but so is iconTitleFontSizePixels
    
       Form.ScaleBy(iconTitleFontSizePixels, currentFontSizePixels);
    end;
    
    protected
       procedure ChangeScale(M, D: Integer); override;