GetSystemMetrics and TScreen returns wrong value

耗尽温柔 提交于 2019-12-12 15:23:54

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!