GVKun编程网logo

delphi – 在Windows Vista和Windows 7中排除DPI虚拟化和DPI感知应用程序的故障

22

如果您对delphi–在WindowsVista和Windows7中排除DPI虚拟化和DPI感知应用程序的故障感兴趣,那么这篇文章一定是您不可错过的。我们将详细讲解delphi–在WindowsVis

如果您对delphi – 在Windows Vista和Windows 7中排除DPI虚拟化和DPI感知应用程序的故障感兴趣,那么这篇文章一定是您不可错过的。我们将详细讲解delphi – 在Windows Vista和Windows 7中排除DPI虚拟化和DPI感知应用程序的故障的各种细节,此外还有关于c# – 使现有的.NET Windows应用程序具有DPI感知能力、c# – 有没有办法在Windows 7和visual studio 2012中创建一个Windows Phone 8应用程序、Delphi High DPI在自身缩放和Windows缩放之间切换、Delphi – Shift Ctrl 0组合Windows Vista上的应用程序看不到的实用技巧。

本文目录一览:

delphi – 在Windows Vista和Windows 7中排除DPI虚拟化和DPI感知应用程序的故障

delphi – 在Windows Vista和Windows 7中排除DPI虚拟化和DPI感知应用程序的故障

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

我的应用程序将使它知道Windows,它不需要DPI虚拟化功能,否则不会。我很了解我不明白的是DPI更改如何在两台机器上造成不同的外观,两台机器都以144 dpi的速度运行Windows 7,以相同的固定尺寸显示相同的字体和形式。

在DPI虚拟化中涉及到某些与配置有关的元素,我需要在Windows(注册表等)中进行检查?否则,您如何解决并了解DPI虚拟化是否在客户端窗口中完成?

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

在我的应用程序中对我来说最令人困惑的是,我有一个控制,只能在我的大型真实应用程序中存在不正当行为,但是在单独的应用程序中,我不会轻易地调试控件。要了解独立应用程序中的控制行为,我被迫做一个演示应用程序,我通过清单文件强制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>

这里是一个例子,约30个地方之一,当我的应用程序禁用DPI虚拟化时,我的应用程序中的控件被搞砸了。这个特殊的故障是通过关闭我的形式的Scaled属性来解决的。但在其他地方,TForm.Scaled = false会导致问题,而在某些形式中,它会修复它:

更新:事实证明,我的一些控件使用GDI,GDI上下文中的字体行为与正常GDI上下文中的字体行为不同,至少对于使用GDI的某些第三方控件。这是头痛的主要来源。其次,在VCL中有DPI意识的测试覆盖面和定义不明确的要求。一些VCL控件是基于MS Common Controls的,而在高DPI情况下,底层公共控件可能正常工作是可以公平的,并不是所有的VCL控件包装器都能保证正常工作。因此,在所有控件中检查高DPI意识的应用程序,以及所有可用的Windows 7主题中的正确行为:

>航空玻璃,在96dpi(大多数现代硬件的默认Win7外观)
>基本主题(aero glass off),但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虚拟化。

您不是要使用DPI虚拟化,所以我认为没有办法解决它的工作原理。它可以很容易地依赖于显卡驱动程序。我们几乎不可能解释为什么虚拟化的行为是这样的:你甚至没有给出任何屏幕截图,硬件细节等等。但是,你根本不应该打扰这个诊断。清单是dpiaware,这是一个非问题。

作为参考,我提供给你:

> Writing High-DPI Win32 Applications
> http://www.rw-designer.com/DPI-aware

c# – 使现有的.NET Windows应用程序具有DPI感知能力

c# – 使现有的.NET Windows应用程序具有DPI感知能力

我们有一个现有的 Windows .net应用程序,它使用所有自定义控件.

由于我们只支持默认的96 dpi分辨率,所以这些天很顺利.

现在我们需要我们的应用程序是dpi感知的.当我们去下一个时,事情就会变得混乱

更高分辨率120或144等

最常见的问题

>位图缩放问题和
>文字截止

