I have a form that pops up on a user's screen and has TopMost=true, but it steals the focus. How can I get it to not steal focus when it first appears?
- 1,884
 - 4
 - 28
 - 51
 
- 22,657
 - 67
 - 188
 - 276
 
- 
                    2+1: I hate windows that steal the focus! – Sep 16 '10 at 19:19
 - 
                    If it's possible, I bet Raymond Chen wrote about it: http://blogs.msdn.com/b/oldnewthing/ – Sep 16 '10 at 19:21
 - 
                    I'm surprised this isn't something just built into WinForms... – sooprise Sep 16 '10 at 19:31
 
7 Answers
This is what worked for me. It provides TopMost but without focus-stealing.
    protected override bool ShowWithoutActivation
    {
       get { return true; }
    }
    private const int WS_EX_TOPMOST = 0x00000008;
    protected override CreateParams CreateParams
    {
       get
       {
          CreateParams createParams = base.CreateParams;
          createParams.ExStyle |= WS_EX_TOPMOST;
          return createParams;
       }
    }
Remember to omit setting TopMost in Visual Studio designer, or elsewhere.
This is stolen, err, borrowed, from here (click on Workarounds):
- 11,420
 - 7
 - 80
 - 106
 
- 
                    
 - 
                    @FactorMystic Eh, late but [Archive.org link](http://web.archive.org/web/20120422130419/http://connect.microsoft.com/VisualStudio/feedback/details/401311/showwithoutactivation-is-not-supported-with-topmost). – Jed Burke Jul 20 '16 at 00:10
 
Paste this code in your form:
protected override bool ShowWithoutActivation
{
    get { return true; }
}
- 98,240
 - 88
 - 296
 - 433
 
- 922,412
 - 146
 - 1,693
 - 2,536
 
- 
                    It does not work in VS2008 when TopMost is set to True. I will try it on VS2010 now. – Nope Sep 16 '10 at 19:49
 - 
                    Still doesn't work in VS 2010. Only works when TopMost on the popup form is set to false. – Nope Sep 16 '10 at 19:56
 - 
                    9Oh rats, that's true, TopMost messes this up. Won't work in VS2010 either. You'll have to P/Invoke SetWindowPos() with HWND_TOPMOST and SWP_NOACTIVATE. Use pinvoke.net for the declarations. – Hans Passant Sep 16 '10 at 19:59
 - 
                    @Soo: Not sure how you got it to work as it is a well known bug. @Hans: +1 on the comment adding the mentioning of P/Invoke to solve that issue. – Nope Sep 25 '10 at 00:17
 
You can set:
this.TopMost = True;
on Load event of that form.
It's OK with me!
- 21
 - 1
 
- 
                    dont forget to disable the .topmost on the IDE first though - works like a charm – Stavm Aug 11 '15 at 13:10
 
You can do it like this:
    private const int SW_SHOWNOACTIVATE = 4;
    private const int HWND_TOPMOST = -1;
    private const uint SWP_NOACTIVATE = 0x0010;
    [System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint = "SetWindowPos")]
    private static extern bool SetWindowPos(
         int hWnd,             // Window handle
         int hWndInsertAfter,  // Placement-order handle
         int X,                // Horizontal position
         int Y,                // Vertical position
         int cx,               // Width
         int cy,               // Height
         uint uFlags);         // Window positioning flags
    [System.Runtime.InteropServices.DllImport("user32.dll")]
    private static extern bool ShowWindow(System.IntPtr hWnd, int nCmdShow);
    public static void ShowInactiveTopmost(System.Windows.Forms.Form frm)
    {
        try
        {
            ShowWindow(frm.Handle, SW_SHOWNOACTIVATE);
            SetWindowPos(frm.Handle.ToInt32(), HWND_TOPMOST,
            frm.Left, frm.Top, frm.Width, frm.Height,
            SWP_NOACTIVATE);
        }
        catch (System.Exception ex)
        {
            // error handling
        }
    }
- 1,911
 - 3
 - 20
 - 37
 
I came across the same problem. I'm not using C# but C++. I figure this could be useful anyways:
Using windows.h:
BOOL WINAPI SetWindowPos(
  __in      HWND hWnd,
  __in_opt  HWND hWndInsertAfter,
  __in      int X,
  __in      int Y,
  __in      int cx,
  __in      int cy,
  __in      UINT uFlags
);
Passing the flag SWP_NOACTIVATE to the uFlags argument worked for me.
- 79,279
 - 19
 - 185
 - 195
 
- 869
 - 8
 - 20
 
I tested the below code using a timer on form1 to instantiate and show form2 with form1 as owner.
In form2's Shown event I then set focus to the owner, which is the current active form.
I have a textbox on form1 and was able to continuesly write in the textbox without loosing focus during this process.
My timer code in form1:
private void timer1_Tick(object sender, EventArgs e)
{
    Form2 popup = new Form2();
    popup.TopMost = true;
    popup.Show(this);
    timer1.Enabled = false;
}
My code in the Shown event of form2:
private void Form2_Shown(object sender, EventArgs e)
{
    this.Owner.Focus();
}
You can do this or simply set TopMost to false and use the override of ShowWithoutActivation as Hans Passant stated.
Edit: (Or use p/invoke as seen in Hans Passant's additional comment I missed while I wrote this)
- 22,147
 - 7
 - 47
 - 72
 
Instead of writing .setfocus()in _activated event; write it to .shown event of the form.
- 101
 - 8