2011-09-30 14 views
7

Tôi đang cố gắng thực hiện những gì họ giải thích trên this bài viết trong phần Controlling Download and Execution. Tôi hiểu số Web Browser Control trong ngữ cảnh đó không phải là số WebBrowser của .NET.Triển khai IDispatch :: Gọi để được gọi bằng điều khiển WebBrowser

Điều tôi đang cố gắng làm là giành quyền kiểm soát những nội dung tải xuống kiểm soát WebBrowser. Tôi đã tìm kiếm điều này rất nhiều và luôn luôn en up trong csEXWB, trong đó có một mã rất lớn mà tôi chỉ không thể giải mã.

Những gì tôi đã làm cho đến nay là kế thừa NET của WebBrowser, hãy thừa hưởng lớp com của tôi có thể nhìn thấy bằng cách sử dụng các thuộc tính [ComVisible(true)], thêm phương pháp này để lớp học của tôi (lấy từ csEXWB):

[DispId(HTMLDispIDs.DISPID_AMBIENT_DLCONTROL)] 
    public int Idispatch_AmbiantDlControl_Invoke_Handler() 
    { 
     return (int)m_DLCtlFlags; 
    } 

Và sau đó gọi dòng mã này, nơi Browser là một thể hiện của lớp được thừa kế của tôi:

IfacesEnumsStructsClasses.IOleControl oleControl = Browser.ActiveXInstance as IfacesEnumsStructsClasses.IOleControl; 
oleControl.OnAmbientPropertyChange(IfacesEnumsStructsClasses.HTMLDispIDs.DISPID_AMBIENT_DLCONTROL); 

Vì vậy, những gì tôi hy vọng là các oleControl sẽ gọi phương thức Idispatch_AmbiantDlControl_Invoke_Handler của tôi, mà nó không. Tôi không biết làm thế nào, và điều này có lẽ là những gì mã của tôi là mất tích, là oleControl nghĩa vụ phải biết về đối tượng để gọi phương pháp Idispatch_AmbiantDlControl_Invoke_Handler của tôi.

Bài viết tôi đã liên kết ở trên nói là it will call your IDispatch::Invoke. Nó có nghĩa là gì bởi your. Làm cách nào để tôi biết oleControl đối tượng nào là IDispatch của tôi. Hy vọng tôi có ý nghĩa gì.

+0

Bạn không chặt chẽ, tùy chủ nhà là bắt buộc. Một lớp nội bộ có tên là WebBrowserSite trong trường hợp của WebBrowser. Việc ghi đè việc triển khai IDispatch là vấn đề khó, nó được CLR triển khai cho mã được quản lý. Khó để xem cách bạn có thể thực hiện công việc này mà không có mã gốc. –

+0

Vâng, csEXWB được viết bằng C# AFAIK. Bạn có biết bất kỳ nơi nào tôi có thể bắt đầu về cách ghi đè việc triển khai IDispatch không? – Ahmet

+1

Lớp System.Windows.Forms.AmbientProperties được niêm phong. Thời gian từ bỏ trình bao bọc như csEXWB đã làm. –

Trả lời

17

Đây là WebBrowser được tùy chỉnh cho phép bạn thay đổi cờ DLCONTROL.

Đây là một ví dụ mã:

public partial class Form1 : Form 
{ 
    private MyWebBrowser _webBrowser; 

    public Form1() 
    { 
     InitializeComponent(); 

     _webBrowser = new MyWebBrowser(); 
     _webBrowser.Dock = DockStyle.Fill; 

     Controls.Add(_webBrowser); 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     _webBrowser.DownloadControlFlags = (int)WebBrowserDownloadControlFlags.DOWNLOADONLY; 
     _webBrowser.Navigate("http://mysamplewebsite"); 
    } 
} 

Và mã WebBrowser tùy chỉnh:

public class MyWebBrowser : WebBrowser 
{ 
    private const int DISPID_AMBIENT_DLCONTROL = -5512; 
    private int _downloadControlFlags; 

    // we want our site class, not the default one 
    protected override WebBrowserSiteBase CreateWebBrowserSiteBase() 
    { 
     return new MyWebBrowserSite(this); 
    } 

    [DispId(DISPID_AMBIENT_DLCONTROL)] 
    public int DownloadControlFlags 
    { 
     get 
     { 
      return _downloadControlFlags; 
     } 
     set 
     { 
      if (_downloadControlFlags == value) 
       return; 

      _downloadControlFlags = value; 
      IOleControl ctl = (IOleControl)ActiveXInstance; 
      ctl.OnAmbientPropertyChange(DISPID_AMBIENT_DLCONTROL); 
     } 
    } 

    protected class MyWebBrowserSite : WebBrowserSite, IReflect 
    { 
     private Dictionary<int, PropertyInfo> _dispidCache; 
     private MyWebBrowser _host; 

     public MyWebBrowserSite(MyWebBrowser host) 
      : base(host) 
     { 
      _host = host; 
     } 

