Многострочная кнопка с центрированным текстом в Delphi и Pascal: Просто и элегантно
Создание пользовательского интерфейса в Delphi и Pascal часто требует нестандартных решений. Одним из таких решений является создание многострочной кнопки с центрированным текстом. Стандартный компонент TButton не предоставляет такой возможности "из коробки", но это легко реализуется с помощью небольшого количества кода.
Проблема:
Стандартный компонент TButton позволяет отображать только одну строку текста. Попытка вставить символ переноса строки (#13#10 или sLineBreak) в свойство Caption кнопки приведет лишь к отображению этих символов как обычного текста. Кроме того, стандартная кнопка не предоставляет возможности центрирования текста по вертикали.
Решение 1: Использование DrawText и перерисовка кнопки
Наиболее распространенным и гибким решением является перерисовка кнопки с использованием функции DrawText. Мы создадим свой собственный компонент, унаследованный от TButton, и переопределим метод Paint.
unit MultiLineButton;
interface
uses
System.SysUtils, System.Classes, Vcl.Controls, Vcl.StdCtrls, Vcl.Graphics;
type
TMultiLineButton = class(TButton)
private
FAlignment: TAlignment;
procedure SetAlignment(const Value: TAlignment);
protected
procedure Paint; override;
public
constructor Create(AOwner: TComponent); override;
published
property Alignment: TAlignment read FAlignment write SetAlignment default taCenter;
end;
procedure Register;
implementation
uses Vcl.Themes;
{ TMultiLineButton }
constructor TMultiLineButton.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FAlignment := taCenter;
ControlStyle := ControlStyle + [csOpaque]; // Важно для предотвращения мерцания
end;
procedure TMultiLineButton.Paint;
var
TextRect: TRect;
Flags: Integer;
begin
inherited; // Сначала рисуем стандартную кнопку
TextRect := ClientRect;
Flags := DT_WORDBREAK or DT_CENTER or DT_VCENTER or DT_SINGLELINE;
if not Enabled then
begin
Canvas.Font.Color := TColor($00A0A0A0); // Серый цвет для неактивной кнопки
end
else
begin
if Themes.ThemeServices.ThemesEnabled then
begin
Canvas.Font.Color := Color; // Цвет текста из текущей темы
end
else
begin
Canvas.Font.Color := Color; // Цвет текста по умолчанию
end;
end;
DrawText(Canvas.Handle, PChar(Caption), Length(Caption), TextRect, Flags);
end;
procedure TMultiLineButton.SetAlignment(const Value: TAlignment);
begin
if FAlignment <> Value then
begin
FAlignment := Value;
Invalidate; // Перерисовываем кнопку
end;
end;
procedure Register;
begin
RegisterComponents('MyComponents', [TMultiLineButton]);
end;
end.
Пояснения к коду:
TMultiLineButton: Наш новый компонент, унаследованный от TButton.
Paint: Переопределенный метод, отвечающий за отрисовку кнопки.
DrawText: Функция WinAPI, позволяющая рисовать текст в указанной области с заданными параметрами.
DT_WORDBREAK: Разрешает перенос слов на новую строку, если текст не помещается в ширину.
DT_CENTER: Центрирует текст по горизонтали.
DT_VCENTER: Центрирует текст по вертикали.
DT_SINGLELINE: Указывает, что текст должен быть отображен в одной строке. Вместе с DT_WORDBREAK обеспечивает многострочность с автоматическим переносом.
ControlStyle := ControlStyle + [csOpaque]: Добавляет стиль csOpaque для предотвращения мерцания при перерисовке.
FAlignment: Приватное поле для хранения выравнивания текста. Можно добавить опции taLeftJustify, taRightJustify для выравнивания по левому и правому краю.
Как использовать:
Сохраните код в файл MultiLineButton.pas.
В Delphi, выберите Component -> Install Component....
Укажите путь к файлу MultiLineButton.pas и нажмите OK.
На палитре компонентов появится новая категория (в данном случае 'MyComponents') с компонентом TMultiLineButton.
Перетащите компонент на форму и задайте свойство Caption (например, "Первая строка#13#10Вторая строка").
Альтернативное решение: Использование TStaticText на TPanel
Вместо создания нового компонента, можно использовать комбинацию TPanel и TStaticText. TPanel будет выступать в роли кнопки, а TStaticText будет отображать многострочный текст с центрированием.
AutoSize := False: Отключает автоматическое изменение размера TStaticText.
WordWrap := True: Включает перенос слов на новую строку.
Parent := Panel1: Устанавливает панель родителем для TStaticText. Это необходимо для правильного отображения и обработки событий.
Align := alClient: Растягивает TStaticText на всю область панели.
Panel1Click: Обработчик события OnClick для панели.
Преимущества и недостатки:
Перерисовка кнопки (DrawText):
Преимущества: Более гибкое решение, позволяет полностью контролировать внешний вид кнопки. Компонент можно легко переиспользовать.
Недостатки: Требует написания кода. Может потребовать дополнительной настройки для корректной работы с различными стилями и темами Windows.
TPanel и TStaticText:
Преимущества: Проще в реализации, не требует создания нового компонента.
Недостатки: Менее гибкое решение. Требует ручной настройки размеров и положения компонентов. Может выглядеть менее "нативно", чем перерисованная кнопка.
Вывод:
Оба решения позволяют создать многострочную кнопку с центрированным текстом в Delphi и Pascal. Выбор зависит от ваших потребностей и предпочтений. Если вам нужна максимальная гибкость и контроль над внешним видом, выбирайте перерисовку кнопки. Если вам нужно быстрое и простое решение, используйте TPanel и TStaticText. В любом случае, Delphi и Pascal предоставляют все необходимые инструменты для создания пользовательских интерфейсов любой сложности.
В Delphi и Pascal можно создать многострочную кнопку с центрированным текстом, перерисовывая стандартный компонент `TButton` с использованием функции `DrawText` или комбинируя компоненты `TPanel` и `TStaticText`.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.