Суббота, 18.05.2024
Королевство Delphi
Главное меню
Статьи
Наш опрос
Нашли свой исходник?
Всего ответов: 94
Статистика
Онлайн всего: 1
Гостей: 1
Пользователей: 0
Форма входа
Главная » Статьи » Сеть-интернет » Разные

Использование компонента TWebBrowser

Базовые операции

Тонкая настройка

Доступ к документной модели TWebBrowser

Во многих современных программах необходимо работать с данными в формате HTML. В качестве средства для просмотра таких данных в Delphi применяется компонент TWebBrowser, который использует элемент управления ActiveX WebBrowser, входящий в состав Microsoft Internet Explorer. Таким образом, этот компонент имеется на любом компьютере, на котором установлен Internet Explorer. Все последние версии Windows содержат TWebBrowser в своем составе и без него практически неработоспособны.

Базовые операции

Для того чтобы использовать TWebBrowser в своей программе, следует разместить на форме соответствующий компонент, имеющийся на закладке Internet. Затем, для отображения в нем страницы HTML, необходимо вызвать его метод Navigate:

procedure TForm1.Button1Click(Sender: TObject);
var
 Flags, TargetFrameName, PostData, Headers: OleVariant;
begin
 WebBrowser1.Navigate(‘http://www.borland.com’, Flags, 
 TargetFrameName, PostData, Headers);
end;

Рассмотрим подробнее параметры, передаваемые в метод Navigate.

Первым параметром является строка с URL, указывающим адрес, из которого должна осуществляться загрузка. Поддерживаются все протоколы, доступные в IE, например file:// — загрузка файла, res:// — загрузка из ресурса.

Остальные параметры не являются обязательными и служат для передачи дополнительной информации (табл. 1).

Таблица 1

Flags Целое число, представляющее собой битовую маску из следующих флагов: 1 — открыть ресурс в новом окне; 2 — не добавлять страницу в историю просмотренных; 4 — не загружать страницу из кэша; 8 — не сохранять страницу в кэше.
TargetFrameName Задает имя фрейма, в который будет загружена страница.
PostData Задает данные для запроса с сервера методом HTTP POST. Если этот параметр пустой, используется метод GET.
Headers Задает дополнительные заголовки HTTP.

Наиболее интересным является параметр PostData, позволяющий передать на Web-сервер данные, полученные в результате заполнения формы, если этот сервер требует HTTP — транзакции POST. Так, следующий фрагмент кода передает на сервер имя пользователя и пароль, заполненные в форме Delphi:

var
 LoginDialog: TLoginDialog;
 Flags, TargetFrameName, PostData, Headers: OleVariant;
 S: String;

...
with TLoginDialog.Create(Application) do 
try
 if ShowModal = mrOk then 
 begin
 S := Format(‘UserName=%s&Password=%s’, _
 [Edit1.Text, Edit2.Text]);
 PostData := VarArrayCreate([1, _
 Length(S) + 1], varByte);
 System.Move(S[1], VarArrayLock(PostData)^, _
 Length(S) + 1);
 VarArrayUnlock(PostData);
 Headers := 
 ‘Content-Type: application/x-www-form-urlencoded’#10#13;
 WebBrowser1.Navigate(‘http://intranetserver/secretpage’, Flags,
 TargetFrameName, PostData, Headers);
 end;
finally
 Free;
end;

Например, на Web-сервере этот запрос может быть обработан, следующим ASP-скриптом:

