Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I stop Chromium from creating a "WebViewHost" host window when launching the user's default web browser?

I am using the Chromium web browser control in my Delphi 6 application.

Whenever the user clicks on a web link in the web page currently being displayed that is not on my primary web site I launch their default web browser with the URL, by opening the URL using the Windows ShellExecute() function with the 'Open' verb. I do this from the BeforeBrowse() event handler and simultaneously cancel the navigation.

In other words, I do not show external URLs in the Chromium control but instead, show them in the user's default web browser.

It works fine but sometimes I also get a stand-alone window pop up owned by my application and that takes up about half the screen that is completely empty (blank white client area with my Windows theme). The Windows class name of the window is "webviewhost".

Can anyone tell me how to suppress this "ghost" window?

like image 541
Robert Oschler Avatar asked Feb 12 '12 15:02

Robert Oschler


1 Answers

The problem here is with popup windows. They are created before the OnBeforeBrowse event is fired and you cancel their navigation so they looks like ghosts.

You can prevent their creation by setting the result of the OnBeforePopup event to True, but this will end the navigation so the OnBeforeBrowse won't get fired. If you follow this way then you will have to perform your ShellExecute action in the OnBeforePopup event as well.

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;

Another way is to set the m_bWindowRenderingDisabled flag to True in the OnBeforePopup event what should prevent the popup window to be created (as described in ceflib.pas, not in the official documentation, IMHO the window is created but remains hidden, and I hope this won't lead to any leak, haven't verified that) and the navigation will continue so the OnBeforePopup event will get fired.

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;

The following code is the simulation of your problem (in this tutorial used as the example is the link my popup in the lower part of the page which if you click on will open the popup window).

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;
like image 110
TLama Avatar answered Sep 28 '22 08:09

TLama