Windows窗体与IDownloadManager Webbrowswer控制 [英] Windows Forms Webbrowswer control with IDownloadManager

查看:2480
本文介绍了Windows窗体与IDownloadManager Webbrowswer控制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用了 Systems.Windows.Forms.Webbrowser 控制和需要覆盖的下载管理器。我跟着指示 的子类的形式和覆盖 CreateWebBrowserSiteBase()

I'm using the Systems.Windows.Forms.Webbrowser control and need to override the download manager. I've followed the instructions here to subclass the form and override CreateWebBrowserSiteBase()

/// <summary>
/// Browser with download manager
/// </summary>
public class MyBrowser : WebBrowser  
{
    /// <summary>
    /// Returns a reference to the unmanaged WebBrowser ActiveX control site,
    /// which you can extend to customize the managed <see ref="T:System.Windows.Forms.WebBrowser"/> control.
    /// </summary>
    /// <returns>
    /// A <see cref="T:System.Windows.Forms.WebBrowser.WebBrowserSite"/> that represents the WebBrowser ActiveX control site.
    /// </returns>
    protected override WebBrowserSiteBase CreateWebBrowserSiteBase()
    {
        var manager = new DownloadWebBrowserSite(this);
        manager.FileDownloading += (sender, args) =>
            {
                if (FileDownloading != null)
                {
                    FileDownloading(this, args);
                }
            };
        return manager;
    }
}

DownloadWebBrowserSite ,我实施的IServiceProvider 提供一个 IDownloadManager 时提出要求。

In the DownloadWebBrowserSite, I implement IServiceProvider to provide an IDownloadManager when requested.

        /// <summary>
        /// Queries for a service
        /// </summary>
        /// <param name="guidService">the service GUID</param>
        /// <param name="riid"></param>
        /// <param name="ppvObject"></param>
        /// <returns></returns>
        public int QueryService(ref Guid guidService, ref Guid riid, out IntPtr ppvObject)
        {
            if ( (guidService == Constants.IID_IDownloadManager && riid == Constants.IID_IDownloadManager ))
            {
                ppvObject = Marshal.GetComInterfaceForObject(_manager, typeof(IDownloadManager));
                return Constants.S_OK;
            }
            ppvObject = IntPtr.Zero;
            return Constants.E_NOINTERFACE;
        }



下载管理器是从上面的例子所

/// <summary>
/// Intercepts downloads of files, to add as PDFs or suppliments
/// </summary>
[ComVisible(true)]
[Guid("bdb9c34c-d0ca-448e-b497-8de62e709744")]
[CLSCompliant(false)]
public class DownloadManager : IDownloadManager
{
    /// <summary>
    /// event called when the browser is about to download a file
    /// </summary>
    public event EventHandler<FileDownloadEventArgs> FileDownloading;

    /// <summary>
    /// Return S_OK (0) so that IE will stop to download the file itself. 
    /// Else the default download user interface is used.
    /// </summary>
    public int Download(IMoniker pmk, IBindCtx pbc, uint dwBindVerb, int grfBINDF, IntPtr pBindInfo,
                        string pszHeaders, string pszRedir, uint uiCP)
    {
        // Get the display name of the pointer to an IMoniker interface that specifies the object to be downloaded.
        string name;
        pmk.GetDisplayName(pbc, null, out name);
        if (!string.IsNullOrEmpty(name))
        {
            Uri url;
            if (Uri.TryCreate(name, UriKind.Absolute, out url))
            {
                if ( FileDownloading != null )
                {
                     FileDownloading(this, new FileDownloadEventArgs(url));
                }
                return Constants.S_OK;
            }
        }
        return 1;
    }
}

的问题是, pmk.GetDisplayName 返回初始URL,而不是项目的网址下载。如果URI指向一个动态页面,如 http://www.example.com/download.php ,我没有收到实际的文件被下载。我需要从标题获取URL,这样我得到我应该要下载的实际文件。

The problem is that the pmk.GetDisplayName returns the initial URL, not the URL of the item to be downloaded. If the URI points to a dynamic page, such as http://www.example.com/download.php, I'm not getting the actual file to be downloaded. I need to get the URL from the header so that I get the actual file I'm supposed to be downloading.

谷歌表示,我要创建一个 IBindStatusCallback 的实施也实现 IHttpNegotiate 的IServiceProvider IID_IHttpNegotiate ,这样我可以看到 IHttpNegotiate.OnResponse 。我已经成功地实施,但是, QueryService的似乎只问过了 IID_IInternetProtocol 从不 IID_IHttpNegotiate

Google indicates that I have to create a IBindStatusCallback implementation that also implements IHttpNegotiate and IServiceProvider to respond to IID_IHttpNegotiate, so that I can see the IHttpNegotiate.OnResponse. I've managed to implement that, however, QueryService only seems to ever ask for IID_IInternetProtocol and never IID_IHttpNegotiate.

任何意见将是巨大的。

推荐答案

您缺少一个电话:CreateBindCtx

Your missing a call to: CreateBindCtx.

以下内容添加到您的下载管理器:

Add the following to your DownloadManager:

   [DllImport("ole32.dll")]
        static extern int CreateBindCtx(uint reserved, out IBindCtx ppbc);



然后确保您在注册回调之前调用它。我在你的下载实现()这个方法如下:

Then make sure you call this before registering your callback. I have implemented this in your Download() method as follows:

public int Download(IMoniker pmk, IBindCtx pbc, uint dwBindVerb, int grfBINDF, IntPtr pBindInfo,
                            string pszHeaders, string pszRedir, uint uiCP)
        {
            // Get the display name of the pointer to an IMoniker interface that specifies the object to be downloaded.
            string name;
            pmk.GetDisplayName(pbc, null, out name);
            if (!string.IsNullOrEmpty(name))
            {
                Uri url;
                if (Uri.TryCreate(name, UriKind.Absolute, out url))
                {
                    Debug.WriteLine("DownloadManager: initial URL is: " + url);
                    CreateBindCtx(0, out pbc);
                    RegisterCallback(pbc, url);
                    BindMonikerToStream(pmk, pbc);

                    return MyBrowser.Constants.S_OK;
                }
            }
            return 1;
        }



有了这个地方,你IHttpNegotiate执行将被调用,你就会有访问响应头。

With this in place, your IHttpNegotiate implementation will be called and you'll have access to the response headers.

这篇关于Windows窗体与IDownloadManager Webbrowswer控制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