В Delphi, задача изменения иконки курсора при наведении на определенное слово в компоненте TLabel может быть решена несколькими способами. Рассмотрим их, начиная с самого простого и переходя к более сложным и гибким решениям.
Простейший способ: Использование свойства Cursor компонента TLabel
Компонент TLabel обладает свойством Cursor, которое позволяет изменить иконку курсора при наведении на весь компонент. Вы можете установить это свойство как во время разработки в инспекторе объектов, так и программно. Доступны предопределенные системные курсоры, такие как стрелка, рука, песочные часы и т.д.
Label1.Cursor := crHandPoint; // Изменяет курсор на "руку" при наведении на Label1
Доступные значения для Cursor:
crDefault
crNone
crArrow
crCross
crIBeam
crSize
crSizeNES
crSizeNS
crSizeNWSE
crSizeWE
crUpArrow
crHourGlass
crDrag
crNoDrop
crHSplit
crVSplit
crMultiDrag
crSQLWait
crNo
crAppStart
crHelp
crHandPoint
crSizeAll
Ограничения:
Этот метод изменяет курсор для всего компонента TLabel. Если вам нужно изменить курсор только при наведении на определенное слово, этот способ не подходит.
Более сложный способ: Разбиение TLabel на несколько и использование TLayout
Если вам нужно изменить курсор только при наведении на определенное слово в TLabel, то необходимо разбить текст на части и поместить каждое слово (или группу слов) в отдельный компонент TLabel. Для удобного расположения этих компонентов можно использовать компонент TLayout.
Создайте TLayout на форме.
Добавьте несколько TLabel внутрь TLayout. Каждый TLabel будет содержать отдельное слово или фразу.
Установите свойство Cursor для того TLabel, над которым нужно изменить курсор.
Настройте расположение TLabel в TLayout, чтобы они выглядели как единый текст. Можно использовать свойства Align, Margins и Padding для точной настройки.
// Пример кода (частичный, нужно создать компоненты в дизайнере или коде)
procedure TForm1.FormCreate(Sender: TObject);
begin
Label1.Parent := Layout1;
Label2.Parent := Layout1;
Label3.Parent := Layout1;
Label1.Text := 'Это ';
Label2.Text := 'слово';
Label3.Text := ' с другим курсором.';
Label2.Cursor := crHandPoint; // Курсор "рука" только при наведении на Label2
end;
Преимущества:
Позволяет точно контролировать, когда и какой курсор отображается.
Недостатки:
Требует больше работы по созданию и расположению компонентов.
Усложняет изменение текста, так как нужно менять текст в нескольких компонентах.
Альтернативное решение: Использование рисования на канве и обработка событий мыши
Более сложный, но и более гибкий подход - это рисовать текст TLabel самостоятельно на канве и отслеживать координаты мыши. В этом случае вам потребуется:
Создать свой компонент (наследник от TGraphicControl или TCustomControl).
В обработчике OnPaint рисовать текст на канве.
В обработчиках событий мыши (OnMouseMove, OnMouseEnter, OnMouseLeave) определять, находится ли курсор над нужным словом, и менять иконку курсора соответственно.
Этот подход требует более глубоких знаний о рисовании на канве и обработке событий мыши, но позволяет реализовать практически любой сценарий изменения курсора.
type
TMyLabel = class(TCustomControl)
private
FText: string;
FWordRect: TRect; // Прямоугольник, занимаемый "ключевым" словом
procedure CalculateWordRect;
protected
procedure Paint; override;
procedure MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
property Text: string read FText write FText;
end;
implementation
constructor TMyLabel.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
ControlStyle := ControlStyle + [csOpaque, csDoubleClicks, csReplicatable];
Width := 200;
Height := 20;
FText := 'Это ключевое слово.';
CalculateWordRect;
end;
destructor TMyLabel.Destroy;
begin
inherited Destroy;
end;
procedure TMyLabel.Paint;
var
TextRect: TRect;
begin
Canvas.Font := Font;
Canvas.Brush.Color := Color;
Canvas.FillRect(ClientRect);
TextRect := ClientRect;
DrawText(Canvas.Handle, PChar(FText), Length(FText), TextRect, DT_LEFT or DT_SINGLELINE or DT_VCENTER);
end;
procedure TMyLabel.CalculateWordRect;
var
TextRect: TRect;
WordStart: Integer;
begin
// Находим позицию "ключевого" слова (например, "ключевое")
WordStart := Pos('ключевое', FText);
if WordStart > 0 then
begin
TextRect := ClientRect;
Canvas.Font := Font;
// Вычисляем прямоугольник, занимаемый словом
TextRect.Left := Canvas.TextWidth(Copy(FText, 1, WordStart - 1)); // Смещение от начала
TextRect.Right := TextRect.Left + Canvas.TextWidth('ключевое'); // Ширина слова
FWordRect := TextRect;
end else
begin
FWordRect := Rect(0, 0, 0, 0); // Не найдено
end;
end;
procedure TMyLabel.MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
if PtInRect(FWordRect, Point(X, Y)) then
begin
Cursor := crHandPoint;
end else
begin
Cursor := crDefault;
end;
end;
Важные замечания:
При использовании любого из этих методов, убедитесь, что иконка курсора хорошо видна на фоне компонента TLabel.
Для пользовательских иконок курсора (не из стандартного набора) вам потребуется загрузить иконку из файла и использовать API Windows для установки курсора.
При использовании рисования на канве, необходимо учитывать изменение шрифта и размера текста, чтобы правильно рассчитывать координаты слов.
В заключение, выбор метода зависит от сложности задачи и требуемой гибкости. Для простых случаев достаточно свойства Cursor компонента TLabel. Для более сложных задач потребуется разбиение TLabel на несколько компонентов или использование рисования на канве с обработкой событий мыши.
Контекст описывает способы изменения иконки курсора при наведении на определенное слово в компоненте TLabel в Delphi, включая использование свойства Cursor, разбиение TLabel на несколько компонентов и рисование на канве с обработкой событий мыши.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS