Заметки по использованию компонента TWebBrowser в Delphi 7

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

Оставьте комментарий

Ваш адрес email не будет опубликован.