Вопрос, поставленный пользователем, заключается в поиске события, которое позволит отслеживать изменения активного элемента на веб-странице, например, когда пользователь фокусируется на элементе ввода. Пользователь отметил, что он мог бы проверить активный элемент с помощью таймера, но предпочёл бы избежать этого метода.
Контекст и решение проблемы
Используя COM-серверы, такие как SHDocVw или MSHTML, можно отслеживать различные события, связанные с документом в TWebBrowser. Для этого необходимо создать класс, который будет реализовывать интерфейс IDispatch и подключить его к событиям COM-объекта. В примере кода, представленном в контексте, используется класс TEventObject, который позволяет обрабатывать события COM-объектов.
Ключевым моментом является использование IConnectionPoint для подключения к событиям документа. В примере показано, как создать объект TEventObject и подключить его к событию onbeforeeditfocus, которое срабатывает перед получением фокуса элементом ввода.
Пример кода
type
TInvokeEvent = procedure(Sender : TObject; DispIP : Integer) of Object;
TEventObject = class(TInterfacedObject, IDispatch)
private
FOnEvent: TInvokeEvent;
FSinkAllEvents : Boolean;
// ...
end;
type
TForm1 = class(TForm)
// ...
private
procedure AnEvent(Sender : TObject; DispID : Integer);
// ...
public
Doc : IHtmlDocument3;
DocEvent: OleVariant;
// ...
end;
constructor TEventObject.Create(const AnEvent : TInvokeEvent; SinkAll : Boolean);
begin
inherited Create;
FOnEvent := AnEvent;
FSinkAllEvents := SinkAll;
end;
procedure TForm1.AnEvent(Sender : TObject; DispID : Integer);
var
Doc2 : IHTMLDocument2;
E : IHTMLElement;
begin
Doc.QueryInterface(IHTMLDocument2, Doc2);
E := Doc2.activeElement;
// ...
if (E <> Nil) and (E <> PrvActiveElement) and E.isTextEdit then begin
// ...
end;
end;
procedure TForm1.btnLoadClick(Sender: TObject);
var
V : OleVariant;
Doc2 : IHtmlDocument2;
begin
// ...
DocEvent := TEventObject.Create(Self.AnEvent, cbSinkAll.Checked) as IDispatch;
// ...
if cbSinkAll.Checked then begin
// ...
OleCheck((Sink as IConnectionPoint).Advise(DocEvent, Cookie));
end
else
Doc.onbeforeeditfocus := DocEvent;
end;
Важные замечания
При использовании Doc2.ActiveElement для отслеживания изменений активного элемента, следует учитывать, что значение может изменяться несколько раз при входе в один и тот же элемент ввода. Для надёжного обнаружения изменений активного элемента рекомендуется сравнивать атрибуты элемента, например, его имя или ID.
Если необходимо обрабатывать события только для одного элемента, следует назначить объект TEventObject для событий данного элемента (интерфейс HTMLElementEvents2).
В коде можно добавить флаг в конструктор TEventObject.Create для указания, нужно ли обрабатывать все события через IConnectionPoint или только для определённого DispID события.
Заключение
Используя подход, описанный выше, можно отслеживать активные элементы на веб-странице, не прибегая к использованию таймера. Это позволяет более эффективно реагировать на изменения фокуса элементов ввода и других событий, связанных с документом в TWebBrowser.
Контекст вопроса: необходимо отслеживать активные элементы на веб-странице с использованием COM-серверов для реагирования на изменения фокуса, например, на элементах ввода, без использования таймера.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.