Saltar al contenido

¿Cómo muestro una ventana emergente de un WebBrowser en otra ventana que creé?

Hola usuario de nuestro sitio web, tenemos la solución a tu pregunta, desplázate y la obtendrás a continuación.

Solución:

El control del navegador web admite el evento NewWindow para recibir notificaciones sobre una ventana emergente. Sin embargo, el contenedor de Winforms no le permite hacer mucho con él, solo puede cancelar la ventana emergente. El contenedor COM nativo permite devolver una nueva instancia del navegador web, esa instancia se utilizará para mostrar la ventana emergente.

Aprovechar esto requiere algo de trabajo. Para empezar, use Proyecto + Agregar referencia, pestaña Examinar y seleccione c: windows system32 shdocvw.dll. Eso agrega una referencia a la interfaz COM nativa.

Cree un formulario que actúe como formulario emergente. Coloque un WebBrowser en él y haga que su código se vea similar a esto:

public partial class Form2 : Form 
    public Form2() 
        InitializeComponent();
    
    public WebBrowser Browser 
        get  return webBrowser1; 
    

La propiedad del navegador da acceso al navegador que se utilizará para mostrar la página web en la ventana emergente.

Ahora volvamos al formulario principal. Coloque un WebBrowser en él y haga que su código se vea así:

public partial class Form1 : Form 
    public Form1() 
        InitializeComponent();
        webBrowser1.Url = new Uri("http://google.com");
    
    SHDocVw.WebBrowser nativeBrowser;
    protected override void OnLoad(EventArgs e) 
        base.OnLoad(e);
        nativeBrowser = (SHDocVw.WebBrowser)webBrowser1.ActiveXInstance;
        nativeBrowser.NewWindow2 += nativeBrowser_NewWindow2;
    
    protected override void OnFormClosing(FormClosingEventArgs e) 
        nativeBrowser.NewWindow2 -= nativeBrowser_NewWindow2;
        base.OnFormClosing(e);
    

    void nativeBrowser_NewWindow2(ref object ppDisp, ref bool Cancel) 
        var popup = new Form2();
        popup.Show(this);
        ppDisp = popup.Browser.ActiveXInstance;
    

El método OnLoad obtiene una referencia a la interfaz COM nativa y luego suscribe un controlador de eventos al evento NewWindow2. Me aseguré de cancelar la suscripción de ese evento en el controlador de eventos FormClosing, no estoy 100% seguro de si es necesario. Mejor prevenir que lamentar.

El controlador de eventos NewWindow2 es el quid, tenga en cuenta que el primer argumento permite devolver una referencia sin tipo. Ese debería ser el navegador nativo en la ventana emergente. Entonces creo una instancia de Form2 y Show () it. Tenga en cuenta el argumento de Show (), que asegura que la ventana emergente es una ventana propia. Sustituya esto según sea necesario para su aplicación, supongo que desea crear una ventana secundaria MDI en su caso.

Tenga en cuenta que este evento no se activa para la ventana que se muestra cuando Javascript usa alert (). El navegador no trata esa ventana como una ventana emergente HTML y no usa una ventana del navegador para mostrarla, por lo que no puede interceptarla ni reemplazarla.

Descubrí que la mejor manera de hacer esto era implementar / hundir el evento NewWindow3

Agregue la referencia a c: windows system32 shdocvw.dll como se menciona en las otras respuestas aquí.

Agregar controlador de eventos

SHDocVw.WebBrowser wbCOMmain = (SHDocVw.WebBrowser)webbrowser.ActiveXInstance;
wbCOMmain.NewWindow3 += wbCOMmain_NewWindow3;

Método de evento

void wbCOMmain_NewWindow3(ref object ppDisp, 
                          ref bool Cancel, 
                          uint dwFlags, 
                          string bstrUrlContext, 
                          string bstrUrl)

    // bstrUrl is the url being navigated to
    Cancel = true; // stop the navigation

    // Do whatever else you want to do with that URL
    // open in the same browser or new browser, etc.

  • Establezca “Insertar tipos de interoperabilidad” para el ensamblado “Interop.SHDocVw” en false
  • Establezca la “copia local” en true.

