Большой архив статей, книг, документации по программированию, вебдизайну, компьютерной графике, сетям, операционным системам и многому другому
 
<Добавить в Избранное>    <Сделать стартовой>    <Реклама на сайте>    <Контакты>
  Главная Документация Программы Обои   Экспорт RSS E-Books
 
 

   Программирование -> Delphi / Pascal -> Как запустить Internet Explorer или подключиться к нему


Как запустить Internet Explorer или подключиться к нему

В продолжение нескольких статей на Королевстве о работе с компонентом TWebBrowser хочу затронуть пару вопросов работы с Internet Explorer, которые раньше, кажется, не обсуждались. Почти все уже было в ответах Круглого стола, здесь - более подробно. Сначала немного теории

Internet Explorer и его объекты.

На рисунке изображена архитектура Internet Explorer (IE). Для того, чтобы соединить компоненты в целое, используются элементы  ActiveX  и интерфейсы ActiveDocument. Сам исполняемый файл IE мал (у меня на машине IE6 - 89 КБ). Он предоставляет окно и панель инструментов и непосредственно управляет элементом-браузером WebBrowser (ShDocVw.dll). Этот элемент, в свою очередь, управляет компонентом MSHTML.dll, который осуществляет парсинг (разбор) html и его отображение в окне браузера, а также предоставление документа в виде объектной модели. MSHTML, в свою очередь, управляет скриптовыми движками, плагинами и т.д. для отображения своего содержимого. WebBrowser также управляет активными документами, которые могут быть в него загружены, например документами MS Office. Как WebBrowser,  так и MSHTML предоставляют свои интерфейсы для внешних программ. Первый из них может использоваться как элемент ActiveX. Компонент TWebBrowser из палитры компонентов Дельфи - это просто обертка для него.

Практические выводы из написанного следующие: для управления браузером в целом обычно мы используем методы TWebBrowser. Например, для загрузки документа или его печати. Для доступа к элементам документа мы используем интерфейсы, объявленные в MSHTML, основной из которых - IHtmlDocument2, получаемый через свойство TWebBrowser.Document. Еще я бы отметил интерфейс IHtmlWindow, который соответсвует объекту window в javascript. Через него также можно выполнить ряд полезных действий и получить доступ к элементам страницы. Теперь - к более конкретным вопросам.

Создаем и запускаем.

Напомню, что компонент TWebBrowser и интерфейс IWebBrowser2 - основной интерфейс для управления браузером, объявлены в модуле ShDocVw.pas.  Для работы с интерфейсами MSHTML нужно импортировать одноименную библиотеку типов MSHTML.tlb (меню Project->Import Type Library, выбрать Microsoft Html Object Library).

Первая задача: запустить Internet Explorer и открыть в нем документ. Для запуска можно, конечно, воспользоваться функциями CreateProcess или ShellExecute, как для любой другой программы. Однако мы воспользуемся рассматриваемыми методами.

procedure TMainForm.Open(URL: string);
var WB: IWebBrowser2;
begin
  WB:=CoInternetExplorer.Create;
  WB.Visible:=True;
  WB.Navigate(URL, EmptyParam, EmptyParam, EmptyParam, EmptyParam);
  WB:=nil;
end;

Здесь мы запускаем IE и открываем в нем нужный документ с диска или Веб-страницу.  Если не уничтожать переменную WB сразу же, как в примере, то через нее мы имеем доступ к загруженному документу и также можем управлять экземпляром IE. Например, закрыть его. Непосредственно в интерфейсе IWeBrowser2 метода для этого нет. Однако в ShDocVw.pas объявлен интерфейс IWebBrowserApp = interface(IWebBrowser), который содержит метод Quit.  Я не очень понимаю, почему это так, но работает и (WB as IWebBrowserApp).Quit, и просто WB.Quit - закрывается запущенный экземпляр IE.

В модуле ShDocView также определен тип TInternetExplorer. Им тоже можно пользоваться в описанных целях. 

