Проблема и решение: обработка гиперссылок в RichEdit-контролах в Delphi
Вопрос, который рассматривается в данной статье, связан с необходимостью обработки гиперссылок в компоненте RichEdit в среде разработки Delphi. Пользователь столкнулся с проблемой, когда гиперссылки в RichEdit отображались как обычный текст, и нажатие на них не приводило к выполнению действия по умолчанию, например, открытию ссылки в браузере.
Предпосылки и контекст:
RichEdit в Delphi предоставляет широкие возможности для форматирования и отображения текста, включая гиперссылки. Однако для корректной работы гиперссылок необходимо выполнить дополнительные настройки.
Шаги к решению проблемы:
Шаг 1: Настройка обработки URL
Для включения автоматического обнаружения URL в RichEdit необходимо использовать функцию EM_AUTOURLDETECT. Это делается с помощью отправки сообщения SendMessage с кодом EM_AUTOURLDETECT и флагом AURL_ENABLEURL.
Шаг 2: Установка маски событий
Для получения уведомлений о клике по гиперссылке необходимо установить маску событий, включающую ENM_LINK, с помощью сообщения EM_SETEVENTMASK.
Шаг 3: Перехват сообщений
Для обработки кликов по гиперссылкам необходимо перехватить сообщение WM_NOTIFY и проверить, что код уведомления равен EN_LINK. В случае подтверждения, следует выполнить необходимые действия, например, открыть ссылку в браузере.
Обсуждаемые проблемы и решения:
В представленном примере кода пользователь обнаружил, что сообщение WM_NOTIFY не доходит до WndProc формы. После дополнительного анализа выяснилось, что проблема заключалась в том, что RichEdit располагался на панели, которая перехватывала сообщения, предназначенные для формы.
Альтернативный ответ: Создание нового класса TRichEdit, наследуемого от ComCtrls.TRichEdit, с переопределением метода CNNotify для обработки уведомлений о клике по ссылке. Также необходимо переопределить метод CreateWnd для повторной настройки обработки URL и уведомлений после создания нового HWND.
Подтвержденное решение и дополнительные уточнения:
Код, предоставленный пользователем, работает корректно. Форма получает уведомления EN_LINK, и при клике по ссылке она открывается в браузере, как ожидается.
Дополнительные улучшения кода:
- Использование функции EM_GETTEXTRANGE для получения текста ссылки вместо использования EM_EXSETSEL и SelText.
- Обработка случаев пересоздания HWND для RichEdit, переопределив метод CreateWnd.
- Переопределение метода CNNotify для обработки уведомлений непосредственно в классе RichEdit, что позволяет избежать необходимости переопределения WndProc родительского контрола.
Пример кода:
unit RichEditUrlTest;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ComCtrls;
type
TRichEdit = class(Vcl.ComCtrls.TRichEdit)
private
procedure CNNotify(var Message: TWMNotify); message CN_NOTIFY;
protected
procedure CreateWnd; override;
end;
...
implementation
{$R *.dfm}
uses
Winapi.ShellAPI, Winapi.RichEdit;
...
procedure TRichEdit.CreateWnd;
var
mask: LResult;
begin
inherited;
mask := SendMessage(Handle, EM_GETEVENTMASK, 0, 0);
SendMessage(Handle, EM_SETEVENTMASK, 0, mask or ENM_LINK);
SendMessage(Handle, EM_AUTOURLDETECT, AURL_ENABLEURL, 0);
end;
...
procedure TRichEdit.CNNotify(var Message: TWMNotify);
type
PENLink = ^TENLink;
var
p: PENLink;
tr: TEXTRANGE;
url: array of Char;
begin
if (Message.NMHdr.code = EN_LINK) then begin
p := PENLink(Message.NMHdr);
if (p.Msg = WM_LBUTTONDOWN) then begin
SetLength(url, p.chrg.cpMax - p.chrg.cpMin + 1);
tr.chrg := p.chrg;
tr.lpstrText := PChar(url);
SendMessage(Handle, EM_GETTEXTRANGE, 0, LPARAM(@tr));
ShellExecute(Handle, nil, PChar(url), 0, 0, SW_SHOWNORMAL);
end;
end;
inherited;
end;
...
procedure TProgCorner.FormCreate(Sender: TObject);
begin
RichEdit1.Text:= 'http://www.example.com';
end;
...
end.
Заключение:
Обработка гиперссылок в RichEdit-контролах в Delphi требует дополнительной настройки, включая включение автоматического обнаружения URL, установку маски событий и перехват сообщений. Важно также обращать внимание на расположение RichEdit относительно других контролов и возможные проблемы с перехватом сообщений. Создание нового класса TRichEdit с переопределением методов CreateWnd и CNNotify позволяет обеспечить корректную обработку гиперссылок в различных сценариях использования.
Контекст данного описания связан с разработкой в среде Delphi, где рассматривается проблема корректной обработки гиперссылок в компоненте RichEdit.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.