问题
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.
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>
here is how i compiled it
1 24 "mf.txt"
EDIT:
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;
EDIT 2:
I have found SetProcessDPIAware
solved my problem but it doesn't work in XP
回答1:
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
.
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.
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.
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.
来源:https://stackoverflow.com/questions/28339257/getsystemmetrics-and-tscreen-returns-wrong-value