问题描述
我正在使用Delphi XE5.我认为我的笔记本电脑有问题.一段时间后,它向Screen.Width和GetSystemMetrics(SM_CXSCREEN)返回错误的值(与Height相同).我的操作系统是Windows 7 64位.
I am using Delphi XE5. I think i have a problem with my laptop. After a while, it returns wrong value to Screen.Width and GetSystemMetrics(SM_CXSCREEN) (same for Height). My OS is Windows 7 64-bit.
我的笔记本电脑的屏幕分辨率为1920x1080(1080p),但是我的应用程序显示为1280x720(720p).我不认为有DPI问题,因为问题在我重新启动并在一段时间后开始时会发生.兼容性设置也处于关闭状态.有人遇到过这个问题吗?还是您知道解决方案?我还添加了以下清单,但没有帮助
My laptop's screen res is 1920x1080 (1080p) however my app says it is 1280x720 (720p). I don't think there is a DPI problem as the problem goes when i reboot and starts after a while. Also Compatibality settings are off. Did anyone have this problem before? Or do you know a solution? I have also added the manifest below but didn't help
<?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>
</assembly>
这是我的编译方式
1 24 "mf.txt"
好吧,我编写了此函数,这是修复它的棘手方法.我更喜欢Screen.Width返回正确的值:
Ok I wrote this function which is tricky way to fix it. I prefer Screen.Width return correct value:
function ScreenSize(var x, y: integer): boolean;
const
ENUM_CURRENT_SETTINGS = -1;
ENUM_REGISTRY_SETTINGS = -2;
var
dm: TDevMode;
begin
Result := False;
x := 0;
y := 0;
ZeroMemory(@dm, sizeof(dm));
if EnumDisplaySettings(nil, Cardinal(ENUM_CURRENT_SETTINGS), dm) then
begin
Result := True;
x := dm.dmPelsWidth;
y := dm.dmPelsHeight;
end else
begin
x := GetSystemMetrics(SM_CXSCREEN);
y := GetSystemMetrics(SM_CYSCREEN);
end;
end;
我发现SetProcessDPIAware
解决了我的问题,但在XP中不起作用
I have found SetProcessDPIAware
solved my problem but it doesn't work in XP
推荐答案
您声明系统正在以150%的字体缩放比例运行.如果您的应用程序使用 DPI虚拟化运行,那么该虚拟化将说明您观察到的行为.请注意1920 / 1.5 = 1280
和1080 / 1.5 = 720
.
You state that your system is running at 150% font scaling. If your application runs with DPI virtualization then this virtualization explains the behaviour you observe. Note that 1920 / 1.5 = 1280
and 1080 / 1.5 = 720
.
您报告的行为的唯一合理解释是该进程正在DPI虚拟化下运行.应用DPI感知清单选项将停止DPI虚拟化.因此,很可能清单文件未正确链接到您的应用程序,或者清单文件无效.
The only reasonable explanation for the behaviour that you report is that the process is running under DPI virtualization. Applying the DPI aware manifest option will stop DPI virtualization. So, it would seem most likely that the manifest is not being linked to your application correctly, or the manifest is not valid.
我怀疑您的应用程序可能链接了两个清单.其中第二个将被丢弃.如果您在Delphi项目中使用默认的应用程序设置,则会发生这种情况.下一步是使用资源查看器查看链接到可执行文件的实际资源.这是查看已链接内容的肯定方法.
I suspect that your application might have two manifest linked to it. The second one of which would be discarded. That would happen if you used the default application settings in your Delphi project. The next step for you is to look at the actual resources linked to your executable file by using a resource viewer. That's the sure fire way to see what has been linked.
解决方案可能是在Delphi Project Options的应用程序"节点中使用自定义清单选项,并提供完整的应用程序清单.这需要指定comctl32 v6来启用主题,asInvoker
的requireAdministrator
选项以及DPI感知选项.
Probably the solution will be to use the custom manifest option in the Application node of the Delphi Project Options and supply the complete application manifest. This will need to specify comctl32 v6 to enable themes, the requireAdministrator
option of asInvoker
, and the DPI aware option.
这篇关于GetSystemMetrics和TScreen返回错误的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!