...
type
  TMainForm = class(TForm)
  ....
    procedure MyBeforeNavigate2(Sender: TObject; var pDisp: OleVariant;
              var URL: OleVariant; var Flags: OleVariant;
              var TargetFrameName: OleVariant; var PostData: OleVariant;
              var Headers: OleVariant; var Cancel: OleVariant);
  public
    IE: TInternetExplorer;
  ....
  end;
...
implementation
...
procedure TMainForm.btnIECreateClick(Sender: TObject);
begin
   if IE=nil then
   begin
     IE:=TInternetExplorer.Create(nil);
     IE.Visible:=True;
     IE.OnBeforeNavigate2:=MyBeforeNavigate2;
     IE.Navigate('d:\Internet\update.htm');
   end;
end;

procedure TMainForm.MyBeforeNavigate2(Sender: TObject; var pDisp, URL,
  Flags, TargetFrameName, PostData, Headers, Cancel: OleVariant);
begin
  Memo.Lines.Add(URL);
end;

procedure TMainForm.btnIECloseClick(Sender: TObject);
begin
  IE.Quit;
end;

procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  IE.Free;
end;

В примере запускается Internet Explorer, мы подключаемся к его событию OnBeforeNavigate2 и открывается страница (здесь - с жесткого диска). При дальнейших переходах IE на другие страницы, строка адреса (URL) будет добавляться в элемент Memo. Мы также имеем возможность закрыть этот экземпляр IE из своей программы методом IE.Quit.

Подключаемся.

 Следующая задача - подключиться к уже запущенному экземпляру IE. Если попытаться использовать функцию

GetActiveOleObject('InternetExporer.Application');

то мы получим сообщение об ошибке EOleSysError с сообщением "Операция недоступна". Дело в том, что, видимо из соображений безопасности, IE  как сервер автоматизации, после запуска недоступен внешним программам. Это осуществлено так: при старте любой сервер автоматизации регистрирует себя с помощью функции CoRegisterClassObject. Если установить соответствующий флаг (REGCLS_SINGLEUSE) в этой функции, то объект будет недоступен другим приложениям.

Однако, подключиться к интерфейсу IWebBrowser2 запущенного IE все-таки можно! В том же модуле ShDocVw.pas объявлен интерфейс IShellWindows. Через него можно подключиться ко всем открытым окнам IE и Проводника (Explorer)  Windows. Отличить первые от вторых можно по наличию свойства Document. Для доступа воспользуемся стандартными для коллекций  методом Item(i) и свойством Count.

Здесь я натолкнулся на один подводный камень. Попробуем вывести адреса загруженных страниц во всех экземплярах IE в компонент Memo следующим образом:

//ошибочный код
procedure TMainForm.Button2Click(Sender: TObject);
var Winds: IShellWindows;
    i: integer;
begin
  Winds:=CoShellWindows.Create;
  for i:=0 to Winds.Count-1 do
  if (Winds.Item(i) as IWEbBrowser2).Document <> nil //проверка наличия свойства Document
  then Memo.Lines.Add(((Winds.Item(i) as IWEbBrowser2).Document as IHtmlDocument2).url);
end;

При выполнении этот код вызывал ошибку Interface not supported. Оказалось, что у окон проводника свойство Document может быть не равно nil и они благополучно проходят проверку, но при применении оператора as (Document as IHtmlDocument2) возникает исключение, т.к. получить интерфейс IHtmlDocument2 не удается. Как же правильно провести проверку? Здесь можно воспользоваться тем, что в применении к интерфейсам оператор as является оберткой для вызова метода QueryInterface и при компиляции преобразуется в вызовы указанного метода. Метод IUnknown.QueryInterface я и применил. Если окно является окном IE, то мы получим интерфейс IHtmlDocument2, а функция возвратит результат S_OK. В другом случае результат функции будет иным. Работающий код таков:

procedure TMainForm.Button2Click(Sender: TObject);
var Winds: IShellWindows;
    IEWB: IWebBrowser2;
    i: integer;
    Doc: IHtmlDocument2;
