2011-09-30 12 views
7

Estoy tratando de hacer lo que explican en el artículo this en la sección Controlling Download and Execution. Entiendo que el Web Browser Control en ese contexto no es .NET WebBrowser.Implementar IDispatch :: Invoke a ser llamado por un control WebBrowser

Lo que estoy tratando de hacer es obtener control sobre lo que descarga el control WebBrowser. He estado buscando esto mucho y siempre estoy en el csEXWB, que tiene un código enorme que no puedo descifrar.

Lo que he hecho hasta ahora se heredan de WebBrowser .NET, que mi com clase heredada visibles mediante el atributo [ComVisible(true)], añadir este método para mi clase (tomado de csEXWB):

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

Y luego llamar a esta línea de código, donde Browser es una instancia de mi clase derivada:

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

Así que lo que espero es que el oleControl llamarán a mi método Idispatch_AmbiantDlControl_Invoke_Handler, que no lo hace. No sé cómo, y esto es probablemente lo que mi código falta, es el oleControl supuestamente para saber en qué objeto llamar a mi método Idispatch_AmbiantDlControl_Invoke_Handler.

Lo que dice el artículo que he vinculado anteriormente es it will call your IDispatch::Invoke. ¿Qué significa por your. ¿Cómo le digo a oleControl qué objeto es mi IDispatch? Espero que tenga algún sentido.

+0

Usted no está cerca, se requiere la personalización del anfitrión. Una clase interna llamada WebBrowserSite en el caso de WebBrowser. Anular la implementación de IDispatch es el problema difícil, es implementado por el CLR para el código administrado. Es difícil ver cómo puede hacer que esto funcione sin código nativo. –

+0

Bueno, csEXWB está escrito en C# AFAIK. ¿Conoces algún lugar donde pueda comenzar a anular la implementación de IDispatch? – Ahmet

+1

La clase System.Windows.Forms.AmbientProperties está sellada. Es hora de abandonar el contenedor como lo hizo csEXWB. –

Respuesta

17

Aquí hay un WebBrowser personalizado que le permite cambiar las banderas de DLCONTROL.

Este es un ejemplo de código:

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"); 
    } 
} 

Y el código personalizado WebBrowser:

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

¡Muchas gracias! Esto fue en realidad mucho más fácil de lo que esperaba. Todavía necesito mirar este código un poco más cerca, pero lo probé y funcionó :). – Ahmet

Cuestiones relacionadas