如果您对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感知应用程序的故障
- 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感知应用程序的故障
我的应用程序将使它知道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模式都是一个负担太重了。所以大多数人不打扰。我对吗?
解决方法
<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感知能力
由于我们只支持默认的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
解决方法
>必须使用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应用程序
解决方法
Delphi High DPI在自身缩放和Windows缩放之间切换
我设法使我的Delphi 10.1应用程序规模相当好,即使在200%,但因素越高,一些比例变得“不太好看”.许多第三方组件需要特殊的缩放处理,即使这样也不能100%准确地扩展.虽然按窗口缩放的应用程序在高分辨率下看起来有点模糊,但所有比例都是100%准确,并且应用程序看起来更专业.
所以我问自己是否有可能创建一个设置,允许告诉Windows将扩展作为默认设置,并且如果客户希望扩展与当前Windows扩展不同,则只能自行扩展.此设置托管在应用程序启动时读取的可执行文件的Windows清单中.有没有办法在运行时更改它(应用程序的早期启动)?创建具有不同清单的两个可执行文件肯定不是一个好的解决方案.
谢谢你的帮助
解决方法
<?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上的应用程序看不到
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本身.
解决方法
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上的应用程序看不到等相关知识的信息别忘了在本站进行查找喔。
本文标签: