我在webbrowser控件中加载了一些html文本(它的uri变成“about:blank”)。现在我想将其Uri设置为其他东西而不导航到该链接。
我该怎么做
答案 0 :(得分:3)
webbrowser的文档对象通过URL名字对象加载数据。有一个漂亮的图in the MSJ 1996 September issue article "Unified Browsing with ActiveX Extensions Brings the Internet to Your Desktop",展示了关于url标记和浏览器的关系。
您可以通过文档的IPersistStreamInit界面手动将名字对象或流加载到文档中。这就是Winform的webbrowser类在其DocumentStream和DocumentText属性的实现中所做的事情。该文档将调用源的IMoniker :: GetDisplayName来获取url。但是,Windows窗体中的load-from-stream实现不实现IMoniker,并且加载的文档的基址大约为:blank。
有一个关于在http://www.codeproject.com/KB/miscctrl/csEXWB.aspx实现网址名称的示例。在页面上搜索LoadHtmlIntoBrowser(字符串html,字符串sBaseUrl)。
答案 1 :(得分:1)
有两种方法为加载到Web浏览器控件中的自定义html内容设置URL:
<base>
html标签IMoniker
接口(Git回购:[r-aghaei / WebBrowserHtmlContentBaseUrl] 下载
第一个非常简单直接。对于第二个解决方案,我创建了一个令人担忧的示例。您可以在这里找到它:
重要的调试说明:要调试应用程序,请通过转到“调试”菜单→Windows→异常设置→搜索System.NotImplementedException→清除复选标记来禁用
NotImplementedException
。或者,如果引发异常,则可以在“异常”窗口中取消选中该异常。 如果按 Ctrl + F5 ,您应该不会看到任何异常。
注释
使用<base>
标签非常容易且更加直接,但是我无法使用它们加载@font-face
的相对地址。其余的一切都很好。
IMoniker
解决方案需要添加对SHDocVw
的引用,该引用可以在“引用管理器”窗口的“ COM”选项卡中找到为“ Microsoft Internet控件”。
鸣谢:感谢this post,this post的作者和盛江的其他回答。
<base>
标签 HTML <base>
元素指定用于文档中包含的所有相对URL的基本URL。一个文档中只能有一个元素。
因此,像这样将<base>
标记插入<head>
中就足够了:
html = html.Replace(@"<head>", $@"<head><base href=""{new Uri(Application.StartupPath)}/""/>");
webBrowser1.DocumentText = html;
这意味着所有相对地址都将使用<base>
的href属性进行解析。
IMoniker
您可以实现IMoniker
接口并仅为GetDisplayName
和BindToStorage
提供简单的实现。然后使用IWebBrowser2
中的SHDocVw
,可以加载文档并为其设置基本URL。
我为WebBrowser
控件创建了一种扩展方法,它具有以下方法:
void SetHtmlContent(string html, string baseUrl)
具有以下参数:
html
:要在网络浏览器中加载的HTML内容baseUrl
:用于文档的基本URL。它将像真实的网址一样用于解析相对地址。您可以像这样轻松地使用它:
webBrowser1.SetHtmlContent(html, $@"{new Uri(Application.StartupPath)}/");
只需添加对SHDocVw
的引用,然后将以下代码粘贴到您的项目中即可:
using System;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using SHDocVw;
public static class WebBrowserExtensions
{
public static void SetHtmlContent(this System.Windows.Forms.WebBrowser webBrowser, string html, string baseUrl)
{
webBrowser.Navigate("about:blank");
var browser = (IWebBrowser2)webBrowser.ActiveXInstance;
var result = CreateStreamOnHGlobal(Marshal.StringToHGlobalAuto(html), true, out IStream stream);
if ((result != 0) || (stream == null))
return;
var persistentMoniker = browser.Document as IPersistMoniker;
if (persistentMoniker == null)
return;
IBindCtx bindContext = null;
CreateBindCtx((uint)0, out bindContext);
if (bindContext == null)
return;
var loader = new Moniker(baseUrl, html);
persistentMoniker.Load(1, loader, bindContext, (uint)0);
stream = null;
}
[DllImport("ole32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
static extern int CreateStreamOnHGlobal(IntPtr hGlobal, bool fDeleteOnRelease, out IStream istream);
[DllImport("ole32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
static extern int CreateBindCtx([MarshalAs(UnmanagedType.U4)] uint dwReserved, [Out, MarshalAs(UnmanagedType.Interface)] out IBindCtx ppbc);
[ComImport, ComVisible(true)]
[Guid("79EAC9C9-BAF9-11CE-8C82-00AA004BA90B")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
interface IPersistMoniker
{
void GetClassID([In, Out] ref Guid pClassID);
[return: MarshalAs(UnmanagedType.I4)]
[PreserveSig]
int IsDirty();
void Load([In] int fFullyAvailable, [In, MarshalAs(UnmanagedType.Interface)] IMoniker pmk, [In, MarshalAs(UnmanagedType.Interface)] Object pbc, [In, MarshalAs(UnmanagedType.U4)] uint grfMode);
void SaveCompleted([In, MarshalAs(UnmanagedType.Interface)] IMoniker pmk, [In, MarshalAs(UnmanagedType.Interface)] Object pbc);
[return: MarshalAs(UnmanagedType.Interface)]
IMoniker GetCurMoniker();
}
class Moniker : IMoniker
{
public static Guid IID_IStream = new Guid("0000000c-0000-0000-C000-000000000046");
string baseUrl;
IStream stream;
public Moniker(string baseUrl, string content)
{
this.baseUrl = baseUrl;
CreateStreamOnHGlobal(Marshal.StringToHGlobalAuto(content), true, out stream);
}
public void GetDisplayName(IBindCtx pbc, IMoniker pmkToLeft, out string ppszDisplayName)
{
ppszDisplayName = this.baseUrl;
}
public void BindToStorage(IBindCtx pbc, IMoniker pmkToLeft, ref Guid riid, out object ppvObj)
{
ppvObj = null;
if (riid.Equals(IID_IStream))
ppvObj = (IStream)stream; ;
}
public void GetClassID(out Guid pClassID)
{
throw new NotImplementedException();
}
public int IsDirty()
{
throw new NotImplementedException();
}
public void Load(IStream pStm)
{
throw new NotImplementedException();
}
public void Save(IStream pStm, bool fClearDirty)
{
throw new NotImplementedException();
}
public void GetSizeMax(out long pcbSize)
{
throw new NotImplementedException();
}
public void BindToObject(IBindCtx pbc, IMoniker pmkToLeft, ref Guid riidResult, out object ppvResult)
{
throw new NotImplementedException();
}
public void Reduce(IBindCtx pbc, int dwReduceHowFar, ref IMoniker ppmkToLeft, out IMoniker ppmkReduced)
{
throw new NotImplementedException();
}
public void ComposeWith(IMoniker pmkRight, bool fOnlyIfNotGeneric, out IMoniker ppmkComposite)
{
throw new NotImplementedException();
}
public void Enum(bool fForward, out IEnumMoniker ppenumMoniker)
{
throw new NotImplementedException();
}
public int IsEqual(IMoniker pmkOtherMoniker)
{
throw new NotImplementedException();
}
public void Hash(out int pdwHash)
{
throw new NotImplementedException();
}
public int IsRunning(IBindCtx pbc, IMoniker pmkToLeft, IMoniker pmkNewlyRunning)
{
throw new NotImplementedException();
}
public void GetTimeOfLastChange(IBindCtx pbc, IMoniker pmkToLeft, out System.Runtime.InteropServices.ComTypes.FILETIME pFileTime)
{
throw new NotImplementedException();
}
public void Inverse(out IMoniker ppmk)
{
throw new NotImplementedException();
}
public void CommonPrefixWith(IMoniker pmkOther, out IMoniker ppmkPrefix)
{
throw new NotImplementedException();
}
public void RelativePathTo(IMoniker pmkOther, out IMoniker ppmkRelPath)
{
throw new NotImplementedException();
}
public void ParseDisplayName(IBindCtx pbc, IMoniker pmkToLeft, string pszDisplayName, out int pchEaten, out IMoniker ppmkOut)
{
throw new NotImplementedException();
}
public int IsSystemMoniker(out int pdwMksys)
{
throw new NotImplementedException();
}
}
}