用TopMost = true打开一个WinForms表单,但没有窃取焦点?

我有一个弹出用户屏幕的表格,并且TopMost=true ,但它会抢断焦点。 如何才能让它在第一次出现时不会窃取焦点?

将此代码粘贴到您的表单中:

 protected override bool ShowWithoutActivation { get { return true; } } 

这对我有用。 它提供TopMost但没有焦点窃取。

  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; } } 

请记住在Visual Studio设计器或其他地方省略设置TopMost。

这是从这里偷来的,错误的,借来的(点击解决方法):

https://connect.microsoft.com/VisualStudio/feedback/details/401311/showwithoutactivation-is-not-supported-with-topmost

你可以这样做:

  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 } } 

我使用form1上的计时器测试下面的代码来实例化并以form1作为所有者显示form2。

在form2的Shown事件中,我将焦点设置为所有者,这是当前的活动表单。

我在form1上有一个文本框,并且能够在文本框中继续写入而不会在此过程中失去焦点。

form1中的我的计时器代码:

 private void timer1_Tick(object sender, EventArgs e) { Form2 popup = new Form2(); popup.TopMost = true; popup.Show(this); timer1.Enabled = false; } 

我在form2的Shown事件中的代码:

 private void Form2_Shown(object sender, EventArgs e) { this.Owner.Focus(); } 

您可以这样做,或者只是将TopMost设置为false,并使用ShowWithoutActivation的覆盖,如Hans Passant所述。

编辑:(或者使用p / invoke,就像Hans Passant在我写这篇文章时错过的其他评论一样)

我遇到了同样的问题。 我不是在使用C#而是使用C ++。 我认为这可能是有用的:

使用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 ); 

将标志SWP_NOACTIVATE传递给uFlags参数对我有用。

你可以设置:

 this.TopMost = True; 

on该表单的Load事件。

对我来说没关系!

而不是在_activated事件中写入.setfocus() ; 将它写入表单的.shown事件。