Dim sConnect
 Dim sUserName
 Dim sPassword

 sUserName = Request.Form("User”)
 sPassword = Request.Form("Pass”)

 sConnect = "Provider=SQLOLEDB.1;Persist Security Info=True;” & _
 "Initial Catalog=Katren;Data Source=DBSERVER;” & _
 "Password=” & sPassword & _
 ";User ID=” & sUserName
 Session("ConnectString”) = sConnect

После того как данные получены, необходимо предоставить пользователю возможность работы с ними. Многие функции TWebBrowser доступны через метод ExecWB, предоставляющий простой способ обращения к интерфейсу IOleCommandTarget. Этот метод имеет такой вид:

procedure TWebBrowser.ExecWB(
 cmdID: OLECMDID; // Идентификатор команды
 cmdexecopt: OLECMDEXECOPT; // Параметры выполнения
 var pvaIn, // Дополнительные параметры,
 pvaOut: OleVariant // зависящие от команды
); safecall;

CmdID может быть одной из констант OLECMDID, определенных в файле ShDocVw.pas.

Параметр cmdexecopt может принимать одно из четырех значений, приведенных в табл. 2.

Таблица 2

OLECMDEXECOPT_DODEFAULT Выполнить команду с настройками по умолчанию.
OLECMDEXECOPT_PROMPTUSER Запросить у пользователя настройки для выполнения команды (например, при печати — вывести диалог Print Setup).
OLECMDEXECOPT_DONTPROMPTUSER Выполнить команду, не запрашивая пользователя.
OLECMDEXECOPT_SHOWHELP Вывести справку о команде.

Параметры pvaIn и pvaOut являются дополнительными и зависят от конкретной команды.

Имеется возможность запросить у TWebBrowser доступность той или иной команды при помощи функции:

function TWebBrowser.QueryStatusWB(
 cmdID: OLECMDID // Идентификатор команды
): OLECMDF; safecall;

Функция возвращает битовую маску из значений, приведенных в табл. 3.

Таблица 3

OLECMDF_SUPPORTED Команда поддерживается.
OLECMDF_ENABLED Команда поддерживается и разрешена.
OLECMDF_LATCHED Команда является переключателем и сейчас включена.
OLECMDF_NINCHED Зарезервировано.

Следовательно, можно настраивать интерфейс в зависимости от поддерживаемых текущей версией TWebBrowser возможностей:

var
 Flags: OLECMDF;

...

Flags := WebBrowser1.QueryStatusWB(OLECMDID_COPY);
ActionCopy.Visible := (Flags and OLECMDF_SUPPORTED) = 
 OLECMDF_SUPPORTED;
ActionCopy.Enabled := (Flags and OLECMDF_ENABLED) = 
 OLECMDF_ENABLED;

Для печати содержимого TWebBrowser служит команда OLECMDID_PRINT. Метод печати может выглядеть, в частности, следующим образом:

procedure TForm1.ActionPrintExecute(Sender: TObject);
var
 A, B: OleVariant;
 UserAction: Cardinal;
begin
 if Sender = ActionPrintWithSetup then
 UserAction := OLECMDEXECOPT_PROMPTUSER
 else
 UserAction := OLECMDEXECOPT_DONTPROMPTUSER;
 try
 WebBrowser1.ExecWB(OLECMDID_PRINT, UserAction, A, B);
 except
 end;
end;

Блок try … except … end необходим по той причине, что TWebBrowser при выполнении любой команды при помощи ExecWB генерирует исключение EOleException с кодом:

-2147221248 ($80040100) Trying to revoke _
 a drop target that has not been registered.

Начиная с Internet Explorer 5 документированы дополнительные команды, поддерживаемые через интерфейс IOleCommandTarget. Они существенно расширяют возможности по управлению компонентом, однако недоступны либо не документированы в версии 4. Это создает определенные сложности при программировании. Так, чтобы организовать поиск внутри загруженной страницы, необходим следующий код:

const
 // Недокументированная константа
 CGID_IE4: TGUID = ‘{ed016940-bd5b-11cf-ba4e-00c04fd70816}’;
 // Документировано в IE5 SDK
 CGID_MSHTML: TGUID = ‘{DE4BA900-59CA-11CF-9592-444553540000}’;
 IDM_FIND = 67;

procedure TForm1.ActionFindExecute(Sender: TObject);
var
 A, B: OleVariant;
 Target: IOleCommandTarget;
 OleCmd: TOLECMD;
begin
 // Получаем интерфейс IOleCommandTarget
 Target := wbMain.Document as IOLECommandtarget;
 with OleCmd do
 begin
 cmdId := IDM_FIND;
 cmdf := 0;
 end;
 // Запрашиваем, поддерживается ли команда
 Target.QueryStatus(@CGID_MSHTML, 1, @OleCmd, NIL);
 if (OleCmd.cmdf and OLECMDF_SUPPORTED) = OLECMDF_SUPPORTED then
 // Да, у нас IE5+, поэтому вызываем документированным способом
 Target.Exec(@CGID_MSHTML, IDM_FIND, 
 OLECMDEXECOPT_DODEFAULT, A, B)
 else
 // Нет, у нас IE4, поэтому вызываем недокументированным способом
 Target.Exec(@CGID_IE4, 1, OLECMDEXECOPT_DODEFAULT, A, B);
end;

Использование недокументированного вызова в данном случае оправданно, так как в версии 4 этот вызов уже не будет изменяться, а в версии 5 мы обнаруживаем и используем документированный метод. В то же время IE4 пока еще достаточно распространен, так что будет нецелесообразно полностью лишать программу возможности поиска на таких компьютерах.

Тонкая настройка

Если требуется более тонкая настройка компонента, то необходимо реализовать интерфейс IDocHostUIHandler, позволяющий программисту взять под контроль поведение TWebBrowser.

Интерфейс объявлен как:

type
 TDocHostInfo = packed record
 cbSize: ULONG;
 dwFlags: DWORD;
 dwDoubleClick: DWORD;
 end;

const
 DOCHOSTUIFLAG_DIALOG = 1;
 DOCHOSTUIFLAG_DISABLE_HELP_MENU = 2;
 DOCHOSTUIFLAG_NO3DBORDER = 4;
 DOCHOSTUIFLAG_SCROLL_NO = 8;
 DOCHOSTUIFLAG_DISABLE_SCRIPT_INACTIVE = 16;
 DOCHOSTUIFLAG_OPENNEWWIN = 32;
 DOCHOSTUIFLAG_DISABLE_OFFSCREEN = 64;
 DOCHOSTUIFLAG_FLAT_SCROLLBAR = 128;
 DOCHOSTUIFLAG_DIV_BLOCKDEFAULT = 256;
 DOCHOSTUIFLAG_ACTIVATE_CLIENTHIT_ONLY = 512;

const
 DOCHOSTUIDBLCLK_DEFAULT = 0;
 DOCHOSTUIDBLCLK_SHOWPROPERTIES = 1;
 DOCHOSTUIDBLCLK_SHOWCODE = 2;

type
 IDocHostUIHandler = interface(IUnknown)
 [‘{bd3f23c0-d43e-11cf-893b-00aa00bdce1a}’]
 function ShowContextMenu(const dwID: DWORD; const ppt: PPOINT;
 const pcmdtReserved: IUnknown; 
 const pdispReserved: IDispatch): HRESULT; stdcall;
 function GetHostInfo(var pInfo: TDOCHOSTUIINFO): HRESULT; 
 stdcall;
 function ShowUI(const dwID: DWORD; 
 const pActiveObject: IOleInPlaceActiveObject;
 const pCommandTarget: IOleCommandTarget; 
 const pFrame: IOleInPlaceFrame;
 const pDoc: IOleInPlaceUIWindow): HRESULT; stdcall;
 function HideUI: HRESULT; stdcall;
 function UpdateUI: HRESULT; stdcall;
 function EnableModeless(const fEnable: BOOL): HRESULT; stdcall;
 function OnDocWindowActivate(const fActivate: BOOL): HRESULT; 
 stdcall;
 function OnFrameWindowActivate(const fActivate: BOOL): HRESULT; 
 stdcall;
 function ResizeBorder(const prcBorder: PRECT;
 const pUIWindow: IOleInPlaceUIWindow;
 const fRameWindow: BOOL): HRESULT; stdcall;
 function TranslateAccelerator(const lpMsg: PMSG; 
 const pguidCmdGroup: PGUID;
 const nCmdID: DWORD): HRESULT; stdcall;
 function GetOptionKeyPath(var pchKey: POLESTR; 
 const dw: DWORD): HRESULT; stdcall;
 function GetDropTarget(const pDropTarget: IDropTarget;
 out ppDropTarget: IDropTarget): HRESULT; stdcall;
 function GetExternal(out ppDispatch: IDispatch): HRESULT; 
 stdcall;
 function TranslateUrl(const dwTranslate: DWORD; 
 const pchURLIn: POLESTR; var ppchURLOut: POLESTR): HRESULT;
 stdcall;
 function FilterDataObject(const pDO: IDataObject;
 out ppDORet: IDataObject): HRESULT; stdcall;
 end; 

Наследник TWebBrowser, реализующий этот интерфейс, должен быть объявлен так:

type
 TCustomizedWebBrowser = class(TWebBrowser, IDocHostUIHandler)
 // Реализация методов IDocHostUIHandler
 end;

А теперь рассмотрим наиболее интересные, с точки зрения программиста, методы интерфейса IDocHostUIHandler.

Начнем с метода ShowContextMenu:

function ShowContextMenu(const dwID: DWORD; const ppt: PPOINT;
 const pcmdtReserved: IUnknown; 
 const pdispReserved: IDispatch): HRESULT;

Эта функция вызывается в том случае, когда TWebBrowser должен показать контекстное меню. Если вы отображаете собственное меню или хотите подавить меню, то функция должна вернуть S_OK, а если меню должен показать TWebBrowser — то S_FALSE.

В функцию передаются следующие параметры:

1. DwID — идентификатор меню, который может принимать одно из следующих значений:

const
 CONTEXT_MENU_DEFAULT = 0;
 CONTEXT_MENU_IMAGE = 1;
 CONTEXT_MENU_CONTROL = 2;
 CONTEXT_MENU_TABLE = 3;
 CONTEXT_MENU_DEBUG = 4;
 CONTEXT_MENU_1DSELECT = 5;
 CONTEXT_MENU_ANCHOR = 6;
 CONTEXT_MENU_IMGDYNSRC = 7;

В зависимости от значения идентификатора вы можете вывести подходящее меню.

2. ppt — координаты, в которых должно быть показано меню.

3. pcmdtReserved — интерфейс IOleCommandTarget, позволяющий запросить состояние команд и их выполнение.

4. pdispReserved — интерфейс IDispatch объекта, для которого вызывается меню.

Простейшая реализация этого метода может выглядеть следующим образом:

function TcustomizedWebBrowser.ShowContextMenu(const dwID: DWORD;
 const ppt: PPOINT; const pcmdtReserved: IUnknown; 
 const pdispReserved: IDispatch): HRESULT;
begin
 // Предполагаем, что поле FPopupMenu хранит ссылку
 // на компонент TPopupMenu
 if Assigned(FPopupMenu) then begin
 pmContext.Popup(ppt.X, ppt.Y);
 Result := S_OK;
 end 
 else Result := S_FALSE;
end;

Для полного запрета контекстного меню метод должен всегда возвращать S_OK.

Следующий метод, который мы рассмотрим — GetHostInfo:

unction GetHostInfo(var pInfo: TDocHostInfo): HRESULT; stdcall;

Приложение может заполнить структуру pInfo, определенную как:

TDocHostInfo = packed record
 cbSize: ULONG;
 dwFlags: DWORD;
 dwDoubleClick: DWORD;
end;

Здесь dwFlags — битовая маска из следующих флагов, приведенных в табл. 4, а dwDoubleClick задает реакцию на двойной щелчок мышью и может принимать одно из значений, приведенных в табл. 5.

Таблица 4

DOCHOSTUIFLAG_DIALOG Запрещает выделение текста в форме.
DOCHOSTUIFLAG_DISABLE_HELP_MENU Запрещает контекстное меню.
DOCHOSTUIFLAG_NO3DBORDER Подавляет вывод трехмерной рамки вокруг компонента.
DOCHOSTUIFLAG_SCROLL_NO Отключает полосы прокрутки.
DOCHOSTUIFLAG_DISABLE_SCRIPT_INACTIVE Запрещает исполнение скриптов.
DOCHOSTUIFLAG_OPENNEWWIN Открывает ссылки в новых окнах.
DOCHOSTUIFLAG_FLAT_SCROLLBAR Использует плоский стиль для полос прокрутки.
DOCHOSTUIFLAG_DIV_BLOCKDEFAULT При вводе возврата каретки в режиме редактирования будет использоваться тэг
вместо

.

DOCHOSTUIFLAG_ACTIVATE_CLIENTHIT_ONLY Компонент получает фокус только при щелчке мышью в клиентской области окна, а при щелчке в неклиентской области (например, на полосе прокрутке) — не получает.

Таблица 5

DOCHOSTUIDBLCLK_DEFAULT Выполнять действие по умолчанию.
DOCHOSTUIDBLCLK_SHOWPROPERTIES Показывать окно свойств страницы.
DOCHOSTUIDBLCLK_SHOWCODE DOCHOSTUIFLAG_DIALOG Показывать HTML-код страницы.

Метод должен вернуть S_OK или код ошибки OLE.

Например, чтобы создать окно с плоскими полосами прокрутки и без трехмерной рамки, необходимо реализовать этот метод следующим образом:

function TCustomizedWebBrowser.GetHostInfo(
 var pInfo: TDocHostInfo): HRESULT; stdcall; 
begin
 with pInfo do
 dwFlags := dwFlags or DOCHOSTUIFLAG_NO3DBORDER or 
 DOCHOSTUIFLAG_FLAT_SCROLLBAR;
 Result := S_OK;
end;

Метод

function TranslateAccelerator(const lpMsg: TMsg;
 const pguidCmdGroup: TGUID; nCmdID: DWORD): HRESULT; stdcall;

позволяет перехватить исполнение команд и обработку «горячих» клавиш и заменить ее на свою.

Метод

function GetOptionKeyPath(var pchKey: PWideChar; 
 dwReserved: DWORD): HRESULT; stdcall;

позволяет задать путь в реестре, который TWebBrowser будет использовать для хранения настроек. Это дает возможность, в частности, сделать используемый в программе компонент независимым от текущих настроек Internet Explorer.

Путь должен содержаться в ключе реестра HKEY_CURRENT_USER.

Этот метод должен выделить память под строку функцией CoTackMemAlloc. Даже в случае ошибки параметр pchKey нужно инициализировать значением NIL или адресом строки. Метод возвращает S_OK в случае успеха, а в противном случае — S_FALSE.

Типичная реализация этого метода может выглядеть так:

function TCustomizedWebBrowser.GetOptionKeyPath(
 var pchKey: PWideChar; dwReserved: DWORD): HRESULT;
var
 ResultLen: Integer;
begin
 Result := S_FALSE;
 // В поле TCustomizedWebBrowser.FOptionKeyPath: String 
 // хранится путь к настройкам
 if Length(FOptionKeyPath) > 0 then
 begin
 // Получаем длину строки UNICODE
 ResultLen := MultiByteToWideChar(CP_ACP, 0, 
 PChar(FOptionKeyPath), -1, NIL, 0);
 // Выделяем память под буфер
 pchKey := CoTaskMemAlloc(ResultLen * SizeOf(WideChar));
 // Если выделение успешно, копируем строку в буфер
 if Assigned(pchKey) then 
 begin
 MultiByteToWideChar(CP_ACP, 0, PChar(FOptionKeyPath), -1, 
 pchKey, ResultLen);
 Result := S_OK;
 end;
 end else begin
 // Свойство не задано — инициализируем параметр в NIL
 pchKey := NIL;
 end;
end;

Существует ряд настроек, которые, несмотря на наличие обработчика GetOptionKeyPath, в любом случае берут из стандартных параметров Internet Explorer. Наиболее важными из них являются колонтитулы, используемые при печати. В версиях Internet Explorer до 5.5 включительно единственным способом изменить (или подавить) колонтитулы является запись новых значений в ключ реестра:

HKCU\Software\Microsoft\Internet Explorer\PageSetup 

перед печатью и восстановление их после печати.

А теперь поговорим о методе

function GetExternal(var ppDispatch: IDispatch): HRESULT; stdcall;

Он позволяет вернуть указатель на реализованный в вашем приложении интерфейс IDispatch, который будет доступен для скриптов в TWebBrowser. Если вы не реализуете этот интерфейс, то параметр ppDispatch должен быть установлен равным NIL. Метод возвращает S_OK в случае успеха или код ошибки OLE в случае ошибки.

Методы этого интерфейса доступны из скриптов, которые выполняют в TWebBrowser следующим образом:

window.external.MethodName

Реализовать IDispatch можно, например, при помощи класса TAutoObject.

Метод TranslateURL позволяет изменить URL, по которому осуществляется загрузка страницы.

function TranslateURL(dwTranslate: DWORD; pchURLIn: PWideChar;
 var ppchURLOut: PWideChar): HRESULT; stdcall;

pchURLIn указывает на строку, содержащую исходный URL. Если ваше приложение осуществляет трансляцию, то оно должно выделить память под новое значение, используя функцию CoTaskMemAlloc, заполнить буфер новым значением URL и вернуть S_OK.

В противном случае вы должны присвоить ppchURLOut значение NIL и вернуть S_FALSE. При возникновении ошибки метод должен вернуть OLE-код ошибки.

Обработчик вызывается только при интерактивном переходе по ссылке из TWebBrowser и не вызывается при переходе с помощью метода Navigate.

Доступ к документной модели TWebBrowser

В Internet Explorer реализовано расширение HTML, называемое Dynamic HTML (DHTML). Эта модель представляет все элементы HTML-документа в виде набора коллекций объектов, доступных для изменения. Скрипты, встроенные в страницы и приложения и имеющие доступ к этим коллекциям, могут находить и изменять их элементы, а также добавлять новые, причем изменения будут немедленно отражены в окне TWebBrowser. Иерархическое объектное представление HTML-объектов называется DOM (Document Object Model).

Программисту DOM в элементе управления IE ActiveX доступна в виде набора COM-интерфейсов. Отправной точкой для доступа к ней служит свойство:

property Document: IDispatch;

Это свойство обеспечивает доступ к интерфейсу IHtmlDocument2, позволяющему работать с содержимым документа. Для получения интерфейса необходимо запросить его при помощи оператора as:

var
 Document: IHtmlDocument2;
...

Document := WebBrowser.Document as IHtmlDocument2;

Документ в DOM представляет собой набор коллекций элементов. Для доступа к коллекции служит интерфейс IHtmlElementCollection, а к элементу коллекции — IHtmlElement. Следующий пример выводит все тэги, имеющиеся в текущем документе и текст внутри тэгов:

procedure TForm1.Button1Click(Sender: TObject);
var
 HtmlDocument: IHtmlDocument2;
 HtmlCollection: IHtmlElementCollection;
 HtmlElement: IHtmlElement;
 I: Integer;
begin
 Memo1.Lines.Clear;
 HtmlDocument := WebBrowser.Document as IHtmlDocument2;
 HtmlCollection := HtmlDocument.All;
 for I := 0 to HtmlCollection.Length - 1 do begin
 HtmlElement := HtmlCollection.Item(i, 0) as IHtmlElement;
 Memo1.Lines.Add(HtmlElement.TagName + ‘ ‘ +
 HtmlElement.InnerText);
end;

Кроме того, возможно динамическое создание документов в памяти, без необходимости записи их на диск и вызова метода Navigate с протоколом ‘file://’

Проиллюстрируем работу с документной модели TWebBrowser на конкретном примере. Расположим на форме компоненты TWebBrowser, TMemo и три TButton, а потом создадим следующие обработчики событий:

uses MSHTML, ActiveX;


procedure TForm1.FormCreate(Sender: TObject);
begin
 // Инициализируем пустой документ в TWebBrowser
 WebBrowser1.Navigate(‘about:blank’);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 Document: IHTMLDocument2;
 V: OleVariant;
begin
 // Этот метод переписывает в TWebBrowser HTML-
 // документ из TMemo
 Document := WebBrowser1.Document as IHtmlDocument2;
 V := VarArrayCreate([0, 0], varVariant);
 V[0] := Memo1.Text;
 Document.Write(PSafeArray(TVarData(v).VArray));
 Document.Close;
end;

procedure TForm1.Button3Click(Sender: TObject);
var
 Document: IHTMLDocument2;
 Collection: IHTMLElementCollection;
 Element: IHTMLElement;
 I: Integer;
begin
 // Этот метод модифицирует текст документа при помощи DHTML
 Document := WebBrowser1.Document as IHtmlDocument2;
 Collection := Document.all;
 Collection := Collection.Tags(‘BODY’) as IHTMLElementCollection;
 Element := Collection.Item(NULL, 0) as IHTMLElement;
 Element.InnerText := ‘Modifyed by DHTML’;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
 Document: IHTMLDocument2;
begin
 // Этот метод позволяет просмотреть в TMemo код HTML
 // документа из TWebBrowser
 Document := WebBrowser1.Document as IHtmlDocument2;
 Memo1.Text := (Document.all.Item(NULL, 0) 
 as IHTMLElement).OuterHTML;
end;

В Memo1.Lines запишем такой текст:

<HTML>
 <HEAD>
 <TITLE>Hello World</TITLE>
 </HEAD>
 <BODY>
Hello again !
 </BODY>
</HTML>

Итак, мы получили возможность динамически создавать HTML-документы и предоставлять их пользователю.

КомпьютерПресс 6'2001

Автор: Анатолий Тенцер

Получить ссылку на материал

Категория: Разные | Добавил: Барон (14.12.2011)
Просмотров: 2833 | Теги: TWebBrowser, компонент | Рейтинг: 0.0/0
[ Пожертвования для сайта ] [ Пожаловаться на материал ]

Если вам помог материал сайта кликните по оплаченной рекламе размещенной в центре

Поиск
Категории раздела
Web-приложения [6]
Почта [12]
Работа с HTTP [4]
Робота с XML [4]
Сервер [3]
Разные [50]
Королевство Delphi © 2010-2024
Яндекс цитирования