经过these MSDN docs和existing SO问题后,我尝试了

在我的应用程序中使用这样的修复是徒劳的(因为所有使用的控件都是

定制,不是dpi感知).

在修改我的application.manifest以启用dpi-awareness标志并在主窗体和其他窗体上将AutoScaleMode设置为AutoScaleMode.Dpi之后尝试的事情使用AutoScaleMode作为继承

>更改了OnLoad事件中的控件字体

图形g = this.CreateGraphics();
int dpi = int.Parse(g.DpiX.ToString());

switch (dpi)
    {
        case 125:
            this.Font = new Font(this.Font.FontFamily,this.Font.Size * 125.0f / (float)(g.DpiX));
            Debug.WriteLine("<<---- Selected DPI Resolution :" + " 125 DPI ---->"); 
            break;
    ... so on

>尝试重写ScaleControl方法以使用基于DPI的不同缩放因子

但所有这些似乎都不适合我的情况.

有谁知道/建议我更好地解决这个问题.

谢谢

VATSAG

解决方法

所以,我在我的一个应用程序中遇到了同样的问题.我设法在两个步骤中绕过它,遗憾的是需要大量的重构,但是在完成工作之后,我设法让我的应用程序自动扩展到不同的DPI.这是怎么回事:

>必须使用AutoScaleMode = AutoScaleMode.Font将所有表单设置为缩放.当我进行一些挖掘时,我发现AutoScaleMode.Dpi并不像人们期望的那样工作.您还应该选择标准DPI单元.假设它是96,因为这是您的应用程序最初设计的原因,那么您必须将所有表单设置为使用AutoScaleDimensions = new System.Drawing.Sizef(6F,13F).您可以从设计器视图中设置这些配置.此外,如果您已创建任何自定义控件,则应将它们全部设置为使用AutoScaleMode = AsutoScaleMode.Inherit.有了这两件事,您可以放心,.NET将对所有静态组件进行所有扩展.
>现在是时候变得棘手了.问题是框​​架将保持所有关于正确大小的控件,只要它们不是动态创建并放在表单中.

所以如果你做的事情如下:

var myTextBox = new TextBox();
myTextBox.Location = new System.Drawing.Point(20,20);
myForm.Controls.Add(myTextBox);

然后,无论您的DPI是什么,该文本框都将被放置在位置(20,20),从而导致它在高DPI监视器上看起来不合适.所以解决方案是永远不要使用硬编码像素值,而是使用可动态扩展的值,具体取决于您当前的DPI配置.所以,你可能想要写一些类似的东西:

var graphics = Graphics.FromHwnd(IntPtr.Zero); // This gets the graphics configuration of the current screen
var scaleX = graphics.DpiX / 96; // 96 was our standard design DPI,remember?
var scaleY = graphics.DpiY / 96;
var myTextBox = new TextBox();

myTextBox.Location = new System.Drawing.Point((int)Math.Round(20 * scaleX),(int)Math.Round(20 * scaleY));

myForm.Controls.Add(myTextBox);

这样,您将在屏幕上绘制控件的位置将取决于实际的DPI.而且,如果我可以建议,我实际上会将缩放功能提取到某种辅助类中,您可以在其中定义在x和y上缩放值的方法,因此您将拥有标准的缩放机制.请注意,在x和y上独立缩放也很重要,因为某些屏幕在每个轴上具有不同的像素密度.

无论如何,如果你遵循这两个条件,你的应用程序应该看起来很好,独立于它显示的屏幕.

c# – 有没有办法在Windows 7和visual studio 2012中创建一个Windows Phone 8应用程序

c# – 有没有办法在Windows 7和visual studio 2012中创建一个Windows Phone 8应用程序

有没有办法在visual studio 2012和 Windows 7中创建和测试应用程序(Windows Phone 8的模拟器)?我从Dreamspark获得了所有正确的SDK等,但我似乎无法在Windows 7中找到一种方法.它只在Windows 8中“可行”吗?

解决方法

可能不是,微软只为Windows 8发布了它,但你总是可以拥有一台虚拟机,Dreamspark也有Windows的许可证,所以你也不会有任何问题.

Delphi High DPI在自身缩放和Windows缩放之间切换

Delphi High DPI在自身缩放和Windows缩放之间切换

我的一些客户希望能够手动扩展我的应用程序(当 Windows dpi设置为96时),因此我必须实现扩展.不幸的是,这些客户不能将Windows DPI设置为其他值并让WIndows扩展我的应用程序,因为他们使用的一些非常重要的应用程序在分辨率<>分辨率上表现不佳96 DPI.

我设法使我的Delphi 10.1应用程序规模相当好,即使在200%,但因素越高,一些比例变得“不太好看”.许多第三方组件需要特殊的缩放处理,即使这样也不能100%准确地扩展.虽然按窗口缩放的应用程序在高分辨率下看起来有点模糊,但所有比例都是100%准确,并且应用程序看起来更专业.

所以我问自己是否有可能创建一个设置,允许告诉Windows将扩展作为默认设置,并且如果客户希望扩展与当前Windows扩展不同,则只能自行扩展.此设置托管在应用程序启动时读取的可执行文件的Windows清单中.有没有办法在运行时更改它(应用程序的早期启动)?创建具有不同清单的两个可执行文件肯定不是一个好的解决方案.

谢谢你的帮助

解决方法

感谢Sertac Akyuz,我找到了解决问题的方法.在包含缩放代码的单元的初始化部分中,我可以在DPI-Awareness和Non-DPI-Awareness之间切换.重要的是不要在应用程序清单中设置此设置,这可以通过提供这样的自定义清单(使用控件修饰并使用当前用户的权限运行)来实现:

<?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的值,它完美无缺.

Delphi – Shift Ctrl 0组合Windows Vista上的应用程序看不到

Delphi – Shift Ctrl 0组合Windows Vista上的应用程序看不到

我从一个新的Delphi VCL应用程序开始,将menus添加到uses子句中,在表单上放置一个标签,并分配表单的OnShortCut事件:
procedure TForm1.FormShortCut(var Msg: TWMKey; var Handled: Boolean);
begin
  Label1.Caption := ShortCutToText(ShortCut(Msg.CharCode,KeyDataToShiftState(Msg.KeyData)));
end;

在XP上,对于我所尝试的所有快捷键组合(包括Shift Ctrl 0),该功能正常工作.在Vista和Windows 7上,测试应用程序通过Shift Ctrl 9显示Shift Ctrl 1,但不显示Shift Ctrl 0.其他组合如Shift 0,Ctrl 0,甚至Shift Ctrl Alt 0都显示正常.

在调试器下运行应用程序,我发现如果在按下0键的同时按住Shift和Ctrl键,OnShortCut事件永远不会被Msg.CharCode = Ord(‘0’)触发.

Delphi IDE在Vista下有同样的问题. Ctrl Shift 1设置书签1,但是Ctrl Shift 0不设置书签0,它应该是书签.

我已经使用Delphi 2007和2010在VMware的Windows Vista和7的处理器安装上进行了测试,所以没有第三方软件捕获密钥.我没有尝试任何其他开发工具来确定问题是与Delphi还是Vista本身.

解决方法

Shift Ctrl 0在Vista中被预先分配给输入法编辑器(IME):

http://support.microsoft.com/kb/967893

这将解决您的问题,但会影响IME的用户(大多是亚洲版本),因此您应该考虑不要使用此快捷方式.

关于delphi – 在Windows Vista和Windows 7中排除DPI虚拟化和DPI感知应用程序的故障的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于c# – 使现有的.NET Windows应用程序具有DPI感知能力、c# – 有没有办法在Windows 7和visual studio 2012中创建一个Windows Phone 8应用程序、Delphi High DPI在自身缩放和Windows缩放之间切换、Delphi – Shift Ctrl 0组合Windows Vista上的应用程序看不到等相关知识的信息别忘了在本站进行查找喔。

本文标签: