¿Abrir un formulario de WinForms con TopMost = true pero no tenerlo para robar el foco?

Tengo un formulario que aparece en la pantalla de un usuario y tiene TopMost=true , pero roba el foco. ¿Cómo puedo conseguir que no robe el foco cuando aparece por primera vez?

Pega este código en tu formulario:

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

Esto es lo que funcionó para mí. Proporciona TopMost pero sin robo de enfoque.

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

Recuerde omitir la configuración TopMost en el diseñador de Visual Studio o en cualquier otro lugar.

Esto es robado, errado, prestado, desde aquí (haga clic en Soluciones provisionales):

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

Puedes hacerlo así:

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

Probé el siguiente código utilizando un temporizador en form1 para crear una instancia y mostrar form2 con form1 como propietario.

En el evento Mostrado de form2, puse el foco en el propietario, que es la forma activa actual.

Tengo un cuadro de texto en form1 y pude escribir continuamente en el cuadro de texto sin perder el enfoque durante este proceso.

Mi código de temporizador en form1:

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

Mi código en el evento Mostrado de form2:

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

Puede hacer esto o simplemente establecer TopMost en falso y usar la anulación de ShowWithoutActivation como se indicó Hans Passant.

Edición: (O use p / invoke como se ve en el comentario adicional de Hans Passant que me perdí mientras escribía esto)

Me encontré con el mismo problema. No estoy usando C # pero C ++. Me imagino que esto podría ser útil de todos modos:

Utilizando 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 ); 

Pasar la bandera SWP_NOACTIVATE al argumento uFlags funcionó para mí.

Puedes configurar:

 this.TopMost = True; 

en el evento de carga de esa forma.

Esta bien conmigo

En lugar de escribir .setfocus() en el evento _activated ; .shown a .shown evento del formulario.