Стилистика элементов управления MDI в TActionMainMenuBar для соответствия TMainMenu в приложениях на Delphi
При разработке приложений с использованием Delphi и VCL часто возникает потребность в единообразном стиле элементов управления. Одной из задач является стилизация кнопок управления окнами (Minimize, Close и т.д.) в MDI-интерфейсе, чтобы они соответствовали стилю основного меню TMainMenu. В данной статье мы рассмотрим, как решить эту проблему, используя примеры кода на Object Pascal.
Описание проблемы
В процессе разработки MDI-приложений на Delphi пользователь столкнулся с проблемой стилизации кнопок управления окнами в TActionMainMenuBar. Несмотря на применение стилей VCL, кнопки оставались нестилизованными, в отличие от TMainMenu. Пример проблемы представлен на изображении:
Анализ проблемы
Проблема заключается в том, что метод TCustomMDIMenuButton.Paint использует устаревший WinAPI метод DrawFrameControl, который не поддерживает стилизацию элементов управления.
Подтвержденный ответ
Выяснилось, что проблема не связана с Vcl Styles, а является багом VCL. В методе TCustomMDIMenuButton.Paint используется DrawFrameControl, который не поддерживает темы оформления. Решением может стать патчинг данного метода с помощью detour и реализация нового метода рисования, использующего StylesServices.
Пример решения
Для решения проблемы можно использовать следующий подход: добавление в проект новой единицы PatchMDIButtons, которая содержит код для патчинга метода рисования кнопок. Ниже приведен примерный код для этой единицы:
unit PatchMDIButtons;
interface
implementation
uses
System.SysUtils,
Winapi.Windows,
Vcl.Themes,
Vcl.Styles,
Vcl.ActnMenus;
type
TCustomMDIMenuButtonClass = class(TCustomMDIMenuButton);
// Остальные типы...
var
PaintMethodBackup: TXRedirCode;
// Остальные переменные...
function GetActualAddr(Proc: Pointer): Pointer;
// Функция для получения актуального адреса процедуры
procedure HookProc(Proc, Dest: Pointer; var BackupCode: TXRedirCode);
// Процедура для установки хука
procedure UnhookProc(Proc: Pointer; var BackupCode: TXRedirCode);
// Процедура для снятия хука
procedure PaintPatch(Self: TObject);
// Процедура для патченного метода рисования
// Здесь используется StylesServices для стилизации элементов
procedure HookPaint;
// Процедура для установки хука на метод Paint
procedure UnHookPaint;
// Процедура для снятия хука с метода Paint
initialization
HookPaint;
finalization
UnHookPaint;
end.
Применение данного патча позволит стилизовать кнопки управления окнами в соответствии со стилем основного меню. Результат применения патча представлен на следующих изображениях:
Заключение
Приведенный пример позволяет решить проблему стилизации кнопок управления окнами в MDI-интерфейсе, делая их внешний вид согласованным с основным меню приложения. Важно помнить, что использование патчей может потребовать дополнительной настройки под конкретные условия проекта, а также необходимо учитывать возможные ограничения и риски, связанные с модификацией системных методов.
Проблема стилизации элементов управления в MDI-интерфейсе на Delphi для соответствия основному меню.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS