2012-02-12 27 views
5

Estoy usando el control del navegador web Chromium en mi aplicación Delphi 6.¿Cómo puedo evitar que Chromium cree una ventana de host "WebViewHost" cuando se inicia el navegador web predeterminado del usuario?

Cada vez que el usuario hace clic en un enlace web en la página web que se muestra actualmente que no está en mi sitio web principal, abro su navegador web predeterminado con la URL abriendo la URL usando la función ShellExecute() de Windows con Verbo 'Abrir'. Lo hago desde el controlador de eventos BeforeBrowse() y simultáneamente cancelo la navegación.

En otras palabras, no muestro las URL externas en el control Chromium, sino que las muestro en el navegador web predeterminado del usuario.

Funciona bien, pero a veces también obtengo una ventana emergente independiente propiedad de mi aplicación y ocupa aproximadamente la mitad de la pantalla que está completamente vacía (área de cliente blanca en blanco con mi tema de Windows). El nombre de clase de Windows de la ventana es "webviewhost".

¿Alguien puede decirme cómo suprimir esta ventana "fantasma"?

Respuesta

7

El problema aquí es con ventanas emergentes. Se crean antes de que se active el evento OnBeforeBrowse y cancelas su navegación para que se vean como fantasmas.

Puede evitar su creación estableciendo el resultado del evento OnBeforePopup en True, pero esto terminará la navegación para que no se active el OnBeforeBrowse. Si sigue de esta manera, tendrá que realizar su acción ShellExecute en el evento OnBeforePopup también.

procedure TForm1.Chromium1BeforePopup(Sender: TObject; 
    const parentBrowser: ICefBrowser; var popupFeatures: TCefPopupFeatures; 
    var windowInfo: TCefWindowInfo; var url: ustring; var client: ICefBase; 
    out Result: Boolean); 
begin 
    // you can set the Result to True here and block the window creation at all, 
    // but then you will stop also the navigation and the OnBeforeBrowse event 
    // won't be fired, so if you will follow this way then you'll have to perform 
    // your ShellExecute action here as well 

    if url <> 'http://www.yourdomain.com' then 
    begin 
    Result := True; 
    ShellExecute(Handle, 'open', PChar(url), '', '', SW_SHOWNORMAL); 
    end; 
end; 

Otra forma es establecer el indicador m_bWindowRenderingDisabled True en el evento OnBeforePopup lo que se debe evitar que la ventana emergente para crear (como se describe en ceflib.pas, no en la documentación oficial, en mi humilde opinión se crea la ventana pero permanece oculta , y espero que esto no genere ninguna fuga, no lo haya verificado) y la navegación continuará para que se active el evento OnBeforePopup.

procedure TForm1.Chromium1BeforePopup(Sender: TObject; 
    const parentBrowser: ICefBrowser; var popupFeatures: TCefPopupFeatures; 
    var windowInfo: TCefWindowInfo; var url: ustring; var client: ICefBase; 
    out Result: Boolean); 
begin 
    // you can set the m_bWindowRenderingDisabled flag to True here what should 
    // prevent the popup window to be created and since we don't need to take 
    // care about substitute parent for popup menus or dialog boxes of this popup 
    // window (because we will cancel the navigation anyway) we don't need to set 
    // the WndParent member here; but please check if there are no resource leaks 
    // with this solution because it seems more that the window is just hidden 

    if url <> 'http://www.yourdomain.com' then 
    windowInfo.m_bWindowRenderingDisabled := True; 
end; 

El código siguiente es la simulación de su problema (en this tutorial utilizado como ejemplo es el enlace my popup en la parte inferior de la página, que si hace clic en se abrirá la ventana emergente).

uses 
    ShellAPI, ceflib, cefvcl; 

const 
    PageURL = 'http://www.htmlcodetutorial.com/linking/linking_famsupp_72.html'; 
    PopupURL = 'http://www.htmlcodetutorial.com/linking/popupbasic.html'; 

procedure TForm1.FormCreate(Sender: TObject); 
begin 
    Chromium1.Load(PageURL); 
end; 

procedure TForm1.Chromium1BeforeBrowse(Sender: TObject; 
    const browser: ICefBrowser; const frame: ICefFrame; 
    const request: ICefRequest; navType: TCefHandlerNavtype; isRedirect: Boolean; 
    out Result: Boolean); 
begin 
    if request.Url = PopupURL then 
    begin 
    Result := True; 
    ShellExecute(Handle, 'open', PChar(request.Url), '', '', SW_SHOWNORMAL); 
    end; 
end; 

procedure TForm1.Chromium1BeforePopup(Sender: TObject; 
    const parentBrowser: ICefBrowser; var popupFeatures: TCefPopupFeatures; 
    var windowInfo: TCefWindowInfo; var url: ustring; var client: ICefBase; 
    out Result: Boolean); 
begin 
{ 
    // Solution 1 
    // this will block the popup window creation and cancel the navigation to 
    // the target, so we have to perform the ShellExecute action here as well 
    if url = PopupURL then 
    begin 
    Result := True; 
    ShellExecute(Handle, 'open', PChar(url), '', '', SW_SHOWNORMAL); 
    end; 
} 
{ 
    // Solution 2 
    // or we can set the m_bWindowRenderingDisabled flag to True and the window 
    // won't be created (as described in ceflib.pas), but the navigation continue 
    if url = PopupURL then 
    windowInfo.m_bWindowRenderingDisabled := True; 
} 
end; 
+4

Gran respuesta, gracias. –

Cuestiones relacionadas