由於項目需要,近來研究了一下WebBrowser組件和MSHtml 在Delphi中的使用,整理了一下這段時間研究的結果,寫下來一是方便大家查閱,二也可以加深我自己的記憶.希望能對大家有所幫助… …,同時,如果有更好的處理方式或者我沒有提到的問題,請大家也告訴我哦, 咱們一塊進步… ...,其中一部分是我從網絡中搜集的資料,謝謝那些兄弟們… …
MSHTML把HTML頁面中的元素封裝成了IHTMLInputElement、 IHTMLInputButtonElement、IHTMLInputTextElement、IHTMLTextAreaElement、IHTMLTitleElement、IHtmlFormElement等等組件接口。
在程序中可以通過MSHTML提供的IHTMLDocument2接口得到整個Document對象,IHtmlElementCollection接口得到所有頁面元素的集合,通過該接口的Item方法可以得到具體的某個組件,然後設置和讀取該組件的屬性值。
下面是一些常用功能的事例代碼.
1. 打開某個頁面:
web.Navigate(ExtractFilePath(Application.ExeName) + 'Template/login.Html');
2. 取出頁面中某個HtmlElement的Value屬性值:
function GetValueByElementName(web: TWebBrowser; elementName: string; index: integer): string;
begin
result := (((web.Document as IHtmlDocument2).body.all as
IHTMLElementCollection).item(elementName, index) as IHtmlInputElement
).value
end;
3. 給HtmlElement設置Value屬性
procedure SetValueTextAreaName(web: TWebBrowser; elementName, value: string;index: integer);
begin
(((web.Document as IHtmlDocument2).body.all as
IHTMLElementCollection).item(elementName, index) as IHtmlTextAreaElement
).value := value;
end;
4. 判斷頁面執行結果是否成功
因為Web應用中如果出錯的一般是采用錯誤頁面的方式呈現給最終用戶,所以我們也無法抓到Http錯誤,只能通過在webBeforeNavigate2事件中將URL參數記錄到全局變量中, 然後在webDocumentComplete事件中根據URL參數和全局變量中的URL參數來判斷執行結果是否正確.當然,這樣需要將頁面地址編碼到代碼中,降低了靈活性,但是這也是我能想到的唯一的方法,如果大家有什麼好的方法,請告訴我哦.
5. 屏蔽鼠標右鍵和某些快捷鍵
本功能需要在webBrowser的窗口中加入ApplicationEvents組件,設置它的OnMessage事件代碼如下即可.
procedure TwebAdapterForm.ApplicationEvents1Message(var Msg: tagMSG;
var Handled: Boolean);
const
_KeyPressMask = $80000000;
begin
//禁用右鍵
with Msg do
begin
if not IsChild(web.Handle, hWnd) then Exit;
Handled := (message = WM_RBUTTONDOWN) or (message = WM_RBUTTONUP) or (message = WM_CONTEXTMENU);
end;
//禁止Ctrl + N
//禁止Ctrl + F
//禁止Ctrl + A
if Msg.message = WM_KEYDOWN then
begin
if ((Msg.lParam and _KeyPressMask) = 0) and
(GetKeyState(VK_Control) <0) and ((Msg.wParam = Ord('N'))
or (Msg.wParam = Ord('F')) or (Msg.wParam = Ord('A'))) then
begin
Handled := True;
end;
end;
end;
6. 在頁面關閉的時候,同時關掉包含頁面的VCL Form.(僅限 InternetExplorer 6.0)
本功能需要卸載掉Delphi自帶的 WebBrowser組件,安裝ActionX組件(Microsoft Internet Controls V1.1),而且以後的程序只能運行在安裝有Internet Explorer 6.0 的環境下.具體方法如下:
在WebBrowser組件的OnWindowClosing事件中,輸入self.close; 代碼即可.如果需要阻止窗口的關閉, 設置CanClose參數的值為Flase.
7. 如何將頁面中超鏈接新開的頁面窗口包到指定的VCL窗口中.
procedure TForm1.webNewWindow2(Sender: TObject; var ppDisp: IDispatch;
var Cancel: WordBool);
var
form : TForm1;
begin
form := TForm1.Create(nil);
ppDisp := form.web.DefaultDispatch;
form.Show;
end;
8. 在WebBrowser加載html頁面完成後,在頁面頂端插入Html代碼, 下面兩種方式斗可以.
{1. ----------------------------------------------------------------}
procedure TForm1.Button1Click(Sender: TObject);
var
Range: IHtmlTxtRange;
begin
Range := ((WebBrowser1.Document as IHtmlDocument2).body as
IHtmlBodyElement).createTextRange;
Range.collapse(False);
Range.pasteHtml('<br/><b>Hello!</b>');
end;
{2. ----------------------------------------------------------------}
procedure TForm1.WebBrowser1DocumentComplete(Sender: TObject;
const pDisp: IDispatch; var URL: OleVariant);
var
WebDoc: HtmlDocument;
WebBody: HtmlBody;
begin
WebDoc := WebBrowser1.Document as HtmlDocument;
WebBody := WebDoc.body as HtmlBody;
WebBody.insertAdjacentHtml('BeforeEnd', '<h1>Hello World!</h1>');
end;
9. 將頁面中顯示的內容全部選中,然後粘貼到Word文檔中.
WebBrowser1.ExecWB(OLECMDID_SELECTALL, OLECMDEXECOPT_DODEFAULT);//全選網頁
WebBrowser1.ExecWB(OLECMDID_COPY, OLECMDEXECOPT_DODEFAULT); //復制網頁
WordDocu.Range.Paste; //Word文檔粘貼
WebBrowser1.ExecWB(OLECMDID_UNDO, OLECMDEXECOPT_DODEFAULT); //取消全選
注:WebBrowser的Document屬性值和WordDocument的Document屬性值必須都不為nil.
10. 如何解決網頁不響應回車事件
public
{ Public declarations }
procedure MsgHandle(var Msg :TMsg; var Handled :Boolean);
end;
var
Form1: TForm1;
FOleInPlaceActiveObject :IOleInPlaceActiveObject;
implementation
{$R *.DFM}
procedure TForm1.MsgHandle(var Msg :TMsg; var Handled :Boolean);
var
iOIPAO :IOleInPlaceActiveObject;
Dispatch :IDispatch;
begin
if WebBrowser1 =nil then
begin
Handled :=False;
Exit;
end;
Handled :=(IsDialogMessage(WebBrowser1.Handle, Msg) =True);
if (Handled) and (not WebBrowser1.Busy) then
begin
if FOleInPlaceActiveObject =nil then
begin
Dispatch :=WebBrowser1.Application;
if Dispatch <>nil then
begin
Dispatch.QueryInterface(IOleInPlaceActiveObject, iOIPAO);
if iOIPAO <>nil then
FOleInPlaceActiveObject :=iOIPAO;
end;
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
else
FOleInPlaceActiveObject.TranslateAccelerator(Msg);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Application.OnMessage :=MsgHandle;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
FOleInPlaceActiveObject :=nil;
end;
11. 如何在WebBrowser中調用當前頁面中的Javascript函數SayHello()
WebBrowser1.OleObject.
Document.parentWindow.execScript('SayHello()', 'Javascript');
//or
(WebBrowser1.Document as IHtmlDocument2
).parentWindow.execScript('SayHello()', 'Javascript')
//or
webrowser1.document.script.SayHello();