Show a Form without stealing focus?

2020-01-22 14:02发布

I'm using a Form to show notifications (it appears at the bottom right of the screen), but when I show this form it steals the focus from the main Form. Is there a way to show this "notification" form without stealing focus?

标签: c# .net winforms
17条回答
何必那么认真
2楼-- · 2020-01-22 14:22

I have something similar, and I simply show the notification form and then do

this.Focus();

to bring the focus back on the main form.

查看更多
ゆ 、 Hurt°
3楼-- · 2020-01-22 14:24

If you're willing to use Win32 P/Invoke, then you can use the ShowWindow method (the first code sample does exactly what you want).

查看更多
做个烂人
4楼-- · 2020-01-22 14:24

The sample code from pinvoke.net in Alex Lyman/TheSoftwareJedi's answers will make the window a "topmost" window, meaning that you can't put it behind normal windows after it's popped up. Given Matias's description of what he wants to use this for, that could be what he wants. But if you want the user to be able to put your window behind other windows after you've popped it up, just use HWND_TOP (0) instead of HWND_TOPMOST (-1) in the sample.

查看更多
来,给爷笑一个
5楼-- · 2020-01-22 14:27

When you create a new form using

Form f = new Form();
f.ShowDialog();

it steals focus because your code can't continue executing on the main form until this form is closed.

The exception is by using threading to create a new form then Form.Show(). Make sure the thread is globally visible though, because if you declare it within a function, as soon as your function exits, your thread will end and the form will disappear.

查看更多
Ridiculous、
6楼-- · 2020-01-22 14:28

Doing this seems like a hack, but it seems to work:

this.TopMost = true;  // as a result the form gets thrown to the front
this.TopMost = false; // but we don't actually want our form to always be on top

Edit: Note, this merely raises an already created form without stealing focus.

查看更多
Ridiculous、
7楼-- · 2020-01-22 14:31

Stolen from PInvoke.net's ShowWindow method:

private const int SW_SHOWNOACTIVATE = 4;
private const int HWND_TOPMOST = -1;
private const uint SWP_NOACTIVATE = 0x0010;

[DllImport("user32.dll", EntryPoint = "SetWindowPos")]
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

[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

static void ShowInactiveTopmost(Form frm)
{
     ShowWindow(frm.Handle, SW_SHOWNOACTIVATE);
     SetWindowPos(frm.Handle.ToInt32(), HWND_TOPMOST,
     frm.Left, frm.Top, frm.Width, frm.Height,
     SWP_NOACTIVATE);
}

(Alex Lyman answered this, I'm just expanding it by directly pasting the code. Someone with edit rights can copy it over there and delete this for all I care ;) )

查看更多
登录 后发表回答