[转载]WebBrowser知识
生活随笔
收集整理的這篇文章主要介紹了
[转载]WebBrowser知识
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
WebBrowser知識
WebBrowser知識
Q: What is WebBrowser?
A: The WebBrowser is Microsoft's Internet Explorer in the form of an ActiveX control. It can be imported into the Delphi IDE and dropped on a form like any other component. Therefore, you can harness the power of Internet Explorer to turn your Delphi application into a customized browser.
Q: Where can I get documentation on the WebBrowser?
A: For more information, visit the WebBrowser overview section of the Microsoft site and the WebBrowser object page.
Q: How can I use the WebBrowser component in my Delphi application?
A: You must have Internet Explorer installed on your system. From the menu in the Delphi IDE, select "Component - Import ActiveX Control". Select "Microsoft Internet Controls" and add it to a new or existing package. Delphi will generate a ShDocVw_TLB.pas file and add the WebBrowser component to the component palette's ActiveX tab.
Q: I see 2 components on my component palette's ActiveX tab, WebBrowser and WebBrowser_V1. Which one do I use?
A: If you have 2 components then you are using IE 4.x or greater and WebBrowser is IE 4.x and WebBrowser_V1 is IE 3.x. If you only have one component, then WebBrowser is IE 3.x.
Q: How can I determine which version of IE is installed on a target machine?
A: Information is available on the Microsoft site.
Q: How do I Print?
A: There are a couple of ways to print. The first example works in IE 4.x and up, but you'll have to use the second example in IE 3.x:
var
vaIn, vaOut: OleVariant;
...
WebBrowser.ControlInterface.ExecWB(OLECMDID_PRINT, OLECMDEXECOPT_DONTPROMPTUSER, vaIn, vaOut);
or
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
// Nothing
end;
end;
Note: If you're not using Delphi 3.02 or higher, you'll have to change
PGuid(nil)
to
PGuid(nil)^
. And you really should upgrade to 3.02, if you're using 3.0 or 3.01.
Q: How do I invoke the Find, Option or View Source options?
A: Here's a code sample for invoking the Find dialog:
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
// Nothing
end;
Dispose(PtrGUID);
end;
Q: How do I disable the right-click popup menu?
A: You have to implement the IDocHostUIHandler interface. You'll need these two files: ieConst.pas and IEDocHostUIHandler.pas. In the ShowContextMenu method of the IDocHostUIHandler interface, you have to change the return value from E_NOTIMPL to S_OK and the menu will not appear on a right-click. Add the two units mentioned above to your Uses clause and implement the following code:
...
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;
Q: How do I load a string into the WebBrowser without Navigating to a file?
A: Load the string into a Variant array and then write to the Document:
...
var
v: Variant;
HTMLDocument: IHTMLDocument2;
begin
HTMLDocument := WebBrowser1.Document as IHTMLDocument2;
v := VarArrayCreate([0, 0], varVariant);
v[0] := HTMLString; // Here's your HTML string
HTMLDocument.Write(PSafeArray(TVarData(v).VArray));
HTMLDocument.Close;
...
end;
...
This tip provided by Ron Loewy
Q: How do I load a stream into the WebBrowser without Navigating to a file?
A: Here's some sample code:
function TForm1.LoadFromStream(const AStream: TStream): HRESULT;
begin
AStream.seek(0, 0);
Result := (WebBrowser1.Document as IPersistStreamInit).Load(TStreamAdapter.Create(AStream));
end;
This tip provided by Per Larsen
Q: How do I use the "about:" protocol?
A: The "about:" protocol will let you Navigate to an HTML string:
procedure TForm1.LoadHTMLString(sHTML: String);
var
Flags, TargetFrameName, PostData, Headers: OleVariant;
begin
WebBrowser1.Navigate('about:' + sHTML, Flags, TargetFrameName, PostData, Headers)
end;
Q: How do I use the "res:" protocol?
A: The "res:" protocol will let you Navigate to an HTML file stored as a resource. More informations is available from the Microsoft site:
procedure TForm1.LoadHTMLResource;
var
Flags, TargetFrameName, PostData, Headers: OleVariant;
begin
WebBrowser1.Navigate('res://' + Application.ExeName + '/myhtml', Flags, TargetFrameName, PostData, Headers)
end;
Create a resource file (*.rc) with the following code and compile it with brcc32.exe:
MYHTML 23 ".\html\myhtml.htm"
MOREHTML 23 ".\html\morehtml.htm"
Edit your project file so that it looks like this:
{$R *.RES}
{$R HTML.RES} //where html.rc was compiled into html.res
Q: How can I get the full HTML source?
A: With IE5, you can get the source by using the HTML tags outerHTML property. With IE4 or IE3, you have to save the document to a file and then load the file into a TMemo, TStrings, etc.
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;
This tip provided by Ron Loewy
Note: You have to import the MSHTML type library and include the resulting MSHTML_TLB, as well as ActiveX, in your Uses clause.
Q: How can I pass PostData when I Navigate to a URL?
A: I call the below method with a URL destination, PostData in the format of 'animal=cat etc. and the TWebBrowser object that I want to load the URL inside of...
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.}
This tip provided by Craig Foley based on techniques from Nathan Wilhelmi's Usenet posting to borland.public.delphi.internet on the 31/1/99
A: Here's another option:
procedure TForm1.SubmitPostForm;
var
strPostData: string;
Data: Pointer;
URL, Flags, TargetFrameName, PostData, Headers: OleVariant;
begin
{
submit this html form: -- method="post" action="http://127.0.0.1/cgi-bin/register.pl" type="text" name="FIRSTNAME" value="Hans" type="text" name="LASTNAME" value="Gulo" type="text" name="NOTE" value="thats it" type="submit" }
strPostData := 'FIRSTNAME=Hans 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 will see that we are providing
// post data and then should automatically fill
// this Headers with appropriate value
WebBrowser1.Navigate2(URL, Flags, TargetFrameName, PostData, Headers);
end;
This tip provided by Hans Gulo.
Q: How can I make WebBrowser flat instead of 3D?
A: Here's a code sample to set the Body's 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;
This tip provided by Donovan J. Edye
Q: How can I save a web page to a bitmap?
A: Here's a code sample:
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;
This tip provided by John
Q: How can I save a web page to a bitmap?
A: Here's a code sample:
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));
// Resize the src bitmap to the target bitmap
targetDrawRect := Rect(0,0, tarWidth, tarHeight);
targetBitmap.Height := tarHeight;
targetBitmap.Width := tarWidth;
targetBitmap.Canvas.StretchDraw(targetDrawRect, sourceBitmap);
// Create a JPEG from the Bitmap and save it
jpeg.Assign(targetBitmap) ;
makeFileWriteable(jpegFQFilename);
jpeg.SaveToFile (jpegFQFilename);
finally
jpeg.free;
sourceBitmap.free ;
targetBitmap.free;
end;
except
// Error Code
end;
end;
This tip provided by Donall Burns
Q: What is DOM?
A: The Document Object Model is a platform- and language-neutral interface that will allow programs and scripts to dynamically access and update the content, structure and style of documents. The document can be further processed and the results of that processing can be incorporated back into the presented page.
Q: Where can I get documentation on the DOM?
A: There's an overview of DOM-related materials at the W3C site and an FAQ. Check the Document object on the Microsoft site for the DOM implementation in IE 4 5.
Q: How can I iterate through all frames currently shown in the WebBrowser?
A: This sample code shows how to interate through all frames in order to test whether the 'copy' command is enabled:
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;
This tip provided by Peter Friese
Q: How can I iterate through all the cells of a
A: This sample code shows how to interate through all the cells of a table, adding the contents of each cell to a TMemo:
procedure TForm1.Button1Click(Sender: TObject);
var
i, j: integer;
ovTable: OleVariant;
begin
ovTable := WebBrowser1.OleObject.Document.all.tags('TABLE').item(0); // I'm using the first TABLE on the page as an example only
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;
Q: Paste works fine, but Cut and Copy won't work. What's the problem?
A: You have to add the following line to the bottom of your unit:
initialization
OleInitialize(nil);
finalization
OleUninitialize;
Q: ShortCut (Ctrl-C, Ctrl-O, etc.) and Delete keys have no effect. What's the problem?
A: It's not a bug, it's a feature. There's information about this in a Microsoft KnowledgeBase article Q168777. The code below should fix the problem:
...
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;
發表者 midpoint at 10:17 下午 0 評論 ?
標簽: 編程人生
TWebBrowser編程簡述
1、初始化和終止化(Initialization inalization)
大家在執行TWebBrowser的某個方法以進行期望的操作,如ExecWB等的時候可能都碰到過“試圖激活未注冊的丟失目標”或“OLE對象未注冊”等錯誤,或者并沒有出錯但是得不到希望的結果,比如不能將選中的網頁內容復制到剪貼板等。以前用它編程的時候,我發現ExecWB有時侯起作用但有時侯又不行,在Delphi生成的缺省工程主窗口上加入TWebBrowser,運行時并不會出現“OLE對象未注冊”的錯誤。同樣是一個偶然的機會,我才知道OLE對象需要初始化和終止化(懂得的東東實在太少了)。
我用我的前一篇文章《Delphi程序窗口動畫 />
initialization
OleInitialize(nil);
finalization
try
OleUninitialize;
except
end;
這幾句話放在主窗口所有語句之后,“end.”之前。
-----------------------------------------------------------------------
2、EmptyParam
在Delphi 5中TWebBrowser的Navigate方法被多次重載:
procedure Navigate(const URL: WideString); overload;
procedure Navigate(const URL: WideString; var Flags: OleVariant); overload;
procedure Navigate(const URL: WideString; var Flags: OleVariant; var TargetFrameName: OleVariant); overload;
procedure Navigate(const URL: WideString; var Flags: OleVariant; var TargetFrameName: OleVariant; var PostData: OleVariant); overload;
procedure Navigate(const URL: WideString; var Flags: OleVariant; var TargetFrameName: OleVariant; var PostData: OleVariant; var Headers: OleVariant); overload;
而在實際應用中,使用后幾種方法調用時,由于我們很少用到后面幾個參數,但函數聲明又要求是變量參數,一般的做法如下:
var
t:OleVariant;
begin
webbrowser1.Navigate(edit1.text,t,t,t,t);
end;
需要定義變量t(還有很多地方要用到它),很麻煩。其實我們可以用EmptyParam來代替(EmptyParam是一個公用的Variant空變量,不要對它賦值),只需一句話就可以了:
webbrowser1.Navigate(edit1.text,EmptyParam,EmptyParam,EmptyParam,EmptyParam);
雖然長一點,但比每次都定義變量方便得多。當然,也可以使用第一種方式。
webbrowser1.Navigate(edit1.text)
-----------------------------------------------------------------------
3、命令操作
常用的命令操作用ExecWB方法即可完成,ExecWB同樣多次被重載:
procedure ExecWB(cmdID: OLECMDID; cmdexecopt: OLECMDEXECOPT); overload;
procedure ExecWB(cmdID: OLECMDID; cmdexecopt: OLECMDEXECOPT; var pvaIn:
OleVariant); overload;
procedure ExecWB(cmdID: rOLECMDID; cmdexecopt: OLECMDEXECOPT; var pvaIn:
OleVariant; var pvaOut: OleVariant); overload;
打開: 彈出“打開Internet地址”對話框,CommandID為OLECMDID_OPEN(若瀏覽器版本為IE5.0,
則此命令不可用)。
另存為:調用“另存為”對話框。
ExecWB(OLECMDID_SAVEAS,OLECMDEXECOPT_DODEFAULT, EmptyParam,
EmptyParam);
打印、打印預覽和頁面設置: 調用“打印”、“打印預覽”和“頁面設置”對話框(IE5.5及以上版本才支持打
印預覽,故實現應該檢查此命令是否可用)。
ExecWB(OLECMDID_PRINT, OLECMDEXECOPT_DODEFAULT, EmptyParam,
EmptyParam);
if QueryStatusWB(OLECMDID_PRINTPREVIEW)=3 then
ExecWB(OLECMDID_PRINTPREVIEW, OLECMDEXECOPT_DODEFAULT,
EmptyParam,EmptyParam);
ExecWB(OLECMDID_PAGESETUP, OLECMDEXECOPT_DODEFAULT, EmptyParam,
EmptyParam);
剪切、復制、粘貼、全選: 功能無須多說,需要注意的是:剪切和粘貼不僅對編輯框文字,而且對網頁上的非編
輯框文字同樣有效,用得好的話,也許可以做出功能特殊的東東。獲得其命令使能狀
態和執行命令的方法有兩種(以復制為例,剪切、粘貼和全選分別將各自的關鍵字替
換即可,分別為CUT,PASTE和SELECTALL):
A、用TWebBrowser的QueryStatusWB方法。
if(QueryStatusWB(OLECMDID_COPY)=OLECMDF_ENABLED) or
OLECMDF_SUPPORTED) then
ExecWB(OLECMDID_COPY, OLECMDEXECOPT_DODEFAULT, EmptyParam,
EmptyParam);
B、用IHTMLDocument2的QueryCommandEnabled方法。
var
Doc: IHTMLDocument2;
begin
Doc :=WebBrowser1.Document as IHTMLDocument2;
if Doc.QueryCommandEnabled('Copy') then
Doc.ExecCommand('Copy',false,EmptyParam);
end;
查找: 參考第九條“查找”功能。
-----------------------------------------------------------------------
4、字體大小
類似“字體”菜單上的從“最大”到“最小”五項(對應整數0~4,Largest等假設為五個菜單項的名字,Tag 屬性分別設為0~4)。
A、讀取當前頁面字體大小。
var
t: OleVariant;
Begin
WebBrowser1.ExecWB(OLECMDID_ZOOM, OLECMDEXECOPT_DONTPROMPTUSER,
EmptyParam,t);
case t of
4: Largest.Checked :=true;
3: Larger.Checked :=true;
2: Middle.Checked :=true;
1: Small.Checked :=true;
0: Smallest.Checked :=true;
end;
end;
B、設置頁面字體大小。
Largest.Checked :=false;
Larger.Checked :=false;
Middle.Checked :=false;
Small.Checked :=false;
Smallest.Checked :=false;
TMenuItem(Sender).Checked :=true;
t :=TMenuItem(Sender).Tag;
WebBrowser1.ExecWB(OLECMDID_ZOOM, OLECMDEXECOPT_DONTPROMPTUSER,
t,t);
-----------------------------------------------------------------------
5、添加到收藏夾和整理收藏夾
const
CLSID_ShellUIHelper: TGUID = '{64AB4BB7-111E-11D1-8F79-00C04FC2FBE1}';
var
p:procedure(Handle: THandle; Path: PChar); stdcall;
procedure TForm1.OrganizeFavorite(Sender: Tobject);
var
H: HWnd;
begin
H := LoadLibrary(PChar('shdocvw.dll'));
if H 0 then
begin
p := GetProcAddress(H, PChar('DoOrganizeFavDlg'));
if Assigned(p) then p(Application.Handle, PChar(FavFolder));
end;
FreeLibrary(h);
end;
procedure TForm1.AddFavorite(Sender: TObject);
var
ShellUIHelper: ISHellUIHelper;
url, title: Olevariant;
begin
Title := Webbrowser1.LocationName;
Url := Webbrowser1.LocationUrl;
if Url '' then
begin
ShellUIHelper := CreateComObject(CLSID_SHELLUIHELPER) as IShellUIHelper;
ShellUIHelper.AddFavorite(url, title);
end;
end;
-----------------------------------------------------------------------
6、使WebBrowser獲得焦點
TWebBrowser非常特殊,它從TWinControl繼承來的SetFocus方法并不能使得它所包含的文檔獲得焦點,從而不能立即使用Internet Explorer本身具有得快捷鍵,解決方法如下: />
procedure TForm1.SetFocusToDoc;
begin
if WebBrowser1.Document nil then
with WebBrowser1.Application as IOleobject do
DoVerb(OLEIVERB_UIACTIVATE, nil, WebBrowser1, 0, Handle, GetClientRect);
end;
除此之外,我還找到一種更簡單的方法,這里一并列出:
if WebBrowser1.Document nil then
IHTMLWindow2(IHTMLDocument2(WebBrowser1.Document).ParentWindow).focus
剛找到了更簡單的方法,也許是最簡單的:
if WebBrowser1.Document nil then
IHTMLWindow4(WebBrowser1.Document).focus
還有,需要判斷文檔是否獲得焦點這樣來做:
if IHTMLWindow4(WebBrowser1.Document).hasfocus then
-----------------------------------------------------------------------
7、點擊“提交”按鈕
如同程序里每個窗體上有一個“缺省”按鈕一樣,Web頁面上的每個Form也有一個“缺省”按鈕——即屬性為“Submit”的按鈕,當用戶按下回車鍵時就相當于鼠標單擊了“Submit”。但是TWebBrowser似乎并不響應回車鍵,并且,即使把包含TWebBrowser的窗體的 KeyPreview設為True,在窗體的KeyPress事件里還是不能截獲用戶向TWebBrowser發出的按鍵。
我的解決辦法是用 ApplicatinEvents構件或者自己編寫TApplication對象的OnMessage事件,在其中判斷消息類型,對鍵盤消息做出響應。至于點擊“提交”按鈕,可以通過分析網頁源代碼的方法來實現,不過我找到了更為簡單快捷的方法,有兩種,第一種是我自己想出來的,另一種是別人寫的代碼,這里都提供給大家,以做參考。
A、用SendKeys函數向WebBrowser發送回車鍵
在Delphi 5光盤上的Info\Extras\SendKeys目錄下有一個SndKey32.pas文件,其中包含了兩個函數SendKeys和 AppActivate,我們可以用SendKeys函數來向WebBrowser發送回車鍵,我現在用的就是這個方法,使用很簡單,在 WebBrowser獲得焦點的情況下(不要求WebBrowser所包含的文檔獲得焦點),用一條語句即可:
Sendkeys('~',true);// press RETURN key
SendKeys函數的詳細參數說明等,均包含在SndKey32.pas文件中。
B、在OnMessage事件中將接受到的鍵盤消息傳遞給WebBrowser。
procedure TForm1.ApplicationEvents1Message(var Msg: TMsg; var Handled: Boolean);
{fixes the malfunction of some keys within webbrowser control}
const
StdKeys = [VK_TAB, VK_RETURN]; { standard keys }
ExtKeys = [VK_DELETE, VK_BACK, VK_LEFT, VK_RIGHT]; { extended keys }
fExtended = $01000000; { extended key flag }
begin
Handled := False;
with Msg do
if ((Message WM_KEYFIRST) and (Message WM_KEYLAST)) and
((wParam in StdKeys) or
{$IFDEF VER120}(GetKeyState(VK_CONTROL) 0) or {$ENDIF}
(wParam in ExtKeys) and
((lParam and fExtended) = fExtended)) then
try
if IsChild(Handle, hWnd) then { handles all browser related messages }
begin
with {$IFDEF VER120}Application_{$ELSE}Application{$ENDIF} as
IOleInPlaceActiveObject do
Handled := TranslateAccelerator(Msg) = S_OK;
if not Handled then
begin
Handled := True;
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
end;
except
end;
end; // MessageHandler
(此方法來自EmbeddedWB.pas)
-----------------------------------------------------------------------
8、直接從TWebBrowser得到網頁源碼及Html
下面先介紹一種極其簡單的得到TWebBrowser正在訪問的網頁源碼的方法。一般方法是利用TWebBrowser控件中的 Document對象提供的IPersistStreamInit接口來實現,具體就是:先檢查WebBrowser.Document對象是否有效,無效則退出;然后取得IPersistStreamInit接口,接著取得HTML源碼的大小,分配全局堆內存塊,建立流,再將HTML文本寫到流中。程序雖然不算復雜,但是有更簡單的方法,所以實現代碼不再給出。其實基本上所有IE的功能TWebBrowser都應該有較為簡單的方法來實現,獲取網頁源碼也是一樣。下面的代碼將網頁源碼顯示在Memo1中。
Memo1.Lines.Add(IHtmlDocument2(WebBrowser1.Document).Body.OuterHtml);
同時,在用TWebBrowser瀏覽HTML文件的時候要將其保存為文本文件就很簡單了,不需要任何的語法解析工具,因為TWebBrowser也完成了,如下:
Memo1.Lines.Add(IHtmlDocument2(WebBrowser1.Document).Body.OuterText);
-----------------------------------------------------------------------
9、“查找”功能
查找對話框可以在文檔獲得焦點的時候通過按鍵Ctrl-F來調出,程序中則調用IOleCommandTarget對象的成員函數Exec執行OLECMDID_FIND操作來調用,下面給出的方法是如何在程序中用代碼來做出文字選擇,即你可以自己設計查找對話框。
var
Doc: IHtmlDocument2;
TxtRange: IHtmlTxtRange;
begin
Doc :=WebBrowser1.Document as IHtmlDocument2;
Doc.SelectAll; //此處為簡寫,選擇全部文檔的方法請參見第三條命令操作
//這句話尤為重要,因為IHtmlTxtRange對象的方法能夠操作的前提是
//Document已經有一個文字選擇區域。由于接著執行下面的語句,所以不會
//看到文檔全選的過程。
TxtRange :=Doc.Selection.CreateRange as IHtmlTxtRange;
TxtRange.FindText('Text to be searched',0.0);
TxtRange.Select;
end;
還有,從Txt.Get_text可以得到當前選中的文字內容,某些時候是有用的。
-----------------------------------------------------------------------
10、提取網頁中所有鏈接
這個方法來自大富翁論壇hopfield朋友的對一個問題的回答,我本想自己試驗,但總是沒成功。
var
doc:IHTMLDocument2;
all:IHTMLElementCollection;
len,i:integer;
item:OleVariant;
begin
doc:=WebBrowser1 .Document as IHTMLDocument2;
all:=doc.Get_links; //doc.Links亦可
len:=all.length;
for i:=0 to len-1 do begin
item:=all.item(i,varempty); //EmpryParam亦可
memo1.lines.add(item.href);
end;
end;
-----------------------------------------------------------------------
11、設置TWebBrowser的編碼
為什么我總是錯過很多機會?其實早就該想到的,但是一念之差,便即天壤之別。當時我要是肯再多考慮一下,多試驗一下,這就不會排到第11條了。下面給出一個函數,搞定,難以想象的簡單。
procedure SetCharSet(AWebBrowser: TWebBrowser; ACharSet: String);
var
RefreshLevel: OleVariant;
Begin
IHTMLDocument2(AWebBrowser.Document).Set_CharSet(ACharSet);
RefreshLevel :=7; //這個7應該從注冊表來,幫助有Bug。
AWebBrowser.Refresh2(RefreshLevel);
End;
WebBrowser知識
Q: What is WebBrowser?
A: The WebBrowser is Microsoft's Internet Explorer in the form of an ActiveX control. It can be imported into the Delphi IDE and dropped on a form like any other component. Therefore, you can harness the power of Internet Explorer to turn your Delphi application into a customized browser.
Q: Where can I get documentation on the WebBrowser?
A: For more information, visit the WebBrowser overview section of the Microsoft site and the WebBrowser object page.
Q: How can I use the WebBrowser component in my Delphi application?
A: You must have Internet Explorer installed on your system. From the menu in the Delphi IDE, select "Component - Import ActiveX Control". Select "Microsoft Internet Controls" and add it to a new or existing package. Delphi will generate a ShDocVw_TLB.pas file and add the WebBrowser component to the component palette's ActiveX tab.
Q: I see 2 components on my component palette's ActiveX tab, WebBrowser and WebBrowser_V1. Which one do I use?
A: If you have 2 components then you are using IE 4.x or greater and WebBrowser is IE 4.x and WebBrowser_V1 is IE 3.x. If you only have one component, then WebBrowser is IE 3.x.
Q: How can I determine which version of IE is installed on a target machine?
A: Information is available on the Microsoft site.
Q: How do I Print?
A: There are a couple of ways to print. The first example works in IE 4.x and up, but you'll have to use the second example in IE 3.x:
var
vaIn, vaOut: OleVariant;
...
WebBrowser.ControlInterface.ExecWB(OLECMDID_PRINT, OLECMDEXECOPT_DONTPROMPTUSER, vaIn, vaOut);
or
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
// Nothing
end;
end;
Note: If you're not using Delphi 3.02 or higher, you'll have to change
PGuid(nil)
to
PGuid(nil)^
. And you really should upgrade to 3.02, if you're using 3.0 or 3.01.
Q: How do I invoke the Find, Option or View Source options?
A: Here's a code sample for invoking the Find dialog:
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
// Nothing
end;
Dispose(PtrGUID);
end;
Q: How do I disable the right-click popup menu?
A: You have to implement the IDocHostUIHandler interface. You'll need these two files: ieConst.pas and IEDocHostUIHandler.pas. In the ShowContextMenu method of the IDocHostUIHandler interface, you have to change the return value from E_NOTIMPL to S_OK and the menu will not appear on a right-click. Add the two units mentioned above to your Uses clause and implement the following code:
...
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;
Q: How do I load a string into the WebBrowser without Navigating to a file?
A: Load the string into a Variant array and then write to the Document:
...
var
v: Variant;
HTMLDocument: IHTMLDocument2;
begin
HTMLDocument := WebBrowser1.Document as IHTMLDocument2;
v := VarArrayCreate([0, 0], varVariant);
v[0] := HTMLString; // Here's your HTML string
HTMLDocument.Write(PSafeArray(TVarData(v).VArray));
HTMLDocument.Close;
...
end;
...
This tip provided by Ron Loewy
Q: How do I load a stream into the WebBrowser without Navigating to a file?
A: Here's some sample code:
function TForm1.LoadFromStream(const AStream: TStream): HRESULT;
begin
AStream.seek(0, 0);
Result := (WebBrowser1.Document as IPersistStreamInit).Load(TStreamAdapter.Create(AStream));
end;
This tip provided by Per Larsen
Q: How do I use the "about:" protocol?
A: The "about:" protocol will let you Navigate to an HTML string:
procedure TForm1.LoadHTMLString(sHTML: String);
var
Flags, TargetFrameName, PostData, Headers: OleVariant;
begin
WebBrowser1.Navigate('about:' + sHTML, Flags, TargetFrameName, PostData, Headers)
end;
Q: How do I use the "res:" protocol?
A: The "res:" protocol will let you Navigate to an HTML file stored as a resource. More informations is available from the Microsoft site:
procedure TForm1.LoadHTMLResource;
var
Flags, TargetFrameName, PostData, Headers: OleVariant;
begin
WebBrowser1.Navigate('res://' + Application.ExeName + '/myhtml', Flags, TargetFrameName, PostData, Headers)
end;
Create a resource file (*.rc) with the following code and compile it with brcc32.exe:
MYHTML 23 ".\html\myhtml.htm"
MOREHTML 23 ".\html\morehtml.htm"
Edit your project file so that it looks like this:
{$R *.RES}
{$R HTML.RES} //where html.rc was compiled into html.res
Q: How can I get the full HTML source?
A: With IE5, you can get the source by using the HTML tags outerHTML property. With IE4 or IE3, you have to save the document to a file and then load the file into a TMemo, TStrings, etc.
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;
This tip provided by Ron Loewy
Note: You have to import the MSHTML type library and include the resulting MSHTML_TLB, as well as ActiveX, in your Uses clause.
Q: How can I pass PostData when I Navigate to a URL?
A: I call the below method with a URL destination, PostData in the format of 'animal=cat etc. and the TWebBrowser object that I want to load the URL inside of...
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.}
This tip provided by Craig Foley based on techniques from Nathan Wilhelmi's Usenet posting to borland.public.delphi.internet on the 31/1/99
A: Here's another option:
procedure TForm1.SubmitPostForm;
var
strPostData: string;
Data: Pointer;
URL, Flags, TargetFrameName, PostData, Headers: OleVariant;
begin
{
submit this html form: -- method="post" action="http://127.0.0.1/cgi-bin/register.pl" type="text" name="FIRSTNAME" value="Hans" type="text" name="LASTNAME" value="Gulo" type="text" name="NOTE" value="thats it" type="submit" }
strPostData := 'FIRSTNAME=Hans 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 will see that we are providing
// post data and then should automatically fill
// this Headers with appropriate value
WebBrowser1.Navigate2(URL, Flags, TargetFrameName, PostData, Headers);
end;
This tip provided by Hans Gulo.
Q: How can I make WebBrowser flat instead of 3D?
A: Here's a code sample to set the Body's 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;
This tip provided by Donovan J. Edye
Q: How can I save a web page to a bitmap?
A: Here's a code sample:
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;
This tip provided by John
Q: How can I save a web page to a bitmap?
A: Here's a code sample:
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));
// Resize the src bitmap to the target bitmap
targetDrawRect := Rect(0,0, tarWidth, tarHeight);
targetBitmap.Height := tarHeight;
targetBitmap.Width := tarWidth;
targetBitmap.Canvas.StretchDraw(targetDrawRect, sourceBitmap);
// Create a JPEG from the Bitmap and save it
jpeg.Assign(targetBitmap) ;
makeFileWriteable(jpegFQFilename);
jpeg.SaveToFile (jpegFQFilename);
finally
jpeg.free;
sourceBitmap.free ;
targetBitmap.free;
end;
except
// Error Code
end;
end;
This tip provided by Donall Burns
Q: What is DOM?
A: The Document Object Model is a platform- and language-neutral interface that will allow programs and scripts to dynamically access and update the content, structure and style of documents. The document can be further processed and the results of that processing can be incorporated back into the presented page.
Q: Where can I get documentation on the DOM?
A: There's an overview of DOM-related materials at the W3C site and an FAQ. Check the Document object on the Microsoft site for the DOM implementation in IE 4 5.
Q: How can I iterate through all frames currently shown in the WebBrowser?
A: This sample code shows how to interate through all frames in order to test whether the 'copy' command is enabled:
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;
This tip provided by Peter Friese
Q: How can I iterate through all the cells of a
A: This sample code shows how to interate through all the cells of a table, adding the contents of each cell to a TMemo:
procedure TForm1.Button1Click(Sender: TObject);
var
i, j: integer;
ovTable: OleVariant;
begin
ovTable := WebBrowser1.OleObject.Document.all.tags('TABLE').item(0); // I'm using the first TABLE on the page as an example only
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;
Q: Paste works fine, but Cut and Copy won't work. What's the problem?
A: You have to add the following line to the bottom of your unit:
initialization
OleInitialize(nil);
finalization
OleUninitialize;
Q: ShortCut (Ctrl-C, Ctrl-O, etc.) and Delete keys have no effect. What's the problem?
A: It's not a bug, it's a feature. There's information about this in a Microsoft KnowledgeBase article Q168777. The code below should fix the problem:
...
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;
發表者 midpoint at 10:17 下午 0 評論 ?
標簽: 編程人生
TWebBrowser編程簡述
1、初始化和終止化(Initialization inalization)
大家在執行TWebBrowser的某個方法以進行期望的操作,如ExecWB等的時候可能都碰到過“試圖激活未注冊的丟失目標”或“OLE對象未注冊”等錯誤,或者并沒有出錯但是得不到希望的結果,比如不能將選中的網頁內容復制到剪貼板等。以前用它編程的時候,我發現ExecWB有時侯起作用但有時侯又不行,在Delphi生成的缺省工程主窗口上加入TWebBrowser,運行時并不會出現“OLE對象未注冊”的錯誤。同樣是一個偶然的機會,我才知道OLE對象需要初始化和終止化(懂得的東東實在太少了)。
我用我的前一篇文章《Delphi程序窗口動畫 />
initialization
OleInitialize(nil);
finalization
try
OleUninitialize;
except
end;
這幾句話放在主窗口所有語句之后,“end.”之前。
-----------------------------------------------------------------------
2、EmptyParam
在Delphi 5中TWebBrowser的Navigate方法被多次重載:
procedure Navigate(const URL: WideString); overload;
procedure Navigate(const URL: WideString; var Flags: OleVariant); overload;
procedure Navigate(const URL: WideString; var Flags: OleVariant; var TargetFrameName: OleVariant); overload;
procedure Navigate(const URL: WideString; var Flags: OleVariant; var TargetFrameName: OleVariant; var PostData: OleVariant); overload;
procedure Navigate(const URL: WideString; var Flags: OleVariant; var TargetFrameName: OleVariant; var PostData: OleVariant; var Headers: OleVariant); overload;
而在實際應用中,使用后幾種方法調用時,由于我們很少用到后面幾個參數,但函數聲明又要求是變量參數,一般的做法如下:
var
t:OleVariant;
begin
webbrowser1.Navigate(edit1.text,t,t,t,t);
end;
需要定義變量t(還有很多地方要用到它),很麻煩。其實我們可以用EmptyParam來代替(EmptyParam是一個公用的Variant空變量,不要對它賦值),只需一句話就可以了:
webbrowser1.Navigate(edit1.text,EmptyParam,EmptyParam,EmptyParam,EmptyParam);
雖然長一點,但比每次都定義變量方便得多。當然,也可以使用第一種方式。
webbrowser1.Navigate(edit1.text)
-----------------------------------------------------------------------
3、命令操作
常用的命令操作用ExecWB方法即可完成,ExecWB同樣多次被重載:
procedure ExecWB(cmdID: OLECMDID; cmdexecopt: OLECMDEXECOPT); overload;
procedure ExecWB(cmdID: OLECMDID; cmdexecopt: OLECMDEXECOPT; var pvaIn:
OleVariant); overload;
procedure ExecWB(cmdID: rOLECMDID; cmdexecopt: OLECMDEXECOPT; var pvaIn:
OleVariant; var pvaOut: OleVariant); overload;
打開: 彈出“打開Internet地址”對話框,CommandID為OLECMDID_OPEN(若瀏覽器版本為IE5.0,
則此命令不可用)。
另存為:調用“另存為”對話框。
ExecWB(OLECMDID_SAVEAS,OLECMDEXECOPT_DODEFAULT, EmptyParam,
EmptyParam);
打印、打印預覽和頁面設置: 調用“打印”、“打印預覽”和“頁面設置”對話框(IE5.5及以上版本才支持打
印預覽,故實現應該檢查此命令是否可用)。
ExecWB(OLECMDID_PRINT, OLECMDEXECOPT_DODEFAULT, EmptyParam,
EmptyParam);
if QueryStatusWB(OLECMDID_PRINTPREVIEW)=3 then
ExecWB(OLECMDID_PRINTPREVIEW, OLECMDEXECOPT_DODEFAULT,
EmptyParam,EmptyParam);
ExecWB(OLECMDID_PAGESETUP, OLECMDEXECOPT_DODEFAULT, EmptyParam,
EmptyParam);
剪切、復制、粘貼、全選: 功能無須多說,需要注意的是:剪切和粘貼不僅對編輯框文字,而且對網頁上的非編
輯框文字同樣有效,用得好的話,也許可以做出功能特殊的東東。獲得其命令使能狀
態和執行命令的方法有兩種(以復制為例,剪切、粘貼和全選分別將各自的關鍵字替
換即可,分別為CUT,PASTE和SELECTALL):
A、用TWebBrowser的QueryStatusWB方法。
if(QueryStatusWB(OLECMDID_COPY)=OLECMDF_ENABLED) or
OLECMDF_SUPPORTED) then
ExecWB(OLECMDID_COPY, OLECMDEXECOPT_DODEFAULT, EmptyParam,
EmptyParam);
B、用IHTMLDocument2的QueryCommandEnabled方法。
var
Doc: IHTMLDocument2;
begin
Doc :=WebBrowser1.Document as IHTMLDocument2;
if Doc.QueryCommandEnabled('Copy') then
Doc.ExecCommand('Copy',false,EmptyParam);
end;
查找: 參考第九條“查找”功能。
-----------------------------------------------------------------------
4、字體大小
類似“字體”菜單上的從“最大”到“最小”五項(對應整數0~4,Largest等假設為五個菜單項的名字,Tag 屬性分別設為0~4)。
A、讀取當前頁面字體大小。
var
t: OleVariant;
Begin
WebBrowser1.ExecWB(OLECMDID_ZOOM, OLECMDEXECOPT_DONTPROMPTUSER,
EmptyParam,t);
case t of
4: Largest.Checked :=true;
3: Larger.Checked :=true;
2: Middle.Checked :=true;
1: Small.Checked :=true;
0: Smallest.Checked :=true;
end;
end;
B、設置頁面字體大小。
Largest.Checked :=false;
Larger.Checked :=false;
Middle.Checked :=false;
Small.Checked :=false;
Smallest.Checked :=false;
TMenuItem(Sender).Checked :=true;
t :=TMenuItem(Sender).Tag;
WebBrowser1.ExecWB(OLECMDID_ZOOM, OLECMDEXECOPT_DONTPROMPTUSER,
t,t);
-----------------------------------------------------------------------
5、添加到收藏夾和整理收藏夾
const
CLSID_ShellUIHelper: TGUID = '{64AB4BB7-111E-11D1-8F79-00C04FC2FBE1}';
var
p:procedure(Handle: THandle; Path: PChar); stdcall;
procedure TForm1.OrganizeFavorite(Sender: Tobject);
var
H: HWnd;
begin
H := LoadLibrary(PChar('shdocvw.dll'));
if H 0 then
begin
p := GetProcAddress(H, PChar('DoOrganizeFavDlg'));
if Assigned(p) then p(Application.Handle, PChar(FavFolder));
end;
FreeLibrary(h);
end;
procedure TForm1.AddFavorite(Sender: TObject);
var
ShellUIHelper: ISHellUIHelper;
url, title: Olevariant;
begin
Title := Webbrowser1.LocationName;
Url := Webbrowser1.LocationUrl;
if Url '' then
begin
ShellUIHelper := CreateComObject(CLSID_SHELLUIHELPER) as IShellUIHelper;
ShellUIHelper.AddFavorite(url, title);
end;
end;
-----------------------------------------------------------------------
6、使WebBrowser獲得焦點
TWebBrowser非常特殊,它從TWinControl繼承來的SetFocus方法并不能使得它所包含的文檔獲得焦點,從而不能立即使用Internet Explorer本身具有得快捷鍵,解決方法如下: />
procedure TForm1.SetFocusToDoc;
begin
if WebBrowser1.Document nil then
with WebBrowser1.Application as IOleobject do
DoVerb(OLEIVERB_UIACTIVATE, nil, WebBrowser1, 0, Handle, GetClientRect);
end;
除此之外,我還找到一種更簡單的方法,這里一并列出:
if WebBrowser1.Document nil then
IHTMLWindow2(IHTMLDocument2(WebBrowser1.Document).ParentWindow).focus
剛找到了更簡單的方法,也許是最簡單的:
if WebBrowser1.Document nil then
IHTMLWindow4(WebBrowser1.Document).focus
還有,需要判斷文檔是否獲得焦點這樣來做:
if IHTMLWindow4(WebBrowser1.Document).hasfocus then
-----------------------------------------------------------------------
7、點擊“提交”按鈕
如同程序里每個窗體上有一個“缺省”按鈕一樣,Web頁面上的每個Form也有一個“缺省”按鈕——即屬性為“Submit”的按鈕,當用戶按下回車鍵時就相當于鼠標單擊了“Submit”。但是TWebBrowser似乎并不響應回車鍵,并且,即使把包含TWebBrowser的窗體的 KeyPreview設為True,在窗體的KeyPress事件里還是不能截獲用戶向TWebBrowser發出的按鍵。
我的解決辦法是用 ApplicatinEvents構件或者自己編寫TApplication對象的OnMessage事件,在其中判斷消息類型,對鍵盤消息做出響應。至于點擊“提交”按鈕,可以通過分析網頁源代碼的方法來實現,不過我找到了更為簡單快捷的方法,有兩種,第一種是我自己想出來的,另一種是別人寫的代碼,這里都提供給大家,以做參考。
A、用SendKeys函數向WebBrowser發送回車鍵
在Delphi 5光盤上的Info\Extras\SendKeys目錄下有一個SndKey32.pas文件,其中包含了兩個函數SendKeys和 AppActivate,我們可以用SendKeys函數來向WebBrowser發送回車鍵,我現在用的就是這個方法,使用很簡單,在 WebBrowser獲得焦點的情況下(不要求WebBrowser所包含的文檔獲得焦點),用一條語句即可:
Sendkeys('~',true);// press RETURN key
SendKeys函數的詳細參數說明等,均包含在SndKey32.pas文件中。
B、在OnMessage事件中將接受到的鍵盤消息傳遞給WebBrowser。
procedure TForm1.ApplicationEvents1Message(var Msg: TMsg; var Handled: Boolean);
{fixes the malfunction of some keys within webbrowser control}
const
StdKeys = [VK_TAB, VK_RETURN]; { standard keys }
ExtKeys = [VK_DELETE, VK_BACK, VK_LEFT, VK_RIGHT]; { extended keys }
fExtended = $01000000; { extended key flag }
begin
Handled := False;
with Msg do
if ((Message WM_KEYFIRST) and (Message WM_KEYLAST)) and
((wParam in StdKeys) or
{$IFDEF VER120}(GetKeyState(VK_CONTROL) 0) or {$ENDIF}
(wParam in ExtKeys) and
((lParam and fExtended) = fExtended)) then
try
if IsChild(Handle, hWnd) then { handles all browser related messages }
begin
with {$IFDEF VER120}Application_{$ELSE}Application{$ENDIF} as
IOleInPlaceActiveObject do
Handled := TranslateAccelerator(Msg) = S_OK;
if not Handled then
begin
Handled := True;
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
end;
except
end;
end; // MessageHandler
(此方法來自EmbeddedWB.pas)
-----------------------------------------------------------------------
8、直接從TWebBrowser得到網頁源碼及Html
下面先介紹一種極其簡單的得到TWebBrowser正在訪問的網頁源碼的方法。一般方法是利用TWebBrowser控件中的 Document對象提供的IPersistStreamInit接口來實現,具體就是:先檢查WebBrowser.Document對象是否有效,無效則退出;然后取得IPersistStreamInit接口,接著取得HTML源碼的大小,分配全局堆內存塊,建立流,再將HTML文本寫到流中。程序雖然不算復雜,但是有更簡單的方法,所以實現代碼不再給出。其實基本上所有IE的功能TWebBrowser都應該有較為簡單的方法來實現,獲取網頁源碼也是一樣。下面的代碼將網頁源碼顯示在Memo1中。
Memo1.Lines.Add(IHtmlDocument2(WebBrowser1.Document).Body.OuterHtml);
同時,在用TWebBrowser瀏覽HTML文件的時候要將其保存為文本文件就很簡單了,不需要任何的語法解析工具,因為TWebBrowser也完成了,如下:
Memo1.Lines.Add(IHtmlDocument2(WebBrowser1.Document).Body.OuterText);
-----------------------------------------------------------------------
9、“查找”功能
查找對話框可以在文檔獲得焦點的時候通過按鍵Ctrl-F來調出,程序中則調用IOleCommandTarget對象的成員函數Exec執行OLECMDID_FIND操作來調用,下面給出的方法是如何在程序中用代碼來做出文字選擇,即你可以自己設計查找對話框。
var
Doc: IHtmlDocument2;
TxtRange: IHtmlTxtRange;
begin
Doc :=WebBrowser1.Document as IHtmlDocument2;
Doc.SelectAll; //此處為簡寫,選擇全部文檔的方法請參見第三條命令操作
//這句話尤為重要,因為IHtmlTxtRange對象的方法能夠操作的前提是
//Document已經有一個文字選擇區域。由于接著執行下面的語句,所以不會
//看到文檔全選的過程。
TxtRange :=Doc.Selection.CreateRange as IHtmlTxtRange;
TxtRange.FindText('Text to be searched',0.0);
TxtRange.Select;
end;
還有,從Txt.Get_text可以得到當前選中的文字內容,某些時候是有用的。
-----------------------------------------------------------------------
10、提取網頁中所有鏈接
這個方法來自大富翁論壇hopfield朋友的對一個問題的回答,我本想自己試驗,但總是沒成功。
var
doc:IHTMLDocument2;
all:IHTMLElementCollection;
len,i:integer;
item:OleVariant;
begin
doc:=WebBrowser1 .Document as IHTMLDocument2;
all:=doc.Get_links; //doc.Links亦可
len:=all.length;
for i:=0 to len-1 do begin
item:=all.item(i,varempty); //EmpryParam亦可
memo1.lines.add(item.href);
end;
end;
-----------------------------------------------------------------------
11、設置TWebBrowser的編碼
為什么我總是錯過很多機會?其實早就該想到的,但是一念之差,便即天壤之別。當時我要是肯再多考慮一下,多試驗一下,這就不會排到第11條了。下面給出一個函數,搞定,難以想象的簡單。
procedure SetCharSet(AWebBrowser: TWebBrowser; ACharSet: String);
var
RefreshLevel: OleVariant;
Begin
IHTMLDocument2(AWebBrowser.Document).Set_CharSet(ACharSet);
RefreshLevel :=7; //這個7應該從注冊表來,幫助有Bug。
AWebBrowser.Refresh2(RefreshLevel);
End;
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1601698
轉載于:https://www.cnblogs.com/gbsck/archive/2007/08/20/862998.html
總結
以上是生活随笔為你收集整理的[转载]WebBrowser知识的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MySQL字符串拼接函数
- 下一篇: 人人开源项目前端添加静态路由