Fuente para esa ayuda MSDN Post

Refinando la respuesta de Hans, puede derivar el WebBrowser para acceder al COM sin agregar la referencia. Es mediante el uso de los métodos Winforms WebBrowser.AttachInterface y DetachInterface no publicados.

Más elaborado aquí.

Aquí está el código:

Uso (cambie su instancia de WebBrowser a WebBrowserNewWindow2)

public partial class Form1 : Form

    public Form1()
    
        InitializeComponent();
        this.webBrowser1.NewWindow2 += webBrowser_NewWindow2;
    

    protected override void OnFormClosing(FormClosingEventArgs e)
    
        webBrowser1.NewWindow2 -= webBrowser_NewWindow2;
        base.OnFormClosing(e);
    

    void webBrowser_NewWindow2(object sender, WebBrowserNewWindow2EventArgs e)
    
        var popup = new Form1();
        popup.Show(this);
        e.PpDisp = popup.Browser.ActiveXInstance;
    
    public WebBrowserNewWindow2 Browser
    
        get  return webBrowser1; 
    

Código:

using System;
using System.Security.Permissions;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace SHDocVw

    public delegate void WebBrowserNewWindow2EventHandler(object sender, WebBrowserNewWindow2EventArgs e);

    public class WebBrowserNewWindow2EventArgs : EventArgs
    
        public WebBrowserNewWindow2EventArgs(object ppDisp, bool cancel)
        
            PpDisp = ppDisp;
            Cancel = cancel;
        

        public object PpDisp  get; set; 
        public bool Cancel  get; set; 
    

    public class WebBrowserNewWindow2 : WebBrowser
    
        private AxHost.ConnectionPointCookie _cookie;
        private WebBrowser2EventHelper _helper;

        [PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust")]
        protected override void CreateSink()
        
            base.CreateSink();

            _helper = new WebBrowser2EventHelper(this);
            _cookie = new AxHost.ConnectionPointCookie(
                this.ActiveXInstance, _helper, typeof(DWebBrowserEvents2));
        

        [PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")]
        protected override void DetachSink()
        
            if (_cookie != null)
            
                _cookie.Disconnect();
                _cookie = null;
            
            base.DetachSink();
        

        public event WebBrowserNewWindow2EventHandler NewWindow2;

        private class WebBrowser2EventHelper : StandardOleMarshalObject, DWebBrowserEvents2
        
            private readonly WebBrowserNewWindow2 _parent;

            public WebBrowser2EventHelper(WebBrowserNewWindow2 parent)
            
                _parent = parent;
            

            public void NewWindow2(ref object pDisp, ref bool cancel)
            
                WebBrowserNewWindow2EventArgs arg = new WebBrowserNewWindow2EventArgs(pDisp, cancel);
                _parent.NewWindow2(this, arg);
                if (pDisp != arg.PpDisp)
                    pDisp = arg.PpDisp;
                if (cancel != arg.Cancel)
                    cancel = arg.Cancel;
            
        

        [ComImport, Guid("34A715A0-6587-11D0-924A-0020AFC7AC4D"),
        InterfaceType(ComInterfaceType.InterfaceIsIDispatch),
        TypeLibType(TypeLibTypeFlags.FHidden)]
        public interface DWebBrowserEvents2
        
            [DispId(0xfb)]
            void NewWindow2(
                [In, Out, MarshalAs(UnmanagedType.IDispatch)] ref object ppDisp,
                [In, Out] ref bool cancel);
        
    

Aquí tienes las reseñas y calificaciones

Si posees algún reparo y forma de aumentar nuestro crónica eres capaz de añadir una explicación y con deseo lo estudiaremos.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *