Сделать приложение Delphi XE не поддерживающим DPI

Я только что создал новое приложение в Delphi, и хотя другие приложения написаны таким же образом, это новое приложение не масштабируется Windows автоматически. Все приложения имеют одинаковые настройки (например, Scaled = false). И Windows обычно масштабирует их правильно (иначе они будут слишком маленькими, если масштабирование установлено на 150 % или выше).

Я обнаружил, что использование меню свойств файла .exe, вкладок «Совместимость», «Изменить настройки HIGH-DPI» и установки «Масштабирование по системе» внизу решает проблему, и приложение масштабируется правильно.

Но как мне активировать эту опцию по умолчанию (Реестр?) или как это сделать программно?

Вы действительно используете XE (с 2010 года)? Приложения IIRC и XE изначально не поддерживали DPI. Вам нужно было написать собственный манифест приложения или явно выполнить вызовы API, чтобы включить поддержку DPI. Только за последние несколько лет в Delphi появилась встроенная функция правильной обработки DPI.

Remy Lebeau 13.07.2024 06:53

Возможно, уже существует манифест, утверждающий, что приложение поддерживает dpi?

Uwe Raabe 13.07.2024 09:33

Нет, проблема была в другой DLL, которая загружается при запуске программы. Он деактивирует масштабирование, поскольку для правильной работы требуется немасштабированное приложение. Мне потребовалось пол ночи, чтобы это выяснить...

Andreas Ströbel 13.07.2024 19:24
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
156
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете предоставить своему приложению манифест приложения, в котором указаны <dpiAwareness>unaware</dpiAwareness> (Windows 10 v1607 и более поздние версии), <gdiScaling>false</gdiScaling> (Windows 10 v1703 и более поздние версии) и <dpiAware>false</dpiAware> (более ранние версии), например:

<?xml version = "1.0" encoding = "UTF-8" standalone = "yes"?>
<assembly xmlns = "urn:schemas-microsoft-com:asm.v1" manifestVersion = "1.0" xmlns:asmv3 = "urn:schemas-microsoft-com:asm.v3">
  <application xmlns = "urn:schemas-microsoft-com:asm.v3">
    <windowsSettings>
      <dpiAware xmlns = "http://schemas.microsoft.com/SMI/2005/WindowsSettings">false</dpiAware>
      <dpiAwareness xmlns = "http://schemas.microsoft.com/SMI/2016/WindowsSettings">unaware</dpiAwareness>
      <gdiScaling xmlns = "http://schemas.microsoft.com/SMI/2017/WindowsSettings">false</gdiScaling>
    </windowsSettings>
  </application>
</assembly>

В качестве альтернативы, прежде чем создавать какие-либо окна графического интерфейса во время выполнения, вы можете вызвать либо SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_UNAWARE) (Windows 10 v1607 и более поздние версии), либо SetProcessDpiAwareness(PROCESS_DPI_UNAWARE) (более ранние версии), например:

program MyProject;

uses
  Vcl.Forms, Winapi.Windows,
  MyMainForm in 'MainForm.pas' {MyMainForm};

{$R *.res}

{$IF NOT DECLARED(DPI_AWARENESS)}
type
  DPI_AWARENESS = (
    DPI_AWARENESS_INVALID = -1,
    DPI_AWARENESS_UNAWARE = 0,
    DPI_AWARENESS_SYSTEM_AWARE = 1,
    DPI_AWARENESS_PER_MONITOR_AWARE = 2
  );
{$IFEND}

{$IF NOT DECLARED(DPI_AWARENESS_CONTEXT)}
type
  DPI_AWARENESS_CONTEXT__ = record
  var
    unused: Integer;
  end;
  DPI_AWARENESS_CONTEXT = ^DPI_AWARENESS_CONTEXT__;

const
  DPI_AWARENESS_CONTEXT_UNAWARE: DPI_AWARENESS_CONTEXT = DPI_AWARENESS_CONTEXT(-1);
{$IFEND}

type
  LPFN_SetProcessDpiAwarenessContext = function(value: DPI_AWARENESS_CONTEXT): BOOL; stdcall;
  LPFN_SetProcessDpiAwareness = function(value: PROCESS_DPI_AWARENESS): HRESULT; stdcall;

var
  lpSetProcessDpiAwarenessContext: LPFN_SetProcessDpiAwarenessContext;
  lpSetProcessDpiAwareness: LPFN_SetProcessDpiAwareness;
begin
  @lpSetProcessDpiAwarenessContext := GetProcAddress(LoadLibrary('User32.dll'), 'SetProcessDpiAwarenessContext');
  if Assigned(lpSetProcessDpiAwarenessContext) then begin
    lpSetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_UNAWARE);
  end else begin
    @lpSetProcessDpiAwareness := GetProcAddress(LoadLibrary('Shcore.dll'), 'SetProcessDpiAwareness');
    if Assigned(lpSetProcessDpiAwareness) then
      lpSetProcessDpiAwareness(PROCESS_DPI_UNAWARE);
  end;

  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Application.CreateForm(TMyMainForm, MyMainForm);
  Application.Run;
end.

Дополнительные сведения см. в разделе Настройка определения DPI по умолчанию для процесса на сайте MSDN.

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