Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Как правильно обрабатывать централизованные TActionLists в приложениях с поддержкой HighDPI для обеспечения правильного масштабирования изображений на разных мониторах?

Delphi , Графика и Игры , Изображения

Решение проблем масштабирования изображений в HighDPI приложениях Delphi с централизованными TActionList

Проблема

При использовании централизованных TActionList с TVirtualImageList на DataModule в приложениях Delphi возникает проблема: при перемещении формы на монитор с другим DPI изображения действий не масштабируются корректно. Это происходит из-за того, что TVirtualImageList не принадлежит форме и не может адаптироваться к изменениям DPI в реальном времени.

Пример сценария:

// DataModule с централизованными ресурсами
TMainDataModule = class(TDataModule)
  ActionList: TActionList;
  VirtualImageList: TVirtualImageList;
  // ...
end;

Привязка действий к элементам управления на разных формах приводит к "расплыванию" иконок на мониторах с высоким DPI.


Основное решение: TVirtualImageList на каждой форме

Почему это необходимо?

Windows API требует, чтобы HIMAGELIST содержал изображения фиксированного размера. Каждая форма может находиться на мониторе с уникальным масштабом, что делает централизованное управление изображениями невозможным.

Шаги реализации: 1. Добавьте TVirtualImageList на каждую форму. 2. Свяжите его с визуальными элементами (меню, тулбары):

// На форме
TMainForm = class(TForm)
  ToolBar: TToolBar;
  MainMenu: TMainMenu;
  Actions: TActionList;
  FormImageList: TVirtualImageList;
  procedure FormCreate(Sender: TObject);
end;

procedure TMainForm.FormCreate(Sender: TObject);
begin
  ToolBar.Images := FormImageList;
  MainMenu.Images := FormImageList;
  Actions.Images := MainDataModule.VirtualImageList; // Централизованные действия
end;
  1. Используйте TImageCollection для хранения оригиналов изображений:
// Центральный ImageCollection на DataModule
TMainDataModule = class(TDataModule)
  ImageCollection: TImageCollection;
  // ...
end;
  1. Настройте TVirtualImageList форм на использование общего TImageCollection:
<!-- DFM-файл формы -->
object FormImageList: TVirtualImageList
  ImageCollection = MainDataModule.ImageCollection
  Scaled = True
end

Альтернативные подходы

1. Использование DevExpress TcxImageList (SVG)

Для проектов с DevExpress компонентами:

// Пример использования SVG
var
  ImageList: TcxImageList;
begin
  ImageList := TcxImageList.Create(nil);
  ImageList.AddSvg('SVG_DATA_HERE', clRed, 16); // 16 - базовый размер
  Action.Images := ImageList;
end;

Ограничения: - Не поддерживает стандартные VCL-контролы (TTreeView, TListView) - Требует замены элементов интерфейса на DX-аналоги (TdxBarManager вместо TMainMenu)

2. Динамическое копирование изображений

Решение Dave Novo с синхронизацией изображений:

// Центральный DataModule
procedure TMainDataModule.CopyImageTo(AImageList: TCustomImageList; 
  const AImageName: string);
begin
  ImageCollection.GetIcon(ImageCollection.GetIndexByName(AImageName), AImageList.Add);
end;

// На форме
procedure TMainForm.FormCreate(Sender: TObject);
begin
  MainDataModule.CopyImageTo(FormImageList, 'ExportToExcel');
  actExport.ImageIndex := 0;
end;

Лучшие практики

  1. Единый источник изображений:
    Храните SVG/PNG в TImageCollection
    Используйте именованные изображения:
     const IMG_EXPORT = 'export_icon';
     IMG_PRINT = 'print_icon';
  2. Автоматизация при проектировании: Создайте шаблон формы с предустановленными настройками:  
    object
     TemplateForm: TForm
    object
     VirtualImageList: TVirtualImageList
     ImageCollection = MainDataModule.ImageCollection
    AutoFill = True
    end
    end

  3. Обработка DPI-изменений:
    procedure TMainForm.WMDpiChanged(var Message: TWMDpi);
    begin
    inherited;
    FormImageList.SetSize(CurrentDpi); // Автоматическая перерисовка
    UpdateActions; // Обновление элементов интерфейса
    end;

  4. Тестирование:
     // Принудительная смена DPI в IDE
    procedure TTestForm.Button1Click(Sender: TObject);
    begin
    ChangeDpi(FormImageList, 144); // Тест для 150%
    end;


Сравнение подходов

Метод Плюсы Минусы
Форменные ImageLists Нативная поддержка VCL Ручное создание компонентов
DevExpress Векторная графика Привязка к DX-контролам
Динамическое копир. Гибкость Риск рассинхронизации

Рекомендация: Для крупных проектов с mixed-DPI окружениями оптимально комбинировать подходы: использовать TVirtualImageList на формах с централизованным TImageCollection, дополняя DevExpress-компонентами для сложных интерфейсов.

Создано по материалам из источника по ссылке.

Этот текст описывает проблему масштабирования изображений в HighDPI приложениях Delphi с централизованными TActionList и предлагает несколько решений для ее устранения.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Изображения ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-05-01 09:20:52/0.0038149356842041/0