Изначально компонент 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) приложение в исключения.
