Opening a WinForms Form with TopMost = true but not having it steal focus?
Solution 1
Paste this code in your form:
protected override bool ShowWithoutActivation
{
get { return true; }
}
Solution 2
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):
Solution 3
You can set:
this.TopMost = True;
on Load event of that form.
It's OK with me!
Solution 4
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
}
}
Solution 5
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)
sooprise
I like to program, but am a noob, which is why I'm here. <-My sexy fatbooth picture
Updated on June 06, 2022Comments
-
sooprise about 2 years
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? -
Nope almost 14 yearsIt does not work in VS2008 when TopMost is set to True. I will try it on VS2010 now.
-
Nope almost 14 yearsStill doesn't work in VS 2010. Only works when TopMost on the popup form is set to false.
-
user1703401 almost 14 yearsOh 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.
-
Nope almost 14 years@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.
-
Stavm almost 9 yearsdont forget to disable the .topmost on the IDE first though - works like a charm
-
Factor Mystic over 8 yearsthis link is also dead
-
Jed Burke almost 8 years@FactorMystic Eh, late but Archive.org link.