     object IReflect.InvokeMember(string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] namedParameters) 
     { 
      object ret = null; 
      // Check direct IDispatch call using a dispid (see http://msdn.microsoft.com/en-us/library/de3dhzwy.aspx) 
      const string dispidToken = "[DISPID="; 
      if (name.StartsWith(dispidToken)) 
      { 
       int dispid = int.Parse(name.Substring(dispidToken.Length, name.Length - dispidToken.Length - 1)); 
       if (_dispidCache == null) 
       { 
        // WebBrowser has many properties, so we build a dispid cache on it 
        _dispidCache = new Dictionary<int, PropertyInfo>(); 
        foreach (PropertyInfo pi in _host.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)) 
        { 
         if ((!pi.CanRead) || (pi.GetIndexParameters().Length > 0)) 
          continue; 

         object[] atts = pi.GetCustomAttributes(typeof(DispIdAttribute), true); 
         if ((atts != null) && (atts.Length > 0)) 
         { 
          DispIdAttribute da = (DispIdAttribute)atts[0]; 
          _dispidCache[da.Value] = pi; 
         } 
        } 
       } 

       PropertyInfo property; 
       if (_dispidCache.TryGetValue(dispid, out property)) 
       { 
        ret = property.GetValue(_host, null); 
       } 
      } 
      return ret; 
     } 

     FieldInfo[] IReflect.GetFields(BindingFlags bindingAttr) 
     { 
      return GetType().GetFields(bindingAttr); 
     } 

     MethodInfo[] IReflect.GetMethods(BindingFlags bindingAttr) 
     { 
      return GetType().GetMethods(bindingAttr); 
     } 

     PropertyInfo[] IReflect.GetProperties(BindingFlags bindingAttr) 
     { 
      return GetType().GetProperties(bindingAttr); 
     } 

     FieldInfo IReflect.GetField(string name, BindingFlags bindingAttr) 
     { 
      throw new NotImplementedException(); 
     } 

     MemberInfo[] IReflect.GetMember(string name, BindingFlags bindingAttr) 
     { 
      throw new NotImplementedException(); 
     } 

     MemberInfo[] IReflect.GetMembers(BindingFlags bindingAttr) 
     { 
      throw new NotImplementedException(); 
     } 

     MethodInfo IReflect.GetMethod(string name, BindingFlags bindingAttr) 
     { 
      throw new NotImplementedException(); 
     } 

     MethodInfo IReflect.GetMethod(string name, BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers) 
     { 
      throw new NotImplementedException(); 
     } 

     PropertyInfo IReflect.GetProperty(string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers) 
     { 
      throw new NotImplementedException(); 
     } 

     PropertyInfo IReflect.GetProperty(string name, BindingFlags bindingAttr) 
     { 
      throw new NotImplementedException(); 
     } 

     Type IReflect.UnderlyingSystemType 
     { 
      get { throw new NotImplementedException(); } 
     } 
    } 

    [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("B196B288-BAB4-101A-B69C-00AA00341D07")] 
    internal interface IOleControl 
    { 
     void Reserved0(); 
     void Reserved1(); 
     void OnAmbientPropertyChange(int dispID); 
     void Reserved2(); 
    } 
} 

[Flags] 
public enum WebBrowserDownloadControlFlags: uint 
{ 
    DLIMAGES       = 0x00000010, 
    VIDEOS       = 0x00000020, 
    BGSOUNDS       = 0x00000040, 
    NO_SCRIPTS      = 0x00000080, 
    NO_JAVA       = 0x00000100, 
    NO_RUNACTIVEXCTLS     = 0x00000200, 
    NO_DLACTIVEXCTLS     = 0x00000400, 
    DOWNLOADONLY      = 0x00000800, 
    NO_FRAMEDOWNLOAD     = 0x00001000, 
    RESYNCHRONIZE      = 0x00002000, 
    PRAGMA_NO_CACHE     = 0x00004000, 
    NO_BEHAVIORS      = 0x00008000, 
    NO_METACHARSET     = 0x00010000, 
    URL_ENCODING_DISABLE_UTF8   = 0x00020000, 
    URL_ENCODING_ENABLE_UTF8   = 0x00040000, 
    NOFRAMES       = 0x00080000, 
    FORCEOFFLINE      = 0x10000000, 
    NO_CLIENTPULL      = 0x20000000, 
    SILENT       = 0x40000000, 
    OFFLINEIFNOTCONNECTED    = 0x80000000, 
    OFFLINE       = OFFLINEIFNOTCONNECTED, 
} 
+0

Cảm ơn bạn rất nhiều !!! Điều này thực sự dễ dàng hơn rất nhiều so với tôi mong đợi. Tôi vẫn cần phải nhìn vào mã này một chút gần hơn nhưng tôi đã thử nghiệm nó và nó đã làm việc :). – Ahmet

Các vấn đề liên quan