Изначально компонент TWebBrowser я стал применять для отображения раздела справки в своих программах. В этом варианте все совсем просто — мы кладем обычные html-файлы в папку и при необходимости вызываем что то типа WebBrowser.Navigate(HelpDir + ‘index.html’);
Ну а сам html уже содержит все что душе угодно, с картинками, перекрестными ссылками и скриптами, доступными InternetExplorer.
Все стало намного интересней, когда я захотел через него отображать информацию из базы данных, а также программно делать изменения на отображаемой странице. Как оказалось и это все возможно.
Вставка CSS решается стандартно для веба, например добавлением перед body:
<style type="text/css"> table {border-collapse: collapse; border-color: #E0E0E0; font-size:x-small;}<br /> td { border: 1px solid; padding: 2px; }<br /></style>
Отображение произвольной html-строки передаваемой в TWebBrowser. Это делается примерно так:
var Doc: Variant; begin if NOT Assigned(wBrowser.Document) then wBrowser.Navigate('about:blank'); Doc := wBrowser.Document; Doc.Clear; Doc.Write('Hello World'); Doc.Close; end;
Перемотка страницы в конец сразу после загрузки. Это оказалось решается добавлением JavaScript в конец страницы (можно после body):
<script>window.scrollTo(0,document.body.scrollHeight);</script>
Выполнение произвольного JavaScript-кода:
var Doc: Variant; begin if NOT Assigned(wBrowser.Document) then wBrowser.Navigate('about:blank'); Doc := wBrowser.Document; Doc.parentWindow.execScript('alert("Hello World");', 'JavaScript');
Вытащить значение атрибута можно примерно так:
function GetElementIdValue(WebBrowser: TWebBrowser; TagName, TagId, TagAttrib: string):string; var Document: IHTMLDocument2; Body: IHTMLElement2; Tags: IHTMLElementCollection; Tag: IHTMLElement; I: Integer; begin Result:=''; if not Supports(WebBrowser.Document, IHTMLDocument2, Document) then raise Exception.Create('Invalid HTML document'); if not Supports(Document.body, IHTMLElement2, Body) then raise Exception.Create('Can''t findelement'); Tags := Body.getElementsByTagName(UpperCase(TagName)); for I := 0 to Pred(Tags.length) do begin Tag:=Tags.item(I, EmptyParam) as IHTMLElement; if Tag.id=TagId then Result := Tag.getAttribute(TagAttrib, 0); end; end; // ПРИМЕР ИСПОЛЬЗОВАНИЯ функции: Result := GetElementIdValue(WebBrowser1, 'input', 'result', 'value');
И наконец самое интересное — как из кода javascript на странице передать событие или информацию в код Delphi? Для этого можно воспользоваться переходом по ссылке внутри HTML и перехватом этого события в обработчике OnBeforeNavigate2, с последующим разбором URL и извлечением из этой строки нужной информации. Естественно не забыть «Cancel := true;» если вам не нужно чтобы браузер перешел по этой ссылке. Лучше для этого метода передачи информации и событий предусмотреть специальный префикс в адресе, по наличию которого определять нужно ли переходить. Пример обработчика:
procedure TMyForm.WebBrowserBeforeNavigate2(Sender: TObject; const pDisp: IDispatch; var URL, Flags, TargetFrameName, PostData, Headers: OleVariant; var Cancel: WordBool); var pre: string; p: Integer; begin p := pos(':', URL); if p > 0 then begin pre := Copy(URL, 1, p-1); if pre = 'event' then begin ShowMessage(Copy(URL, p+1, length(URL)-p)); Cancel := TRUE; end; end; end;
Сам код передающий сюда информацию может быть например таким:
<input id="testButton" type="button" value="test" />
P.S. Минус этого подхода отображения в том что если выполнение происходит скажем на сервере терминалов и там настроены жесткие ограничения то пользователь при инициализации окна содержащего TWebBrowser получит окно Internet Explorer с причинами блокировки, где правда зачастую есть возможность добавить (Add) приложение в исключения.