вторник, 15 июня 2010 г.

Ловим нажатие ссылки в браузере

Эта статья для тех, кто хочет получить Url нажатой ссылки в WebBrowser, а затем использовать его по своему усмотрению, а не открывать ссылку.

На форуме HiAsm не раз проскальзывали сообщения об этом, меня также просили помочь сделать подобное, и вот я взялся за это дело. Всё оказалось гораздо легче, чем можно предположить. Для этого только немного надо подредактировать код компонента WebBrowser. Если вы читали статьи про InlineCode, то быстро поймёте все действия. Стоит лишь напомнить, что код компонента открывается клавишами Ctrl+F, а конфигаруция - Ctrl+G при выделенном компоненте в HiAsm.

Самое сложное здесь - это отловить нажатие, то есть получить событие по нажатии ссылки. Такого события в компоненте нет. И onMouseDown тоже не подойдёт, потому что при загруженной странице оно не действует.

Но в файле KOLSHDocVw.pas, где описан PKOLWebBrowser (в коде hiWebBrowser есть эта библиотека, только подключается она чуть ниже, чем остальные), есть события OnBeforeNavigate2 и OnNewWindow2. Первое происходит при активации ссылки, которая открывается в этом же окне, второе - когда открывается новое окно.

В коде (hiWebBrowser.pas) этим событиям назначены процедуры-обработчики: OnNavigate и OnNewWindow соответственно. То есть при срабатывании этих процедур можно выполнять какие-то свои действия, связанные со ссылкой. Однако процедуры работают лишь внутри кода и не выведены в компонент в виде события. Это и предстоит сделать.


Делается это очень просто. Добавляем в раздел public (самое начало кода) переменную типа THI_Event. Например:

_event_OnUrlActivate:THI_Event;.

Эта переменная и отвечает за событие в компоненте.

Теперь её нужно задействовать в процедурах OnNavigate и OnNewWindow. Делается это так:

_hi_OnEvent(_event_OnUrlActivate,0);.

На первом месте стоит имя переменной, а на втором - выдаваемые данные. Пусть в случае OnNavigate это будет 0, а OnNewWindow - 1. Это нужно, чтобы отличать, в каком окне открывается ссылка.

Этот код должен стоять в самом начале процедуры, чтобы выполнялся первым. Дело в том, что в этих процедурах происходит проверка верхних точек компонента: Navigate и NewWindow. Если они равны 0, но соответствующее открытие ссылки произведено не будет. А так как написанный нами код стоит первым, то у нас будет возможность узнать, какая ссылка открывается, решить, стоит ли прерывать её загрузку.

После этого сохраняйте код компонента и переходите в его конфигурацию. В секции Methods прописываете такую строку:

*OnUrlActivate=Событие происходит всякий раз при активации гиперссылки в браузере и выдаёт в поток 0, если ссылка должна открыться в этом же окне, и 1 - если в новом.|2|.

OnUrlActivate - это имя точки, оно отличается от имени переменной лишь отсутствием «_event_» (так задумано в HiAsm).

Звёздочка означает, что точка будет находиться на вкладке «Точки» и по умолчанию в компоненте не видна.

Затем следует описание точки, а цифра «2» между вертикальными линиями указывает, что это - событие, а не метод, свойство, точка данных. Сохраняйте конфигурацию и перезагружайте HiAsm. Проверьте - точка должна работать.


Теперь надо как-то реализовать запрет загрузки страницы и полчение адреса ссылки. О запрете на загрузку мы уже говорили - достаточно подать на верхние точки - Navigate и NewWindow - нули, и открытия ссылок не произойдёт. А OnUrlActivate произойдёт в любом случае. Получить адрес можно из строки статуса (событие onStatus). Проверьте, если перыве символы равны «http», то это ссылка по соответствующему протоколу (ещё ссылки могут начинаться с «ftp» и др.).

На всякий случай - вот код и конфигурация компонента (если не хотите самостоятельно изменять код, можете просто установить новый компонент взамен старого).

Вот схема использования.





13 комментариев:

  1. Ну а как тогда сделать если хочешь чтоб браузер сам переходил по определенной ссылке или ее части (поиском этой части ссылки по стнанице)
    Например yandex.ru/yandsearch?text а вводишь для поиска yandsearch?text и нужно сделать переход по полной ссылке.

    ОтветитьУдалить
  2. Это просто. Достаточно выполнить поиск текста ссылки на странице (сам текст страницы можно получить с точки Page) и найденную ссылку передать на doNavigate.

    ОтветитьУдалить
  3. Вот как-то так. Это только пример, потому что надо знать, сколько символов копировать при поиске. В примере копируется 100 символов, в каждом конкретном случае это может быть разное количество - всё зависит от целей использования полученной ссылки.

    ОтветитьУдалить
  4. Можно ли перехватить URL с других браузеров?
    И как, если можно!?

    ОтветитьУдалить
  5. На данный момент есть компонент для получения URL из адресной строки IE6. Наверняка можно и перехватить нажатие по ссылке, но я, к сожалению, с этим незнаком.
    Вот ссылка на компонент.

    ОтветитьУдалить
  6. Как зделать автоматическое нажатие мышки на ссылку?

    ОтветитьУдалить
  7. Вряд ли это получится, потому что надо знать координаты ссылки, а это стандартными средствами не узнать. Поэтому можно просто искать в коде страницы ссылки (нижняя точка Page компонента WebBrowser), вынимать из них адрес и загружать его в этот же компонент - это будет имитацией щелчка.

    ОтветитьУдалить
  8. У мня немного другой вопрос. Как отловить событие нажатия кнопок мыши. Чтобы при клике на левую, правую или среднюю кнопку повесить какие-то действия в программе. Причем независимо от активности окна программы. То есть хоть в трее, хоть свернутое. Знаю что координаты передаются так. Вот хотел узнать как отловить нажатия кнопок мышки.

    ОтветитьУдалить
    Ответы
    1. Add(Keyboard,12144496,315,203)
      {
      Key=4
      link(onReadKey,7643011:doText,[])
      }
      Add(Timer,16439525,259,203)
      {
      Interval=10
      link(onTimer,12144496:doReadKey,[])
      }
      Add(Label,7643011,364,203)
      {
      Left=15
      Top=10
      }

      Св-во Key: 1 - ЛКМ, 2 - ПКМ, 4 - СКМ.

      Удалить
  9. Как можно сделать, что бы программа в браузере сама нажимала на определенную ссылку? Например автоматически нажимала добавить в друзья в вк,с периодичностью к разным людям!

    ОтветитьУдалить
  10. Как можно сделать, что бы программа в браузере сама нажимала на определенную ссылку? Например автоматически нажимала добавить в друзья в вк,с периодичностью к разным людям!

    ОтветитьУдалить