GetSystemMetrics и TScreen возвращают неверное значение

Я использую Delphi XE5. Я думаю, что у меня проблема с моим ноутбуком. Через некоторое время он возвращает неверное значение Screen.Width и GetSystemMetrics(SM_CXSCREEN) (то же самое для высоты). Моя ОС - Windows 7 64-битная.

Разрешение экрана моего ноутбука составляет 1920x1080 (1080p), однако мое приложение сообщает, что оно составляет 1280x720 (720p). Я не думаю, что есть проблема 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>
</assembly>

вот как я это скомпилировал

1 24 "mf.txt"

РЕДАКТИРОВАТЬ:

Хорошо, я написал эту функцию, которая является хитрым способом исправить это. Я предпочитаю Screen.Width вернуть правильное значение:

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;

РЕДАКТИРОВАТЬ 2:

я нашел SetProcessDPIAware решил мою проблему, но она не работает в XP

1 ответ

Вы заявляете, что ваша система работает с масштабированием шрифта 150%. Если ваше приложение работает с виртуализацией DPI, эта виртуализация объясняет поведение, которое вы наблюдаете. Обратите внимание, что 1920 / 1.5 = 1280 а также 1080 / 1.5 = 720,

Единственное разумное объяснение поведения, о котором вы сообщаете, состоит в том, что процесс выполняется под виртуализацией DPI. Применение опции манифеста с учетом DPI остановит виртуализацию DPI. Таким образом, наиболее вероятно, что манифест неправильно связан с вашим приложением или недействителен.

Я подозреваю, что ваше приложение может иметь два манифеста, связанных с ним. Второй из которых будет отброшен. Это произошло бы, если бы вы использовали настройки приложения по умолчанию в вашем проекте Delphi. Следующим шагом для вас является просмотр фактических ресурсов, связанных с вашим исполняемым файлом, с помощью средства просмотра ресурсов. Это верный способ увидеть, что было связано.

Вероятно, решение будет состоять в том, чтобы использовать опцию пользовательского манифеста в узле Application в параметрах проекта Delphi и предоставить полный манифест приложения. Для включения тем необходимо указать comctl32 v6. requireAdministrator вариант asInvokerи вариант с поддержкой DPI.

Другие вопросы по тегам