6

I'm using webbrowser control in my winforms app (c#). And when it is doing automation things, I'm losing focus control from the window I was working with. Webbrowsers' form doesn't show up also, I just lose focus from the contol. I now writing this message I have to click into textbox again and again...

How to disable such behaviour in webbrowser?

I create invisible webbrowser like that:

var br = new WebBrowser();
br.Visible = false;
br.ScriptErrorsSuppressed = true;

Please advise.

Joe White
  • 94,807
  • 60
  • 220
  • 330
Jeffrey Rasmussen
  • 367
  • 4
  • 8
  • 21
  • 2
    The code you posted definitely has absolutely nothing to do with the issue you are experiencing. If you are sure that this problem only happens while running your program, you'll need to post more code for the rest of your program. – Trevor Elliott Dec 13 '11 at 20:42
  • possible duplicate of [Prevent WebBrowser control from stealing focus?](http://stackoverflow.com/questions/1562619/prevent-webbrowser-control-from-stealing-focus) – Sheng Jiang 蒋晟 Dec 14 '11 at 16:00

7 Answers7

16

I had the same problem:

The Webbrowser Control stole focus from the application once the URL is loaded.

This worked for me:

  1. Before Webbrowser.Navigate() method call, set the parent control of the Webbrowser to Enabled = false.
  2. At the DocumentCompleted event of the Webbrowser, reset parent control of the Webbrowser to Enabled = true.

You can't do it directly on Webbrowser because WebBrowserBase.Enabled is not supported.

Let me know if it works for you.

Brad
  • 159,648
  • 54
  • 349
  • 530
2

it's a very complex problem to fix, and should be revised by microsoft, an app just stealing the focus is not logical, it does depend on what the website is doing though. I had to resort to a CBT filter, see http://msdn.microsoft.com/en-us/magazine/cc188966.aspx, and filter out unwanted HCBT_ACTIVATE and HCBT_SETFOCUS (return 1;). You can use GetWindowClass(wParam) to see what's going on.

Even above didn't entirely work, the app window would still pop to the front temporarily so worked around that using SetWindowPos HWND_TOPMOST and HWND_NOTOPMOST on the window currently in foreground. The HCBT_SETFOCUS gets hit 2 or 3 times so on 1st set HWND_TOPMOST and last set HWND_NOTOPMOST. Count how many classname == "Internet Explorer_Server" which should be 2 (or possibly depends on website?), the other is "Shell Embedding" but doesn't always occur. Hope it helps.

colin lamarre
  • 1,714
  • 1
  • 18
  • 25
2

I was looking at all the other answers to this question and they weren't working for me, but i saw the one about settings Browser.Parent.Enabled = false; i tried so and got an error, so i tried this instead it just came to mind.

Browser.Parent = new Control();

Browser.Parent.Enabled = false;

And now the problem is completely gone, it does not take away focus anymore. I am using the web browser class as a variable, it is not on my form. well this worked for me try it, this seemed to be a 100% solution.

2

You could try disabling it globally via the SystemParametersInfo api. Use SPI_SETFOREGROUNDLOCKTIMEOUT. Setting foreground lockout is a global settings, so you will want to clear this setting when you're done. A more permanent solution is to change HKCU\Control Panel\Desktop\ForegroundLockTimeout registry key. See also this discussion on social.msdn (specifically, billb08's answer).

Brian
  • 25,523
  • 18
  • 82
  • 173
2

I guess WebBrowser acquires the focus after a page is loaded by calling Navigate (or the Click method of an HtmlElement, which causes navigation). The focus could be given back to the control on the window (the TextBox) in the DocumentComplete event handler of the WebBrowser, but this is very difficult:

  1. When would you determine which control owned the focus originally? Before calling Navigate? This is not enough, because the user can move to another control after calling Navigate, but before handling DocumentComplete.

  2. AFAIK setting the focus to a TextBox will select its whole content, so you will have to put the cursor back to its original position. But when would you store the original position? Same problem.

  3. There can be more than one DocumentComplete event after a single Navigate (or Click).

A possible solution would be to create a separate application for your hidden WebBrowser. This second application would be invisible, and could communicate with the original GUI application using some InterProcess Communication (IPC) technique. Because the WebBrowser in this case would run in a different process, you would have a better chance not to lose lose the focus and bother the user.

kol
  • 27,881
  • 12
  • 83
  • 120
  • Unfortunately - the webcontrol still steals focus even if running in a another process – Tom Mar 14 '18 at 22:03
1
Most of the methods won't work for me on more than one web browser. This method is work with any amount of web browsers;

1. Put web browser into a panel and set panel enabled to false, then navigate;

    webBrowser.Parent = panelBottom;
    panelWebBrowser.Enabled = false;
    webBrowser.Navigate("http://www.google.com");

2. Define a navigated event to web browser and delay panels enabling for a second;

    private void webBrowser_Navigated(object sender, WebBrowserNavigatedEventArgs e)
    {
        System.Threading.Timer timer = null;
        timer = new System.Threading.Timer((obj) =>
        {
            panelWebBrowser.Enabled = true;
            timer.Dispose();
        },null, 1000, Timeout.Infinite);
    }
DiRiNoiD
  • 1,281
  • 2
  • 18
  • 24
0

My solution for sending the focus back to a form:

        Private Sub Web_DocumentCompleted(sender As Object, e As WebBrowserDocumentCompletedEventArgs) Handles Web.DocumentCompleted
    If Me.Visible = False Then
        For Each f As Form In My.Application.OpenForms
            If TypeOf f Is frmLogin Then
                Dim fl As frmLogin = DirectCast(f, frmLogin)
                If fl.Visible = True Then
                    fl.Focus()
                    Exit For
                End If
            End If
        Next
    End If
End Sub
Andre
  • 1
  • 1