1、加入引用
在控件欄按右鍵,選擇“添加/移除項”,選COM組件,選中“Microsoft Web Browser”。然后就可以往窗體上拖出一個該控件(下面把該控件一個對象稱為webBrowser)。控件屬性中可以調整的不多,從一些資料中得知WebBrowser中的MenuBar、StatusBar等其實都沒實現。
2、控件的函數
由於是COM過來的控件,它的一些函數就比較怪,基本的Navigate函數除了第一個參數外,其它都是ref類型的,需要顯式地寫ref才能調用。一般要使之導向到某個頁面,先設置一個空對象,object objNull=null;然后
webBrowser.Navigate(strPage, ref objNull, ref objNull, ref objNull, ref objNull);
即可。具體其它四個參數可參考相關文檔。
還有一個常用的功能,就是怎么讓瀏覽器顯示自己的html文檔,一個方法是用DOM里根元素的innerText:
((mshtml.HTMLDocumentClass)webBrowser.Document).documentElement.innerText=sHTML;
相當用於Javascript設置網頁的代碼。這種方法方便是方便,但是有很多問題,寫入的大部分Javascript函數都沒法正常使用,即使用<script defer>似乎也沒用;這樣不能用前進、后退來進行歷史瀏覽;查看源代碼根本看不到什么……其實最致命的就是 Javascript沒法用,無法滿足一般的需要。
第二個方法是把自己的網頁寫到一個臨時文件,然后navigate到這個文件,Foxmail是這樣做的。這樣做的缺點是會產生很多臨時文件,文件在磁盤上的讀寫需要耗費較多時間,而且要記得及時清理。
第三個方法是用COM中IPersistStreamInit之類的,使用流操作,據說Outlook便是這樣做的。這樣顯然是最好的,在內存中形成網頁進行操作速度也很快。但我在.Net里找不到這個接口,所以不知道如何實現。
3、與應用程序交互
網頁與應用程序的交互不外乎是網頁上點擊某鏈接,或通過其它途徑,比如表單提交等,使瀏覽器導航至新的鏈接,所以我通過BeforeNavigate2這個事件來,該事件有flags、headers、postData、targetFrameName、uRL等屬性,足夠我們進行處理。這樣我們程序就好像一個WebServer,可以處理網頁上的鏈接、提交的表單等等。然后把使瀏覽器導航至處理后產生的結果網頁。
又在網上看到有人用System.Runtime.InteropServices.Expando.IExpando:
mshtml.HTMLDocumentClass doc2=(mshtml.HTMLDocumentClass)webBrowser.Document;
System.Runtime.InteropServices.Expando.IExpando ex=(System.Runtime.InteropServices.Expando.IExpando)doc2;
System.Reflection.PropertyInfo piform1=ex.AddProperty("Form1");
piform1.SetValue(doc2,this,null);
這樣,在網頁中的document.Form1就是這個WinForm的Control了。你可以用腳本來調用Form1!這也不失為一個極妙的方法。
4、應用程序操作瀏覽器/網頁:
WebBrowser瀏覽器控件提供了一些函數,如ExecWB,可以使瀏覽器執行內部定義的一些操作,如執行另存為:
webBrowser.ExecWB( SHDocVw.OLECMDID.OLECMDID_SAVEAS, SHDocVw.OLECMDEXECOPT.OLECMDEXECOPT_DODEFAULT, ref objNull, ref objNull );
但似乎這里按取消的話會拋出一個異常,所以我用一個空的try{}catch(Exception){}來捕獲它,就不會有錯誤了。
還可以用DOM里的一些方法來操作網頁,舉個例子,可以這樣調用網頁中寫好的一個Javascript函數func():
((mshtml.HTMLDocumentClass)webBrowser.Document.DomDocument).parentWindow.execScript( "func()", "JScript" );
webBrowser1.Document.InvokeScript("__doPostBack", new object[] { "PageBar","2" });
暫時就這樣,比較常用的也就是這些了。其它的就讓我們在繼續使用中慢慢琢磨體會吧。
WebBrowser 控件
WebBrowser 控件可以在應用程序中承載網頁以及支持瀏覽器的其他文檔。例如,可以使用 WebBrowser 控件在應用程序中提供基於 HTML 的集成用戶幫助或 Web 瀏覽功能。
WebBrowser控件可以讓你的用戶瀏覽一個特定的網頁。但它不是一個完整的瀏覽器,因為它沒有地址欄,收藏夾 ,選項卡等等。你可以把它當做HTML中的iframe,但它提供了更豐富的界面。你可以通過兩個手指收縮(和雙擊)來進行縮放,平移和滾動是自動內置的,你無須自己實現。
這個控件另一個很棒的特性是它可以加載本地和網絡中的內容。這意味着如果我有很多HTML文件(也許是文檔),那么我不需要為我的應用程序去重新創建這些內容。相反,我可以將這些HTML頁面嵌入到我的應用程序中,並在本地(電話中)加載他們而不是依靠一個可能會出現問題的數據連接。
WebBrowser 控件可提供下列功能:
導航:Source、Navigate、NavigateToStream、NavigateToString 和 Refresh。
導航生存期:Navigating、Navigated 和 LoadCompleted。
導航日記:CanGoBack、GoBack、CanGoForward 和 GoForward。
WPF/HTML 互操作:InvokeScript、ObjectForScripting 和 Document。
1)打開網絡上指定的URL頁面
private void button4_Click(object sender, RoutedEventArgs e)
{
webBrowser1.Navigate(new Uri("http://www.it100.info", UriKind.Absolute));//UriKind=UriKind.Absolute
}
WebBrowser 控件用法詳解
下面的代碼假設你已經建立了一個Windows Form,上面有一個WebBrowser名為“webBrowser”。
Study Case 1:用WinForm的Event Handler響應Web頁面的事件
現在有這樣一個Windows Application,它的界面上只有一個WebBrowser,顯示一個本地的HTML文件作為界面。現在的問題是,所有邏輯都可以放在
HTML文件里,唯獨“關閉”按鈕遇到了困難——通常,Web頁面是沒有辦法直接控制瀏覽器的,更不用說結束這個WinForm程序了。
但是,在.Net 2.0當中,“由Windows Form響應Web頁面的事件”已經成為了現實。
在.Net 2.0中,整個HTML文檔以及其包含的各個HTML元素,都和一個個HtmlDocument、HtmlElement之類的.Net對象對應。因此只要找到這個“關閉”
按鈕對應的HtmlElement對象,為其click事件添加Event Handler即可。
假設HTML源代碼如下:
<html>
<body>
<input type="button" id="btnClose" value="關閉" />
</body>
</html>
那么找出該按鈕並為之添加Event Handler的代碼如下:
HtmlDocument htmlDoc = webBrowser.Document;
HtmlElement btnElement = htmlDoc.All["btnClose"];
if (btnElement != null)
{
btnElement.click += new HtmlElementEventHandler(HtmlBtnClose_Click);
}
其中HtmlBtnClose_Click是按下Web按鈕時的Event Handler。
很簡單吧?那么稍稍高級一點的——我們都知道一個HTML元素可能有很多各種各樣的事件,而HtmlElement這個類只給出最常用、共通的幾個。那么,
如何響應其他事件呢?這也很簡單,只需要調用HtmlElement的AttachEventHandler就可以了:
btnElement.AttachEventHandler("onclick", new EventHandler(HtmlBtnClose_Click));
//這一句等價於上面的btnElement.click += new HtmlElementEventHandler(HtmlBtnClose_Click);
對於其他事件,把"onclick"換成該事件的名字就可以了。例如:
formElement.AttachEventHandler("onsubmit", new EventHandler(HtmlForm_Submit));
Study Case 2:表單(form)的自動填寫和提交
要使我們的WebBrowser具有自動填表、甚至自動提交的功能,並不困難。
假設有一個最簡單的登錄頁面,輸入用戶名密碼,點“登錄”按鈕即可登錄。已知用戶名輸入框的id(或Name,下同)是username,密碼輸入框的id
是password,“登錄”按鈕的id是submitbutton,那么我們只需要在webBrowser的DocumentCompleted事件中使用下面的代碼即可:
HtmlElement btnSubmit = webBrowser.Document.All["submitbutton"];
HtmlElement tbUserid = webBrowser.Document.All["username"];
HtmlElement tbPasswd = webBrowser.Document.All["password"];
if (tbUserid == null || tbPasswd == null || btnSubmit == null)
return;
tbUserid.SetAttribute("value", "smalldust");
tbPasswd.SetAttribute("value", "12345678");
btnSubmit.InvokeMember("click");
這里我們用SetAttribute來設置文本框的“value”屬性,用InvokeMember來調用了按鈕的“click”方法。因為不同的Html元素,其擁有的屬性和方
法也不盡相同,所以.Net 2.0提供了統一的HtmlElement來概括各種Html元素的同時,提供了這兩個方法以調用元素特有的功能。關於各種Html元素的
屬性和方法一覽,可以查閱MSDN的DHTML Reference。
※關於表單的提交,的確還有另一種方法就是獲取form元素而不是button,並用form元素的submit方法:
HtmlElement formLogin = webBrowser.Document.Forms["loginForm"];
//……
formLogin.InvokeMember("submit");
本文之所以沒有推薦這種方法,是因為現在的網頁,很多都在submit按鈕上添加onclick事件,以對提交的內容做最基本的驗證。如果直接使用form的
submit方法,這些驗證代碼就得不到執行,有可能會引起錯誤。
Study Case 3:查找並選擇文本
這次我們希望實現一個和IE一模一樣的查找功能,以對Web頁面內的文字進行查找。
文本查找要借助於TextRange對象的findText方法。但是,.Net里並沒有這個對象。這是因為,.Net 2.0提供的HtmlDocument,HtmlWindow,
HtmlElement等類,只不過是對原有mshtml這個COM組件的不完整封裝,只提供了mshtml的部分功能。所以許多時候,我們仍舊要借助mshtml來實現我
們需要的功能。好在這些.Net類都提供了DomDocument這個屬性,使得我們很容易把.Net對象轉換為COM對象使用。下面的代碼演示了如何查找Web頁面
的文本。
(需要添加mshtml的引用,並加上using mshtml;)
public partial class SearchDemo : Form
{
// 建立一個查找用的TextRange(IHTMLTxtRange接口)
private IHTMLTxtRange searchRange = null;
public SearchDemo()
{
InitializeComponent();
}
private void btnSearch_Click(object sender, EventArgs e)
{
// Document的DomDocument屬性,就是該對象內部的COM對象。
IHTMLDocument2 document = (IHTMLDocument2)webBrowser.Document.DomDocument;
string keyword = txtKeyword.Text.Trim();
if (keyword == "")
return;
// IE的查找邏輯就是,如果有選區,就從當前選區開頭+1字符處開始查找;沒有的話就從頁面最初開始查找。
// 這個邏輯其實是有點不大恰當的,我們這里不用管,和IE一致即可。
if (document.selection.type.ToLower() != "none")
{
searchRange = (IHTMLTxtRange)document.selection.createRange();
searchRange.collapse(true);
searchRange.moveStart("character", 1);
}
else
{
IHTMLBodyElement body = (IHTMLBodyElement)document.body;
searchRange = (IHTMLTxtRange)body.createTextRange();
}
// 如果找到了,就選取(高亮顯示)該關鍵字;否則彈出消息。
if (searchRange.findText(keyword, 1, 0))
{
searchRange.select();
}
else
{
MessageBox.Show("已搜索到文檔結尾。");
}
}
}
到此為止,簡單的查找就搞定了。至於替換功能,看了下一個例子,我相信你就可以觸類旁通輕松搞定了。
=============================
Study Case 4:高亮顯示
上一個例子中我們學會了查找文本——究跟到底,對Web頁面還是只讀不寫。那么,如果說要把所有的搜索結果高亮顯示呢?我們很快會想到把所有匹
配的文字顏色、背景改一下就可以了。
首先想到的可能是直接修改HTML文本吧……但是,與SourceCode的高亮顯示不同,我們需要並且只需要高亮頁面中的文本部分。HTML標簽、腳本代碼
等等是絕對不應該去改動的。因此我們不能把整個頁面的Source Code讀進來然后replace,那樣有破壞HTML文件結構的可能;我們只能在能夠分離出
文本與其他內容(標簽,腳本……)的前提下進行。
具體方法有很多,下面提供兩個比較簡單的方法。
方法一:使用TextRange(IHTMLTxtRange)
有了上一個Case的基礎,相信大家立刻會想到使用TextRange。沒錯,TextRange除了提供查找方法之外,還提供了一個pasteHTML方法,以指定的HTML
文本替換當前TextRange中的內容。代碼片斷如下:
public partial class HilightDemo : Form
{
// 定義高亮顯示效果的標簽。
string tagBefore = "<span style='background-color:yellow;color:black'>";
string tagAfter = "</span>";
// ……
private void btnHilight_Click(object sender, EventArgs e)
{
HtmlDocument htmlDoc = webBrowser.Document;
string keyword = txtKeyword.Text.Trim();
if (keyword == "")
return;
object oTextRange = htmlDoc.Body.InvokeMember("createTextRange");
mshtml.IHTMLTxtRange txtrange = oTextRange as mshtml.IHTMLTxtRange;
while (txtrange.findText(keyword, 1, 4))
{
try
{
txtrange.pasteHTML(tagBefore + keyword + tagAfter);
}
catch { }
txtrange.collapse(false);
}
}
}
※這段代碼里獲取IHTMLTxtRange的方式和上面的例子稍稍不同,其實所謂條條大路通羅馬,本質是一樣的。
方法二:使用DOM(文檔對象模型)
將HTML文檔解析為DOM,然后遍歷每個節點,在其中搜索關鍵字並進行相應替換處理即可。
public partial class HilightDemo : Form
{
//……
private void btnHilight_Click(object sender, EventArgs e)
{
HTMLDocument document = (HTMLDocument)webBrowser.Document.DomDocument;
IHTMLDOMNode bodyNode = (IHTMLDOMNode)webBrowser.Document.Body.DomElement;
string keyword = txtKeyword.Text.Trim();
if (keyword == "")
return;
HilightText(document, bodyNode, keyword);
}
private void HilightText(HTMLDocument document, IHTMLDOMNode node, string keyword)
{
// nodeType = 3:text節點
if (node.nodeType == 3)
{
string nodeText = node.nodeValue.ToString();
// 如果找到了關鍵字
if (nodeText.Contains(keyword))
{
IHTMLDOMNode parentNode = node.parentNode;
// 將關鍵字作為分隔符,將文本分離,並逐個添加到原text節點的父節點
string[] result = nodeText.Split(new string[] { keyword }, StringSplitOptions.None);
for (int i = 0; i < result.Length - 1; i++)
{
if (result[i] != "")
{
IHTMLDOMNode txtNode = document.createTextNode(result[i]);
parentNode.insertBefore(txtNode, node);
}
IHTMLDOMNode orgNode = document.createTextNode(keyword);
IHTMLDOMNode hilightedNode = (IHTMLDOMNode)document.createElement("SPAN");
IHTMLStyle style = ((IHTMLElement)hilightedNode).style;
style.color = "black";
style.backgroundColor = "yellow";
hilightedNode.appendChild(orgNode);
parentNode.insertBefore(hilightedNode, node);
}
if (result[result.Length - 1] != "")
{
IHTMLDOMNode postNode = document.createTextNode(result[result.Length - 1]);
parentNode.insertBefore(postNode, node);
}
parentNode.removeChild(node);
} // End of nodeText.Contains(keyword)
}
else
{
// 如果不是text節點,則遞歸搜索其子節點
IHTMLDOMChildrenCollection childNodes = node.childNodes as IHTMLDOMChildrenCollection;
foreach (IHTMLDOMNode n in childNodes)
{
HilightText(document, n, keyword);
}
}
}
}
上面的兩段代碼都是為了清晰易懂而精簡得不能再簡的,有很多地方很不完善。比如,沒考慮到如何從高亮顯示狀態復原;也沒有大小寫匹配等等。
當然,掌握了原理之后相信這些都不會太難。
這兩種方法各有優缺點:
使用TextRange較輕量迅速,而且有一個特長,就是可以把跨標簽(Tag)的關鍵字挑出來。例如,有這么一段HTML:
<b>Hel</b>lo World!
先不管作者出於什么目的讓Hel三個字母成為粗體,總之顯示在頁面上的是一句“Hello World!”。在我們希望高亮頁面中的“Hello”這個關鍵字時
,如果用DOM分析的話,會得出含有“Hel”的<b>節點和文本節點“lo World!”兩個節點,因此無法將其挑出來。而TextRange則能正確識別,將其設
置為高亮。因此也可以說TextRange是只和文本有關,和HTML語法結構無關的對象。
但是,TextRange也有其致命缺點,加亮容易,反向的話就很難。換句話說,去除高亮顯示的時候不能再用TextRange,而需要采用其他方法。
而DOM方法則正好相反, 由於DOM的樹狀結構特性,雖然不能(或者很難)跨越Tag搜索關鍵字,但是去除高亮顯示並不繁瑣。
Study Case 5:與腳本的互操作
在Case 1當中,我們已經看到,Web頁面的HTML元素的事件,可以由Windows Form端來響應,可以在某種程度上看作是Web頁面調用WinForm;那么反過
來,WinForm除了可以直接訪問Web頁面的HTML元素之外,能否調用Web頁面里的各種Script呢?
首先是調用Web頁面的腳本中已經定義好的函數。假設HTML中有如下Javascript:
function DoAdd(a, b) {
return a + b;
}
那么,我們要在WinForm調用它,只需如下代碼即可:
object oSum = webBrowser.Document.InvokeScript("DoAdd", new object[] { 1, 2 });
int sum = Convert.ToInt32(oSum);
其次,如果我們想執行一段Web頁面中原本沒有的腳本,該怎么做呢?這次.Net的類沒有提供,看來還要依靠COM了。IHTMLWindow2可以將任意的字符
串作為腳本代碼來執行。
string scriptline01 = @"function ShowPageInfo() {";
string scriptline02 = @" var numLinks = document.links.length; ";
string scriptline03 = @" var numForms = document.forms.length; ";
string scriptline04 = @" var numImages = document.images.length; ";
string scriptline05 = @" var numScripts = document.scripts.length; ";
string scriptline06 = @" alert('網頁的統計結果:\r\n鏈接數:' + numLinks + ";
string scriptline07 = @" '\r\n表單數:' + numForms + ";
string scriptline08 = @" '\r\n圖像數:' + numImages + ";
string scriptline09 = @" '\r\n腳本數:' + numScripts);}";
string scriptline10 = @"ShowPageInfo();";
string strScript = scriptline01 + scriptline02 + scriptline03 + scriptline04 + scriptline05 +
scriptline06 + scriptline07 + scriptline08 + scriptline09 + scriptline10;
IHTMLWindow2 win = (IHTMLWindow2)webBrowser.Document.Window.DomWindow;
win.execScript(strScript, "Javascript");http://www.xmlasp.net/n1670c13.aspx
http://hi.baidu.com/motiansen/blog/item/9e99a518233ca3b24aedbca9.html
==================
使用ObjectForScripting屬性,可啟用 WebBrowser 控制項所裝載之 Web 網頁與包含 WebBrowser 控制項之應用程式間的通訊。
這個屬性可讓您整合動態超文字標記語言 (DHTML) 程式碼與用戶端應用程式程式碼。
指定給這個屬性的物件可讓 Web 網頁指令碼做為 window.external 物件,這個物件是為了存取主應用程式而提供的內建 DOM 物件。
private void btnScriptEvent_Click(object sender, EventArgs e)
{
webBrowser1.ObjectForScripting = this;
string szWebBrowserText = "<html>" +
"<head>" +
"<title></title>"+
"</head>" +
"<body onkeydown=\"KeyDown()\" oncontextmenu=\"event.returnValue=false\">"+
"Please enter your name:<br/>"+
"<input type='text' name='Name'/><br/>"+
"<font onClick='window.external.ClickEvent(Name.value)'>Click Here</font>"+
"</body></html>";
webBrowser1.DocumentText = szWebBrowserText;
}
public void ClickEvent(string userName)
{
// Simply echo out the name that the user typed in the input box of the HTML page
if (System.Threading.Thread.CurrentThread.CurrentUICulture.TextInfo.IsRightToLeft == true)
MessageBox.Show("Hello " + userName, "Managed Web Browser Sample", MessageBoxButtons.OK,
MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, MessageBoxOptions.RightAlign | MessageBoxOptions.RtlReading);
else
MessageBox.Show("Hello " + userName, "Managed Web Browser Sample", MessageBoxButtons.OK,
MessageBoxIcon.Information, MessageBoxDefaultButton.Button1);
}
= szWebBrowserText;
==================================
異常類型 條件
ArgumentException
設置該屬性時指定的值為非公共類型的實例。
- 或 -
設置該屬性時指定的值為非 COM 可見的類型的實例。有關更多信息,請參見 Marshal.IsTypeVisibleFromCom。
備注
使用該屬性啟用 WebBrowser 控件承載的網頁與包含 WebBrowser 控件的應用程序之間的通信。使用該屬性可以將動態 HTML (DHTML) 代碼與客戶端
應用程序代碼集成在一起。為該屬性指定的對象可作為 window.external 對象(用於主機訪問的內置 DOM 對象)用於網頁腳本。
可以將此屬性設置為希望其公共屬性和方法可用於腳本代碼的任何 COM 可見的對象。可以通過使用 ComVisibleAttribute 對類進行標記使其成為
COM 可見的類。
若要從客戶端應用程序代碼調用網頁中定義的函數,請使用可從 Document 屬性檢索的 HtmlDocument 對象的 HtmlDocument.InvokeScript 方法。
示例
下面的代碼示例演示如何使用 ObjectForScripting 屬性。在該示例中,ObjectForScripting 屬性被設置為當前窗體。
---------
using System;
using System.Windows.Forms;
using System.Security.Permissions;
[PermissionSet(SecurityAction.Demand, Name="FullTrust")]
[System.Runtime.InteropServices.ComVisibleAttribute(true)]
public class Form1 : Form
{
private WebBrowser webBrowser1 = new WebBrowser();
private Button button1 = new Button();
[STAThread]
public static void Main()
{
Application.EnableVisualStyles();
Application.Run(new Form1());
}
public Form1()
{
button1.Text = "call script code from client code";
button1.Dock = DockStyle.Top;
button1.Click += new EventHandler(button1_Click);
webBrowser1.Dock = DockStyle.Fill;
Controls.Add(webBrowser1);
Controls.Add(button1);
Load += new EventHandler(Form1_Load);
}
private void Form1_Load(object sender, EventArgs e)
{
webBrowser1.AllowWebBrowserDrop = false;
webBrowser1.IsWebBrowserContextMenuEnabled = false;
webBrowser1.WebBrowserShortcutsEnabled = false;
webBrowser1.ObjectForScripting = this;
// Uncomment the following line when you are finished debugging.
//webBrowser1.ScriptErrorsSuppressed = true;
webBrowser1.DocumentText =
"<html><head><script>" +
"function test(message) { alert(message); }" +
"</script></head><body><button " +
"onclick=\"window.external.Test('called from script code')\">" +
"call client code from script code</button>" +
"</body></html>";
}
public void Test(String message)
{
MessageBox.Show(message, "client code");
}
private void button1_Click(object sender, EventArgs e)
{
webBrowser1.Document.InvokeScript("test",
new String[] { "called from client code" });
}
}
---------------------------------------------
// Navigates to the URL in the address box when
// the ENTER key is pressed while the ToolStripTextBox has focus.
private void toolStripTextBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
Navigate(toolStripTextBox1.Text);
}
}
// Navigates to the URL in the address box when
// the Go button is clicked.
private void goButton_Click(object sender, EventArgs e)
{
Navigate(toolStripTextBox1.Text);
}
// Navigates to the given URL if it is valid.
private void Navigate(String address)
{
if (String.IsNullOrEmpty(address)) return;
if (address.Equals("about:blank")) return;
if (!address.StartsWith("http://") &&
!address.StartsWith("https://"))
{
address = "http://" + address;
}
try
{
webBrowser1.Navigate(new Uri(address));
}
catch (System.UriFormatException)
{
return;
}
}
// Updates the URL in TextBoxAddress upon navigation.
private void webBrowser1_Navigated(object sender,
WebBrowserNavigatedEventArgs e)
{
toolStripTextBox1.Text = webBrowser1.Url.ToString();
}
====================================================================================
HtmlElement.DomElement 屬性
屬性值
元素的 COM IUnknown 指針,可以將其強制轉換為 HTML 元素接口中的某一個接口,如 IHTMLElement。
備注
HtmlElement 為 Internet Explorer 文檔對象模型 (DOM) 的包裝,它是用組件對象模型 (COM) 編寫而成。如果需要訪問基礎 COM 接口中的未公開
屬性或方法(如 IHTMLElement),可以使用此對象查詢它們。
為了使用非托管接口,需要將 MSHTML 庫 (mshtml.dll) 導入到應用程序中。但是,也可以使用 Invoke 方法執行未公開屬性和方法。
示例
下面的代碼示例使用非托管接口獲取當前選定的文本,並使用由用戶選擇的 URL 將其轉換為超鏈接。編寫此代碼時,假定窗體擁有一個名為
WebBrowser1 的 WebBrowser 控件,並假定已經以引用的形式將非托管 MSHTML 庫添加到項目中。
C# 復制代碼
private void CreateHyperlinkFromSelection()
{
if (webBrowser1.Document != null)
{
mshtml.IHTMLDocument2 iDoc = (mshtml.IHTMLDocument2)webBrowser1.Document.DomDocument;
if (iDoc != null)
{
mshtml.IHTMLSelectionObject iSelect = iDoc.selection;
if (iSelect == null)
{
MessageBox.Show("Please select some text before using this command.");
return;
}
mshtml.IHTMLTxtRange txtRange = (mshtml.IHTMLTxtRange)iSelect.createRange();
// Create the link.
if (txtRange.queryCommandEnabled("CreateLink"))
{
Object o = null;
txtRange.execCommand("CreateLink", true, o);
}
}
}
}
http://msdn.microsoft.com/zh-cn/library/system.windows.forms.htmlelement.domelement(VS.80).aspx
===========================================================
使用webbrowser和mshtml.dll獲取網頁源代碼的問題
懸賞分:100 - 解決時間:2006-7-19 16:52
我使用C#做一個程序,其中涉及到一個功能,在輸入指定網址之后,需要獲取html源代碼進行分析。
我使用了webbrowser控件和mshtml.dll
但是只能獲取到普通頁面的源代碼
一旦采集帶有cookie控制的頁面就會失敗。
誰能幫幫忙?
我對於webbrowser的使用並不很清楚,這個空間是否能直接獲取html代碼呢?
mshtml.dll說是可以對html代碼進行分析。但如何使用?
有誰能給出說明和源代碼,感激不盡。
問題補充:我使用以下代碼獲取webbrowser中的html,但是有個很奇怪的問題。我每次點完按鈕都會發現文本框中顯示的html都不全,而且都把同一
頁面的html顯示了很多遍。如果頁面內容較大則會引起程序死掉。
為什么呢?
提問者: willgo - 助理 二級 最佳答案
private void button1_Click(object sender, System.EventArgs e) {
object url=\"http://www.google.com\";
object nothing=null;
this.axWebBrowser1.Navigate2(ref url,ref nothing,ref nothing,ref nothing,ref nothing);
this.axWebBrowser1.DownloadComplete+=new System.EventHandler(this.button2_Click);
}
private void button2_Click(object sender, System.EventArgs e) {
this.textBox1.Text=\"\";
mshtml.IHTMLDocument2 doc=(mshtml.IHTMLDocument2)this.axWebBrowser1.Document;
mshtml.IHTMLElementCollection all=doc.all;
System.Collections.IEnumerator enumerator=all.GetEnumerator();
while(enumerator.MoveNext() && enumerator.Current!=null)
{
mshtml.IHTMLElement element=(mshtml.IHTMLElement)(enumerator.Current);
if(this.checkBox1.Checked==true)
{
this.textBox1.Text+=\"\\r\\n\\r\\n\"+element.innerHTML;
}
else
{
this.textBox1.Text+=\"\\r\\n\\r\\n\"+element.outerHTML;
}
}
}
=============
注意 本例程中使用了一個未公開的GUID,其在將來的系統中可以發生變更。
1、定義 IOleCommandTarget 接口
為定義一個.NET接口以獲得關於一個COM接口的參考,請遵從下列步驟:
1) 賦予.NET接口相應的COM接口的GUID值;
2) 包含對接口中所有方法的類型聲明;
3) 包含對Mshtml.dll和Shdocvw.dll文件的參考,在Visual C# .NET工程中操作,請遵從:
A. 在項目菜單下單擊“添加引用”;
B. 單擊“COM” 選項卡;
C. 雙擊“Microsoft HTML Object Library” 和“Microsoft Internet Controls”。