设置webbrowser中加载的自定义HTML的URL

时间:2011-08-23 21:27:07

标签: c# webbrowser-control

我在webbrowser控件中加载了一些html文本(它的uri变成“about:blank”)。现在我想将其Uri设置为其他东西而不导航到该链接。

我该怎么做

2 个答案:

答案 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:

  1. 使用<base> html标签
  2. 通过实现IMoniker接口(Git回购:[r-aghaei / WebBrowserHtmlContentBaseUrl]

下载

第一个非常简单直接。对于第二个解决方案,我创建了一个令人担忧的示例。您可以在这里找到它:

  

重要的调试说明:要调试应用程序,请通过转到“调试”菜单→Windows→异常设置→搜索System.NotImplementedException→清除复选标记来禁用NotImplementedException。或者,如果引发异常,则可以在“异常”窗口中取消选中该异常。   如果按 Ctrl + F5 ,您应该不会看到任何异常。

注释

  • 使用<base>标签非常容易且更加直接,但是我无法使用它们加载@font-face的相对地址。其余的一切都很好。

  • IMoniker解决方案需要添加对SHDocVw的引用,该引用可以在“引用管理器”窗口的“ COM”选项卡中找到为“ Microsoft Internet控件”。

鸣谢:感谢this postthis post的作者和盛江的其他回答。

解决方案1-使用<base>标签

HTML <base>元素指定用于文档中包含的所有相对URL的基本URL。一个文档中只能有一个元素。

因此,像这样将<base>标记插入<head>中就足够了:

html = html.Replace(@"<head>", $@"<head><base href=""{new Uri(Application.StartupPath)}/""/>");
webBrowser1.DocumentText = html;

这意味着所有相对地址都将使用<base>的href属性进行解析。

解决方案2-实施IMoniker

您可以实现IMoniker接口并仅为GetDisplayNameBindToStorage提供简单的实现。然后使用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();
        }
    }
}