Введение.
Довольно часто современному программисту приходится решать
вопросы, которые связанные с отображением или обработкой информации,
представленной в виде html-ресурсов. Например, на некотором сайте приводятся
ежедневные котировки акций и Вам нужно собирать и обрабатывать статистку за
определенный период времени. Или нужно создать сторожа, который "наблюдает" за
он-лайн прайс-листом конкурента и который должен "предупреждать" об изменениях
цены на определенные позиции. Или нужно написать "паука", который должен
пробегать по некоторому сайту в поисках определенного текста, причем в процессе
пробежки ему нужно заполнить несколько регистрационных форм, а фрагменты текста,
которые он отыскал - выделить определенным цветом. Можно назвать бесконечно
много подобных примеров, но суть их сводится к одному - получение веб-страницы,
извлечение из нее определенной части HTML-кода программными средствами
(парсинг), и, возможно, программное влияние на эту часть кода. Можно,
конечно, используя WinInet.dll, получить доступ к требуемому веб-ресурсу,
а затем с помощью многочисленных строковых функций получить интересующею нас ее
часть. Эта технология вполне работает, но довольно трудоемкая и, в большинстве
случаев далека от элегантности. Другой путь - использование функциональности
Microsoft Internet Explorer.
Internet Explorer (далее -
IE)- это не одна отдельная программа, а целая коллекция
компонент, которые можно использовать при разработке своих приложений. Наиболее
интересными с точки зрения прикладного программиста есть компоненты из
shdocvw.dll и mshtml.dll. Первая DLL содержит
WebBrowser - Microsoft ActiveX control, используемый для визуального
просмотра веб-страниц (рабочая область окна Internet Explorer и есть тот самый
компонент WebBrowser). Вторая DLL содержит синтаксический анализатор HTML кода,
а также средства взаимодействия с отдельными элементами этого кода. По скромному
мнению автора этой статьи - Microsoft Internet Explorer в том виде, в котором он
существует в настоящее время, есть очень удачный пример использования
COM-технологии.
Целью написания этого цикла статей есть демонстрация некоторых приемов
использования функциональности ActiveX-контрола WebBrowser в прикладных
дельфийских программах. Автор не претендует на какое-то новшество в этом
вопросе. Все, что Вы прочитаете далее, уже более-менее подробно описано в
многочисленных веб-ресурсах. То небольшое, что отличает этот материал (по мнению
автора) от аналогичных - это во-первых, ориентация на Delphi, а во вторых -
обобщение личного опыта автора, а не пересказ выдержек с
MSDN.
Также эти статьи есть своего рода благодарность тем людям,
которые довольно сильно помогли мне в то время, когда я делал первые шаги в
направлении, к которому имеет отношение эта статья. Я особенно благодарен
Борису Ладугину за тот "ликбез" в части COM, который он провел со мной в
личной переписке, а также Лене Филиповой и всем местным жителям, советы
которых на "круглом столе" не раз давали толчок для движения в верном
направлении.
Автор рассчитывает на то, что читатель уже имеет
некоторый опыт программирования на Delphi и хотя бы в общих чертах знаком с
COM-технологиями. Хотя автор "разборку" с WebBrowser и COM делал одновременно.
Для тех читателей, которые не знакомы с COM, я постараюсь по ходу дела делать
маленькие отступления, которые конечно, не заменят специализированного
материала, но, надеюсь, дадут хотя бы направление поиска в случае затруднений.
Где в Delphi живет
WebBrowser?
Для любого
зарегистрированного в палитре ActivX-контрола Delphi при импорте создает
класс-оболочку, которая наследуется от TOleControl . Для
начала не станем углубляться в особенности TOleControl и производных от нее
оболочек - ибо сие дело поначалу может не так прояснить, как запутать ситуацию.
Отметим только, что оболочка и сам ActiveX есть несколько разные вещи.
Собственно TOleControl и производные от него оболочки есть не более, чем
средство, которое обеспечивают возможность работы с ActiveX, как с "родными"
VCL-компонентами. Для WebBrowser от IE такой оболочкой есть
TWebBrowser. Если Вы используете Delphi5,
то соответствующий компонент можно отыскать на закладке
"Internet " палитры компонентов. Если Вы работаете с
Delphi4 , то Вам нужно провести импорт соответствующего
ActiveX-контрола. Для этого следует воспользоваться меню "Import ActiveX
Control" и в списке ActiveX выбрать "Microsoft Internet Controls"
(разумеется, у Вас должен быть установлен IE). Компонент-оболочка по умолчанию
устанавливается на закладку "ActiveX" палитры компонентов. Если Вам нужен не
только компонент для отображения Web-страниц, а Вы еще собираетесь проводить
парсинг загруженных страниц, то Вам также следует провести импорт
mshtml.dll. Это можно сделать при помощи меню Import Type Library,
выбрав в списке строчку Microsoft HTML Object Library. Даже
если Вы используете Delphi5, в определенных случаях есть смысл исключить
предустановленный компонент TWebBrowser и провести импорт соответствующих
компонентов самостоятельно. Это может быть необходимым в случае, если Вы желаете
написать приложение, совместимое с IE4, а в Delphi5 модули
mshtml.pas и shdocvw.pas рассчитаны на использование IE5. И как
следствие, довольно много интерфейсов, которые декларируются в соответствующих
модулях, не будут поддерживаться IE4 (к примеру, тот же
IHTMLDocument3). Или наоборот, Вас, возможно, заинтересовала какая-то
особенность новой версии IE, декларация которой отсутствует в mshtml.pas (или
shdocvw.pas) c поставки Delphi. Если Вы решитесь для Delphi5
проводить самостоятельный импорт mshtml.dll через Import Type
Library - уберите галочку с "Generate
Component Wrapper" - в противном случае Delphi создаст никому не нужные
класы-оболочки для интерфейсов и раздует результирующий файл
(mshtml_tbl.pas)до несусветных размеров. Понятно, что если Вы провели
импорт, то в Delphi5 Вам вместо
uses mshtml, shdocvw;
придется использовать
uses mshtml_tbl, shdocvw_tbl;
Если Вы проведете импорт, то Вы наверняка обратите внимание на то, что
помимо упоминаемого TWebBrowser рядышком будет TWebBrowser_V1. Что это за зверь?
Ответ довольно прост - это совместимый с IE3 контрол. В IE4 он введен для
совместимости с теми прикладными программами, которые разрабатывались в расчете
на IE3.
И заканчивая тему экспорта - в библиотеке типов от IE
довольно часто используются имена, которые есть зарезервироваными для Delphi. В
большинстве случаев Delphi справляется с этой задачей (к примеру переименовывая
метод type некоего интерфейса в type_). Но для mshtml.dll от IE5
есть один неприятный момент - там декларируется константа
const
True = $00000001;
И если Вы делаете импорт в Delphi4 - то никакого
переименования не происходит. B как следствие в каком-то безобидном месте
наподобие нижеследующего
implemantation
uses mshtml_tbl;
function IsOk: boolean;
begin
result := true;
// .....end;
получаете сообщение компилятора о несовместимости типов. Что делать?
Или смирится и писать:
result := system.true;
или "научить" Delphi4 обходному маневру: перед импортом mshtml.dll
добавить в DELPHI\BIN\tlibimp.sym две строчки:
True
False
Начало Где искать информацию?
Итак, мы уже разобрались, где наш контрол живет. И как его
импортировать в случае необходимости. Теперь несколько слов об дополнительных
источниках информации. Если Вы работаете с Delphi5, то для начала можно
посмотреть встроенную контекстную справку по TWebBrowser. Но к сожаленью, она
довольно скудна, и описывает (и то поверхностно) только основные свойства
компонента TWebBrowser. Вы ни слова не найдете об возможностях mshtml.dll (а там
запрятаны основные вкусности). Наиболее радикальное решение - приобрести свежее
издание MSDN (или работать с ее онлайновой версией http://msdn.microsoft.com). Но и
при таком решении не все будет гладко - так как MSDN в первую очередь не
учебник, а справочник. И к тому же некоторые аспекты в нем освещены не так
полно, как хотелось бы. Но увы, это пожалуй наиболее полный источник информации,
пробелы в котором можно компенсировать только многочисленными экспериментами и
анализом происходящего. Ответ на конкретный вопрос можно попытаться отыскать в
конференциях. Можно и в "общих", таких как старый, добрый
fido7.delphi.ru, или здесь, на Круглом столе. А
также в "специализированных" - http://www.talk.ru/forum/talk.ru.delphi.webbrowser
и http://www.egroups.com/group/delphi-webbrowser
(последняя - англоязычная). Также рекомендую сайт IE & Delphi
.
Я также надеюсь, что время, затраченное мной на написание, а
Вами на прочтение этой статьи, потрачено не зря. Ну, а если Вы находитесь в
самом начале пути - то можно просмотреть статью Александра ЛозовюкаКак сделать
WebBrowser средствами Delphi 5 (рубрика Hello, world
) ...
Исходники этого "шедевра" (Delphi5) c теми
дополнениями, о которых речь идет ниже, можно взять здесь (3k)
Ну а теперь несколько более подробно. Для начала посмотрим список
методов и свойств TWebBrowser. Здесь следует отличать "обычные" методы и
свойства компонентов VCL, и те, которые "отражают" методы соответствующего
ActiveX элемента. Первые нас не очень интересуют (если читатель имеет хотя бы
небольшой опыт работы с Delphi, то по отношению к чисто VCL-свойствам типа Align , TabOrder ему должно быть все
понятно.) Остановимся на второй группе свойств и методов.Их можно
разделить на две группы - те, которые "отражают" default-интерфейс (в нашем
случае это IWebBrowser2 и те, которые "отражают"
нотификационный интерфейс DWebBrowserEvents2 ).
"Cвязку" между методами интерфейсов и методами класса-оболочки делает
експерт импорта ActiveX, основываясь на особенностях реализации TOleControl. Проанализируйте исходники TOleControl и TWebBrowser - и Вы увидите эти
связки. Это довольно интересное и довольно утомительное занятие ... Лично мне до
конца пройти этот путь не хватило терпения - я остановился на той стадии, когда
начал более-менее понимать основные принципы интеграции ActiveX в VCL. Для
заинтересовавшихся подсказка - обратите в первую очередь внимание на методы TWebBrowser.InitControlData и на TOleControl.GetEventMethod(DispID: TDispID; var Method:
TMethod);
Да, вполне возможно, что читатель не знаком с
основами СOM, и понятия "интерфейс", "нотификационный интерфейс" ему ни о чем не
говорят. Я не знаю, смогу ли я в двух-трех предложениях компенсировать этот
пробел. Но все - же попытаюсь. Если читатель ориентируется в
COM-технологиях, но следующих несколько абзацев можно пропустить.
В завершение разговора об COM, я хотел бы упомянуть о некоторых методах
базового интерфейса IUnnknown, так как во первых, эти методы
присутствуют в любом интерфейсе (вспомним о наследовании деклараций и о том, что
любой интерфейс наследуется от IUnnknown) и во вторых, на
использовании этих методов строится вся идеология работы с COM.
Итак, разрешите представить - QueryInterface. С помощью
этого интерфейса клиент может определить, поддерживает ли COM-обьектом какой
либо другой интерфейс, который известен клиенту, и получить указатель на тот
интерфейс, если он поддерживается объектом. При работе с СOM, это пожалуй самый
популярный вызов. В Dеlphi он иногда вызывается явно, иногда неявно. Неявный
вызов происходит при применении оператора as для интерфейсных
ссылок. Интерфейс IUnnknown также декларирует
два метода интерфейса AddRef и Release,
которые ответственны за подсчет использования COM-обьекта (одно из требований к
COM-обьектам - они должны уметь сами себя уничтожить, если в их услугах более
никто не нуждается). Вам вряд ли придется вызывать эти методы напрямую, так как
Delphi генерирует их вызовы автоматически.
Сейчас, пожалуй, самое время время взглянуть на mshtml.pas
- как видим он почти на 100% состоит из одних деклараций интерфейсов - ведь нам
как клиенту важно знать спецификацию. И совсем не обязательно быть в курсе
особенностей реализации.
И напоследок два слова о нотификационных интерфейсах. Довольно часто
бывает так, что COM-обьект должен сообщать клиенту о некоторых событиях. В таком
случае клиент должен реализовать так называемый нотификационный интерфейс,
который известен серверу и сообщить серверу о том, что им поддерживается этот
интерфейс. Тогда сервер сможет извещать клиента об определенных событиях, делая
вызовы методов нотификационного интерфейса. То есть в этом случае COM-сервер и
клиент как бы меняются ролями.
procedure TForm1.SubmitPostForm;
var
strPostData: string;
Data: Pointer;
URL,
Flags,
TargetFrameName,
PostData, Headers: OleVariant;
begin{ <!-- submit thishtml form:-->
<form method="post" action= "http://127.0.0.1/cgi-bin/register.pl">
<input name= "FIRSTNAME" value="Hans">
<input name= "LASTNAME" value="Gulo">
<inputname="NOTE"value="thatsit">
<inputtype="submit"value="thatsit"></form>}
strPostData := "FIRSTNAME=Hans&LASTNAME=Gulo&NOTE=thats+it";
PostData := VarArrayCreate([0, Length(strPostData) - 1], varByte);
Data := VarArrayLock(PostData);
try
Move(strPostData[1], Data^, Length(strPostData));
finally
VarArrayUnlock(PostData);
end;
URL := "?wurl=127.0.0.1/cgi-bin/register.pl";
Flags := EmptyParam;
TargetFrameName := EmptyParam;
Headers := EmptyParam; // TWebBrowser will see that we are providing// post data and then should automatically fill// this Headers with appropriate value
WebBrowser1.Navigate2(URL, Flags, TargetFrameName, PostData, Headers);
end;
Важным есть property Busy . Если это свойство
активно (равно True), то это свидетельствует о том, что наш АктивИкс еще
не закончил загрузки страницы или выполняет некоторую команду. И может быть, что
он проигнорирует новую
команду. Так что в этом случае лучше подождать, когда это свойство станет равным
false (или когда идет загрузка, то остановить ее можно с помощью метода
Stop).
Теперь несколько слов о событиях, которые сопровождают процесс
загрузки. Они, как отмечалось выше, есть своего "продолжение" соответствующих
методов DWebBrowserEvents2 . Наиболее существенными из них
есть (они возникают для каждого фрейма):
OnBeforeNavigate2
Возникает при попытке начать навигацию. Из параметров наиболее
существенным есть pDisp: IDispatch;. Этот параметр
определяет броузер, который начинает навигацию. Для многофреймового документа
этот броузер может не соответствовать броузеру верхнего уровня. К сожалению,
этот обработчик не вызывается при вызове метода Refresh.
OnNavigateComplete2
Возникает, когда попытка навигации была успешной. Наблюдение за WebBrowser
позволяют сделать предположение, что это событие возникает после того, как с
сервера придет первая порция данных. Документ еще продолжает загружаться.
OnDocumentComplete
Возникает при окончании загрузки в независимости от того, был ли документ
загружен полностью или нет. К сожалению нет простого критерия для определения
того, была ли страница загружена полностью или нет. Как решить єту проблему я
попытаюсь рассказать в следующих статьях этого цикла.
OnNewWindow2
Возникает при попытке открыть документ в новом окне. Если Вы хотите, чтобы
документ был открыт в Вашем экземпляре броузера, то Вам нужно создать свой
экземпляр броузера и параметру ppDisp присвоить
интерфейсную ссылку на этот экземпляр:
procedure TFormSimpleWB.WebBrowser1NewWindow2(Sender: TObject;
var ppDisp: IDispatch; var Cancel: WordBool);
var
newForm: TFormSimpleWB;
begin
newForm := TFormSimpleWB.Create(Application);
newForm.Show;
ppDisp := newForm.WebBrowser1.ControlInterface;
end;
С остальными методами должно быть более-менее понятно из их
названия. Если это не так - можно посмотреть уже упоминаемую статью
Александра Лозовюка.
Но на остаток я хотел бы
немного рассказать еще о двух свойствах, при использование которых
можно немного попасть впросак.
Первым делом это TWebBrowser.Document:IDispatch . Через это свойство можно
получить доступ к интерфейсу IHtmlDocument2.. Далее через
этот интерфейс можно получить доступ к большинству средств по взаимодействию с
загруженным документом. То есть это очень интересное и "нужное" свойство. Но
немного забегая наперед, скажу, что если Вы попытаетесь использовать TWebBrowser.Document:IDispatch, то Вы рано или поздно заметите
довольно странную "утечку" памяти в процессе навигации. В чем же дело? После
анализа ситуации, удалось определить, что для любой интерфейсной ссылки на
документ, которая получена через этот свойство, счетчик использования
"необоснованно" увеличивается на 1 и соответствующий COM-обьект никогда не будет
освобожден. При более детальном изучении нашлась и создательница этой
проблемы - function
TOleControl.GetIDispatchProp(Index: Integer): IDispatch;, через которую и
работает TWebBrowser.Document:IDispatch (я речь веду о
Delphi5, возможно в Delphi4 все нормально, не проверял). Детальный рассказ
об этой ситуации выходит за рамки этой статьи..
К счастью эту проблему легко обойти, использовав для получения
IHtmlDocument2 альтернативные возможности, хотя бы WebBrowser1.ControlInterface.Document .
Также хочется упомянуть о property LocationURL:
WideString; Как утверждается в вышеупомянутой статье Александра
Лозовюка , оно содержит URL ресурса, загруженного в браузер. Того же мнения
придерживается и контекстная справка от Delphi5. Мало того - об этом также
говорится в MSDN .
- во всяком случае так было на момент написания статьи ...
Но это
не совсем так. Дополним наш "шедевр" обработчиком события окончания загрузки
документа:
implementation{$R *.DFM}uses mshtml;
procedure TFormSimpleWB.WebBrowser1DocumentComplete(Sender: TObject;
const pDisp: IDispatch; var URL: OleVariant);
begin//
Caption := WebBrowser1.LocationURL + " || " +
((pDisp as IWebBrowser).Document as IHtmlDocument2).URL;
end;
Обратите внимание на включение модуля mshtml,
который позволяет использовать функциональность mshtml.dll.
Перед
тем как продолжить рассказ я снова вынужден сделать маленькое отступление в
сторону COM.
Обратите внимание, как имея в руках интерфейс
типа IDispatch от броузера (параметр pDisp), который
закончил загрузку документа (это можно подсмотреть в описании события
DocumentComplete в MSDN ), мы посредством "as" получаем интерфейс
типаbIWebBrowser на тот же объект (здесь имеем неявный вызов
QueryInterface). Этот интерфейс при помощи свойства
Documentпbозволяет нам получить интерфейс IHtmlDocument2 к
загруженому документу. И вот в конце-концов через этот интерфейс мы можем
обратится к интересующему нас свойству URL , которое и
возвращает адрес того ресурса, который в действительности загружен в браузер (а
property LocationURL говорит только о том, что мы броузеру
сказали загружать). Да, нам еще не раз придется продиратся через
такие дебри интерфейсов, свойств и запросов. И что наиболее печально - MSDN не
всегда внятно говорит где и от кого можно запросить интересующий нас интерфейс
... Также на первых порах вызывает недоумение тот факт, почему тот же
IWebBrowser.Document есть типа IDispatch, а не хотя бы тот же
IHtmlDocument2. Но это довольно легко понять, если вспомнить во первых,
что WebBrowser позволяет работать с ним разного рода скриптовым языкам, а
во вторых, что интерфейс IDispatch позволяет вызывать свойства и методы
по имени (что собственно и делают скриптовые языки). В принципе, мы бы также
работать в Delphi с WebBrowser в стиле скриптовых языков, но
я сознательно не привожу примеров такого подхода, так как он чреват
возникновением разного рода ошибок, которые можно будет обнаружить только во
время выполнения (и которые отсеиваются на этапе компиляции при использовании
"нормальных" интерфейсов).
Но довольно теории - сделаем маленький
эксперимент: запустим "шедевр" на выполнение и дадим команду навигации на
заведомо отсутствующий ресурс. И что же мы видим:
Взглянем на заголовок окна нашей формы - до символов || есть
значение, которое возвращает property LocationURL , после -
действительный адрес того ресурса, который отображается браузером по окончании
загрузки. Прошу понять меня правильно - этот пример я привел с целью еще
один раз показать, что даже в фирменных материалах бывают неточности ... К
сожаленью, такие неточности нам обходятся иногда очень дорого ...
Простой
парсинг
А теперь пожалуй пришло время очень сильно подружится с
интерфейсами, ибо вся работа с основными вкусностями WebBrowser возможна
только через них. Декларации основных интерфейсов Вы найдете в модулях
mshtml и SHDocVw. Перед тем,
как организовать взаимодействие с составляющими документа, естественно что
нужно этот документ разобрать на составляющие, то есть провести парсинг. Это
довольно просто можно сделать при помощи интерфейса IHtmlDocument2, который предоставляет средства по доступу к
документу, который загружен в соответствующий броузер. Сам же IHtmlDocument2 можно получить, имея "в руках" интерфейс IWebBrowser2 на броузер, в котором этот документ
содержится.
Как уже отмечалось, для документа самого верхнего уровня
это сделать довольно просто:
var
doc: IHtmlDocument2;
.....
if assigned(WebBrowser1.ControlInterface.Document) then
WebBrowser1.ControlInterface.Document.QueryInterface(IHtmlDocument2, doc);
Хотел бы обратить Ваше внимание на условие "if" - это связано с
тем, что если броузер еще не делал навигации, то свойство Document не будет
проинициализировано. Также я надеюсь, Вы помните, почему используется
конструкция WebBrowser1.ControlInterface.Document а не WebBrowser1.Document
Использовать свойства самого IHtmlDocument2 для получения доступа к
фреймам. Понятно, что нужно иметь доступ к IHtmlDocument2 самого верхнего
уровня. Пример реализации этого подхода:
type
TDoerOneDoc = procedure(iDoc: IHtmlDocument2);
procedure DoWithFrames(iDoc: IHtmlDocument2; aDoer: TDoerOneDoc);
{ процедура aDoer будет вызвана для каждого IHtmlDocument2, начиная с главного
и для каждого IHtmlDocument2 с любого уровня вложенности фреймов}var
frames: IHTMLFramesCollection2;
i: integer;
ov1: OleVariant;
iDisp: IDispatch;
IWindow2: IHTMLWindow2;
beginifnot assigned(aDoer) then
Exit;
aDoer(iDoc);
frames := iDoc.frames;
ifnot assigned(frames) then
exit;
if frames.length = 0 then
exit;
for i := 1 to frames.length dobegin
ov1 := i - 1;
try
iDisp := frames.item(ov1);
iDisp.QueryInterface(IHTMLWindow2, IWindow2);
if assigned(IWindow2) then
DoWithFrames(IWindow2.document, aDoer);
except{ ShowMessage("Find error !!!");}end;
end;
end;
Итак, имея в руках IHtmlDocument2 можно
приступить и к парсингу ... Наиболее простой способ для этого -
использование метода All интерфейса IHtmlDocument2, который
позволяет получить список или всех тегов или только тегов определенного вида.
Посмотрим пример для получения списка всех тегов:
procedure TFormSimpleWB.WebBrowser1DocumentComplete(Sender: TObject;
const pDisp: IDispatch; var URL: OleVariant);
var
i: integer;
iDoc: IHtmlDocument2;
iDisp: IDispatch;
iElement: IHTMLElement;
iInputElement: IHTMLInputElement;
S: string;
begin
Memo1.Clear;
iDoc := (pDisp as IWebBrowser).Document as IHtmlDocument2;
for i := 1 to iDoc.All.Get_length dobegin
iDisp := iDoc.Get_all.item(pred(i), 0);
iDisp.QueryInterface(IHTMLElement, iElement);
Str(pred(i), S);
S := S + "";
if assigned(iElement) thenbegin
S := S + "tag=" + iElement.Get_tagName + " ";
iElement.QueryInterface(IHtmlInputElement, iInputElement);
if assigned(iInputElement) thenbegin
S := S + "name=" + iInputElement.Get_name;
end;
Memo1.Lines.Add(S);
end;
end;
end;
Как Вы догадались, здесь тип каждого тега заносится в компонент TMemo.
Также делается попытка определить, есть ли очередной тег элементом ввода
(поддерживает ли он соответствующий интерфейс), и если это так, то делается
попытка получить значение специфического для элементов ввода свойства.
Далее посмотрим пример получения списка тегов определенного типа:
procedure TFormSimpleWB.btPutDataClick(Sender: TObject);
var
iDoc: IHtmlDocument2;
i: integer;
ov: OleVariant;
iDisp: IDispatch;
iColl: IHTMLElementCollection;
iInputElement: IHTMLInputElement;
begin//
WebBrowser1.ControlInterface.Document.QueryInterface(IHtmlDocument2, iDoc);
ifnot assigned(iDoc) thenbegin
ShowMessage(" !!!??? Nothing dowloaded ... ");
Exit;
end;
ov := "INPUT";
IDisp := iDoc.all.tags(ov);
if assigned(IDisp) thenbegin
IDisp.QueryInterface(IHTMLElementCollection, iColl);
if assigned(iColl) thenbeginfor i := 1 to iColl.Get_length dobegin
iDisp := iColl.item(pred(i), 0);
iDisp.QueryInterface(IHTMLInputElement, iInputElement);
if assigned(iInputElement) thenbeginif iInputElement.Get_name = "mn" then
iInputElement.Set_value("Ihor");
if iInputElement.Get_name = "pw" then
iInputElement.Set_value("PASSWORD");
end;
end;
end;
end;
end;
В этом примере получаем список тегов типа "INPUT", а потом для
некоторых тегов (которые отбираем по имени) делается попытка сделать "ввод
данных". Полностью этих два примера (как проект) можно взять здесь (4k).
Ну, для начала пожалуй и хватит. Если у Вас есть вопросы к автору, их
можно задать на http://www.talk.ru/forum/talk.ru.delphi.webbrowser,
ведущим которого является автор этой статьи. Вполне возможно, что Ваши вопросы
подскажут направление продолжения этой статьи.
Если Вас заинтересовала или понравилась информация по разработке на Delph - "Использование функциональности IE или заметки о WebBrowser ", Вы можете поставить закладку в социальной сети или в своём блоге на данную страницу: Так же Вы можете задать вопрос по работе этого модуля или примера через форму обратной связи, в сообщение обязательно указывайте название или ссылку на статью!