Implementar IDispatch :: Invoke a ser llamado por un control WebBrowser

Estoy tratando de hacer lo que explican en este artículo en la sección Controlling Download and Execution . Entiendo que el Web Browser Control en ese contexto no es WebBrowser de .NET.

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

Lo que he hecho hasta ahora es heredar WebBrowser de .NET, hacer que mi clase heredada com sea visible usando el [ComVisible(true)] , agregar este método a mi clase (tomado de csEXWB):

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

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

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

Entonces, lo que espero es que oleControl llame a mi método Idispatch_AmbiantDlControl_Invoke_Handler , que no es así. No sé cómo, y probablemente esto es lo que me falta en el código, se supone que oleControl debe 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 your ? ¿Cómo le cuento a oleControl qué objeto es mi IDispatch ? Espero que tenga algún sentido.

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

Este es un código de ejemplo:

 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 de 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 _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(); 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, }