Перевод материала с сайта members.home.com/hfournier/webbrowser.htm
Вопрос: Что такое Веббраузер?
Ответ: Веббраузер
это Microsoft's Internet Explorer в виде ActiveX контрола. Его можно импортировать в Delphi
IDE и размещать на форме на равне
с другими компонентами. Поэтому, чтобы превратить Ваше приложение в браузер,
достаточно воспользоваться всей мощью IE.
Вопрос: Где можно найти документацию
на WebBrowser?
Ответ: Можно заглянуть на сайт Microsoft в раздел WebBrowser overview,
а так же на страницу WebBrowser object.
Вопрос: Как использовать компонент WebBrowser в своём Delphi приложение?
Ответ: Для этого необходимо, чтобы у Вас был
установлен Internet Explorer.
В меню в Delphi IDE, выберите "Component - Import ActiveX Control".
Далее выберите "Microsoft
Internet Controls" и
добавьте его как новый исполняемы пакет. Delphi сгенерирует файл ShDocVw_TLB.pas
и добавит компонент WebBrowser в закладку компонентов
ActiveX.
Вопрос: Я
вижу 2 компонента в закладке компонетов ActiveX, WebBrowser и
WebBrowser_V1. Какой из них нужно использовать?
Ответ: Если у Вас 2 компонента, то в системе
установлен IE 4.x или выше. Соответственно WebBrowser это IE 4.x а
WebBrowser_V1 это IE 3.x. Если Вы видете только один
компонент, то будет использоваться WebBrowser для IE
3.x.
Вопрос: Как определить, какая версия
IE установлена на компьютере?
Ответ: Можно почитать на Microsoft site.
Вопрос: Как производить Печать?
Ответ: Есть два способа вывода на печать.
Первый пример работает в IE 4.x и выше, в то время как второй пример расчитан на IE 3.x:
var
vaIn, vaOut: OleVariant; ... WebBrowser.ControlInterface.ExecWB(OLECMDID_PRINT,
OLECMDEXECOPT_DONTPROMPTUSER, vaIn, vaOut);либо
procedure TForm1.PrintIE;
var
CmdTarget : IOleCommandTarget; vaIn, vaOut: OleVariant;begin
if WebBrowser1.Document <> nil then try WebBrowser1.Document.QueryInterface(IOleCommandTarget, CmdTarget); if CmdTarget <> nil then try CmdTarget.Exec( PGuid(nil), OLECMDID_PRINT, OLECMDEXECOPT_DONTPROMPTUSER, vaIn, vaOut); finally CmdTarget._Release; end; except// Ничего
end;end;
Обратите внимание: Если версия Delphi ниже чем 3.02, то необходимо заменить
PGuid(nil)
на
PGuid(nil)^
. А лучше всего проапгрейдить
до 3.02 (если Вы пользуетесь версиями 3.0 или 3.01).
Вопрос: Как вызвать команды Find, Option или View Source?
Ответ: Вот пример вызова диалога Find:
const
HTMLID_FIND = 1; HTMLID_VIEWSOURCE = 2; HTMLID_OPTIONS = 3; ... procedure TForm1.FindIE;
const
CGID_WebBrowser: TGUID = '{ED016940-BD5B-11cf-BA4E-00C04FD70816}';var
CmdTarget : IOleCommandTarget; vaIn, vaOut: OleVariant; PtrGUID: PGUID;begin
New(PtrGUID); PtrGUID^ := CGID_WebBrowser; if WebBrowser1.Document <> nil then try WebBrowser1.Document.QueryInterface(IOleCommandTarget, CmdTarget); if CmdTarget <> nil then try CmdTarget.Exec( PtrGUID, HTMLID_FIND, 0, vaIn, vaOut); finally CmdTarget._Release; end; except// Ничего
end;
Dispose(PtrGUID);end;
Вопрос: Как запретить всплывающее
меню при нажатии правой книпки мыши?
Ответ: Вам необходимо включить интерфейс IDocHostUIHandler. Для этого Вам понадобятся два файла: ieConst.pas
и IEDocHostUIHandler.pas.
В методе ShowContextMenu интерфейса IDocHostUIHandler, необходимо изменить возвращаемое значение
с E_NOTIMPL на S_OK. После этого меню перестанет реагировать на правое нажатие
кнопки мыши. Добавьте два модуля, упомянутые выше в секцию Uses
и добавьте следующий код:
... var
Form1: TForm1; FDocHostUIHandler: TDocHostUIHandler;... implementation
... procedure TForm1.FormCreate(Sender: TObject);
begin
FDocHostUIHandler := TDocHostUIHandler.Create;end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
FDocHostUIHandler.Free;end;
procedure TForm1.WebBrowser1NavigateComplete2(Sender: TObject;
pDisp: IDispatch; var URL: OleVariant);var
hr: HResult; CustDoc: ICustomDoc;begin
hr := WebBrowser1.Document.QueryInterface(ICustomDoc, CustDoc); if hr = S_OK then CustDoc.SetUIHandler(FDocHostUIHandler);end;
Вопрос: Как загрузить
строковые данные в WebBrowser не прибегая к
открытию файла?
Ответ: Загрузите строку массив Variant, а затем запишите в документ (Document):
... var
v: Variant; HTMLDocument: IHTMLDocument2; begin
HTMLDocument := WebBrowser1.Document as IHTMLDocument2; v := VarArrayCreate([0, 0], varVariant);v[0] := HTMLString; // Это Ваша HTML строка
HTMLDocument.Write(PSafeArray(TVarData(v).VArray)); HTMLDocument.Close; ...end;
...Автор: Ron Loewy
Вопрос: Как загрузить потоковые(stream) данные в WebBrowser не
прибегая к открытию файла?
Ответ: Вот пример кода:
function TForm1.LoadFromStream(const AStream: TStream): HRESULT;
begin
AStream.seek(0, 0); Result := (WebBrowser1.Document as IPersistStreamInit).Load(TStreamAdapter.Create(AStream));end;
Автор: Per Larsen
Вопрос: Как использовать протокол
"about:"?
Ответ: Протокол "about:"
позволяет Вам просмотреть HTML строку:
procedure TForm1.LoadHTMLString(sHTML: String);
var
Flags, TargetFrameName, PostData, Headers: OleVariant;begin
WebBrowser1.Navigate('about:' + sHTML, Flags, TargetFrameName, PostData, Headers)end;
Вопрос: Как можно использовать
протокол "res:"?
Ответ: Протокол "res:"
позволяет просмотреть HTML файл, сохранённый как ресурс. Более подробная
информация доступна на Microsoft site:
procedure TForm1.LoadHTMLResource;
var
Flags, TargetFrameName, PostData, Headers: OleVariant;begin
WebBrowser1.Navigate('res://' + Application.ExeName + '/myhtml', Flags, TargetFrameName, PostData, Headers)end;
Создайте файл ресурса (*.rc)
со следующими строками и откомпилируйте его при помощи brcc32.exe:
MYHTML 23 ".\html\myhtml.htm" MOREHTML 23 ".\html\morehtml.htm"Отредактируйте файл проекта, чтобы он
выглядел примерно так:
{$R *.RES}{$R HTML.RES} //где html.rc будет скомпилирован в html.res
Вопрос: Как получить полный исходник HTML?
Ответ: В IE5, можно получить
исходник используя свойство outerHTML тэгов HTML. В IE4 или IE3, Вам понадобится
записать документ в файл, а затем загрузить файл в TMemo,
TStrings, и т.д.
var
HTMLDocument: IHTMLDocument2; PersistFile: IPersistFile;begin
... HTMLDocument := WebBrowser1.Document as IHTMLDocument2; PersistFile := HTMLDocument as IPersistFile; PersistFile.Save(StringToOleStr('test.htm'), True); while HTMLDocument.readyState <> 'complete' do Application.ProcessMessages;...
end;
Автор: Ron Loewy
Обратите внимание: Вам понадобится
импортировать библиотеку MSHTML и добавить MSHTML_TLB как ActiveX,
в секцию Uses.
Вопрос: Как получить POST данные?
Ответ: Если данные передаются в формате 'animal=cat&color=brown' и т.д., то попробуйте
использовать следующий код:
procedure TDBModule.Navigate(stURL, stPostData: String; var wbWebBrowser: TWebBrowser);
var
vWebAddr, vPostData, vFlags, vFrame, vHeaders: OleVariant; iLoop: Integer;begin
{Are we posting data to this Url?} if Length(stPostData)> 0 then begin {Require this header information if there is stPostData.} vHeaders:= 'Content-Type: application/x-www-form-urlencoded'+ #10#13#0; {Set the variant type for the vPostData.} vPostData:= VarArrayCreate([0, Length(stPostData)], varByte); for iLoop := 0 to Length(stPostData)- 1 do // Iterate begin vPostData[iLoop]:= Ord(stPostData[iLoop+ 1]); end; // for {Final terminating Character.} vPostData[Length(stPostData)]:= 0; {Set the type of Variant, cast} TVarData(vPostData).vType:= varArray; end; {And the other stuff.} vWebAddr:= stURL; {Make the call Rex.} wbWebBrowser.Navigate2(vWebAddr, vFlags, vFrame, vPostData, vHeaders);end; {End of Navigate procedure.}
Автор: Craig Foley
Ответ: А это другой способ:
procedure TForm1.SubmitPostForm;
var
strPostData: string; Data: Pointer; URL, Flags, TargetFrameName, PostData, Headers: OleVariant;begin
{ <!-- submit this html form: --> <form method="post" action="http://127.0.0.1/cgi-bin/register.pl"> <input type="text" name="FIRSTNAME" value="Hans"> <input type="text" name="LASTNAME" value="Gulo"> <input type="text" name="NOTE" value="thats it"> <input type="submit"> </form> } strPostData := 'FIRSTNAME=Hans&LASTNAME=Gulo&NOTE=thats+it'; PostData := VarArrayCreate([0, Length(strPostData) - 1], varByte); Data := VarArrayLock(PostData); try Move(strPostData[1], Data^, Length(strPostData)); finally VarArrayUnlock(PostData); end; URL := 'http://127.0.0.1/cgi-bin/register.pl'; Flags := EmptyParam; TargetFrameName := EmptyParam;Headers := EmptyParam; // TWebBrowser автоматически заполнять
// эти заголовки соответствующими значениями
WebBrowser1.Navigate2(URL, Flags, TargetFrameName, PostData, Headers);end;
Автор: Hans Gulo.
Вопрос: Как сделать WebBrowser плоским вместо 3D?
Ответ: Следующий пример устанавливает borderStyle:
procedure TForm1.WBDocumentComplete(Sender: TObject;
const pDisp: IDispatch; var URL: OleVariant);var
Doc : IHTMLDocument2; Element : IHTMLElement;begin
Doc := IHTMLDocument2(TWebBrowser(Sender).Document); if Doc = nil then Exit; Element := Doc.body; if Element = nil then Exit; case Make_Flat of TRUE : Element.style.borderStyle := 'none'; FALSE : Element.style.borderStyle := ''; end;end;
Автор: Donovan J. Edye
Вопрос: Как сохранить веб страничку в bitmap?
Ответ: Вот пример:
procedure TForm1.Button1Click(Sender: TObject);
var
ViewObject: IViewObject; sourceDrawRect: TRect;begin
if EmbeddedWB1.Document <> nil then try EmbeddedWB1.Document.QueryInterface(IViewObject, ViewObject); if ViewObject <> nil then try sourceDrawRect := Rect(0, 0, Image1.Width, Image1.Height); ViewObject.Draw(DVASPECT_CONTENT, 1, nil, nil, Self.Handle, image1.Canvas.Handle, @sourceDrawRect, nil, nil, 0); finally ViewObject._Release; end; except end;end;
Автор: John
Ответ: А следующий пример позволяет сохранить
её как JPEG:
procedure generateJPEGfromBrowser(browser: iWebBrowser2; jpegFQFilename: String;
srcHeight: Integer; srcWidth: Integer; tarHeight: Integer; tarWidth: Integer);var
sourceDrawRect : TRect; targetDrawRect: TRect; sourceBitmap: TBitmap; targetBitmap: TBitmap; jpeg: TJPEGImage; viewObject: IViewObject;begin
sourceBitmap := TBitmap.Create ; targetBitmap := TBitmap.Create ; jpeg := TJPEGImage.Create ; try try sourceDrawRect := Rect(0,0, srcWidth , srcHeight ); sourceBitmap.Width := srcWidth ; sourceBitmap.Height := srcHeight ; viewObject := browser as IViewObject; if viewObject = nil then Exit; OleCheck(viewObject.Draw(DVASPECT_CONTENT, 1, nil, nil, self.Handle, sourceBitmap.Canvas.Handle, @sourceDrawRect, nil, nil, 0)); // Изменяем размер исходного битмапа для конечного битмапа
targetDrawRect := Rect(0,0, tarWidth, tarHeight);
targetBitmap.Height := tarHeight; targetBitmap.Width := tarWidth; targetBitmap.Canvas.StretchDraw(targetDrawRect, sourceBitmap); // Создаём JPEG из Bitmap и сохраняем его
jpeg.Assign(targetBitmap) ;
makeFileWriteable(jpegFQFilename); jpeg.SaveToFile (jpegFQFilename); finally jpeg.free; sourceBitmap.free ; targetBitmap.free; end; except// Обработка ошибок
end;end;
Автор: Donall Burns
Вопрос: Что такое DOM?
Ответ: Document Object Model это платформенно независимый интерфейс, позволяющий программам
и скриптам динамически обновлять и изменять
содержимое, структуру и стиль документов.
Вопрос: Где
можно почитать документацию по DOM?
Ответ: Обзор материалов по DOM на W3C site , а
так же FAQ. Не забудьте заглянуть на Document object на сайте Microsoft.
Вопрос: Как работать со всеми фреймами,
отображёнными в данный момент в WebBrowser?
Ответ: Данный пример показывает
как определить в каких фреймах разрешена команда 'copy':
procedure TForm1.Button1Click(Sender: TObject);
var
i: integer; begin
for i := 0 to (WebBrowser1.OleObject.Document.frames.Length - 1) do if WebBrowser1.OleObject.Document.frames.item(i).document.queryCommandEnabled('Copy') then ShowMessage('copy command is enabled for frame no.' + IntToStr(i));end;
Автор: Peter Friese
Вопрос: Как работать со всеми
ячейками <TABLE>?
Ответ: Пример показывает
как добавить содержимое каждой ячейки в TMemo:
procedure TForm1.Button1Click(Sender: TObject);
var
i, j: integer; ovTable: OleVariant;begin
// Я использовал первую таблицу на странице в качестве примераovTable := WebBrowser1.OleObject.Document.all.tags('TABLE').item(0);
for i := 0 to (ovTable.Rows.Length - 1) do begin for j := 0 to (ovTable.Rows.Item(i).Cells.Length - 1) do begin Memo1.Lines.Add(ovTable.Rows.Item(i).Cells.Item(j).InnerText;end;
end; end;
Вопрос: Paste
работает отлично, но Cut и Copy
отказываются работать. В чём проблема?
Ответ: Вам нужно добавить следующие строки в
начало unit:
initialization
OleInitialize(nil); finalization
OleUninitialize;
Вопрос: Кобинации
клавиш Ctrl-C, Ctrl-O, и
т.д. не срабатывают. В чём проблема?
Ответ: Это не ошибка. Информацию по данному
вопросу можно найти на сайте Microsoft KnowledgeBase статья Q168777.
Приведённый ниже код, устраняет данную проблему:
... var
Form1: TForm1; FOleInPlaceActiveObject: IOleInPlaceActiveObject;SaveMessageHandler: TMessageEvent;
... implementation
... procedure TForm1.FormActivate(Sender: TObject);
begin
SaveMessageHandler := Application.OnMessage; Application.OnMessage := MyMessageHandler;end;
procedure TForm1.FormDeactivate(Sender: TObject);
begin
Application.OnMessage := SaveMessageHandler;end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Application.OnMessage := SaveMessageHandler; FOleInPlaceActiveObject := nil;end;
procedure TForm1.MyMessageHandler(var Msg: TMsg; var Handled: Boolean);
var
iOIPAO: IOleInPlaceActiveObject; Dispatch: IDispatch;begin
{ exit if we don't get back a webbrowser object } if WebBrowser = nil then begin Handled := False; Exit; end; Handled:=(IsDialogMessage(WebBrowser.Handle, Msg) = True); if (Handled) and (not WebBrowser.Busy) then begin if FOleInPlaceActiveObject = nil then begin Dispatch := WebBrowser.Application; if Dispatch <> nil then begin Dispatch.QueryInterface(IOleInPlaceActiveObject, iOIPAO); if iOIPAO <> nil then FOleInPlaceActiveObject := iOIPAO; end; end; if FOleInPlaceActiveObject <> nil then if ((Msg.message = WM_KEYDOWN) or (Msg.message = WM_KEYUP)) and ((Msg.wParam = VK_BACK) or (Msg.wParam = VK_LEFT) or (Msg.wParam = VK_RIGHT)) then //nothing - do not pass on Backspace, Left or Right arrows else FOleInPlaceActiveObject.TranslateAccelerator(Msg); end;end;