begin
  Memo.Clear;
  Winds:=CoShellWindows.Create;
  for i:=0 to Winds.Count-1 do
  if (Winds.Item(i) as IWEbBrowser2).Document&lt;&gt;nil then
  begin
    IEWB:=Winds.Item(i) as IWEbBrowser2;
    if IEWB.Document.QueryInterface(IhtmlDocument2, Doc)= S_OK
    then Memo.Lines.Add(Doc.url);
  end;
end;

Кстати говоря, окна Проводника тоже поддерживают интерфейс IWebBrowser2, и через него можно определить, какая папка открыта в окне в данный момент.

 Подключившись к окну IE мы далее можем управлять им и получить доступ к загруженному  в него документу. Например, можно закрыть все окна, где адрес страницы не отвечает заданным условиям. Можно также получить доступ к событиям IWebBrowser2. Кроме того, в модуле ShDocVw объявлен интерфейс событий DShellWindowsEvents

DShellWindowsEvents = dispinterface
    ['{FE4106E0-399A-11D0-A48C-00A0C90A8F39}']
    procedure WindowRegistered(lCookie: Integer); dispid 200;
    procedure WindowRevoked(lCookie: Integer); dispid 201;
  end;

Если подключиться к нему, то можно отслеживать события возникновения и уничтожения окон IE и Windows Explorer.

Интерфейс IHtmlWindow2

Получив указатель на интерфейс Document: IHtmlDocument2, мы можем через него получить доступ к интерфейсу IHtmlWindow2, который соответствует объекту window в javasript.

var W: IHtmlWindow2;
W:=Document.ParentWindow;

Не буду описывать все его свойства, их можно найти в MSHTML_TLB.pas, упомяну только процедуру

procedure Alert(const message: WideString);

Эта процедура выводит окно с сообщением в браузере. Другой, на мой взгляд, необычный для Дельфи способ использования этого интерфейса - обращение к именованным объектам страницы. Как известно, в javascript объект window является объектом самого высокого уровня в  иерархии, включающим в себя все остальные. К объектам, имеющим имя, можно обращаться через него - window.myObjectName. Если использовать тип OleVariant, т.е. позднее связывание, то это можно использовать и в Дельфи. Пусть на странице есть сценарий javascript, в котором описана функция showsearch(). Открыв эту страницу в TWebBrowser или в IE, как описано раньше, мы можем вызвать эту функцию.

//WB: TWebBrowser

procedure TMainForm.btnDoSearchClick(Sender: TObject);
var W: OleVariant;
begin
  W:=(WB.Document as IHtmlDocument2).parentWindow;
  W.showsearch;
end;

Автор: Сергей Осколков
Источник: www.delphikingdom.com

Ссылки по теме
Сайт внутри EXE файла
Работа с параллельным портом под Windows
Создание компонент в Delphi
Как работать с реестром в Delphi
Разработка WEB-сервисов в среде Delphi 8
OpenGL и Delphi на практике
 

Компьютерная документация от А до Я - Главная

 

 
Интересное в сети
 
10 новых программ
CodeLobster PHP Edition 3.7.2
WinToFlash 0.7.0008
Free Video to Flash Converter 4.7.24
Total Commander v7.55
aTunes 2.0.1
Process Explorer v12.04
Backup42 v3.0
Predator 2.0.1
FastStone Image Viewer 4.1
Process Lasso 3.70.4
FastStone Image Viewer 4.0
Xion Audio Player 1.0.125
Notepad GNU v.2.2.8.7.7
K-Lite Codec Pack 5.3.0 Full


Наши сервисы
Рассылка новостей. Подпишитесь на рассылку сейчас и вы всегда будете в курсе последних событий в мире информационных технологий.
Новостные информеры. Поставьте наши информеры к себе и у вас на сайте появится дополнительный постоянно обновляемый раздел.
Добавление статей. Если вы являетесь автором статьи или обзора на тему ИТ присылайте материал нам, мы с удовольствием опубликуем его у себя на сайте.
Реклама на сайте. Размещая рекламу у нас, вы получите новых посетителей, которые могут стать вашими клиентами.
 
Это интересно
 

Copyright © CompDoc.Ru
При цитировании и перепечатке ссылка на www.compdoc.ru обязательна. Карта сайта.