c# - tutorial - ¿Cuál es la forma "correcta" de llevar una aplicación de Windows Forms al primer plano?
windows forms c++ visual studio 2017 (12)
¿Has probado Form.Activate ?
Este código parece hacer lo que quieras, restaurando el formulario al tamaño normal si se minimiza y luego activándolo para establecer el foco:
if (this.WindowState == FormWindowState.Minimized)
{
this.WindowState = FormWindowState.Normal;
}
this.Activate();
Advertencia: ¡esto es molesto! Si solo se trata de una aplicación para uso personal, como dices, tal vez puedas vivir con ella. :)
Estoy escribiendo una aplicación de Windows Forms en C #. Necesito poder ponerlo en primer plano. Después de buscar en Google y la experimentación, tengo una solución de trabajo que se ve bastante hacky.
Me gustaría saber la manera elegante de hacer esto, si es que hay alguno. Necesito la aplicación para restaurar y llegar al primer plano, ya sea que se reduzca al mínimo, o no se minimice, sino en segundo plano.
El código actual se ve así:
WindowState = FormWindowState.Minimized;
WindowState = FormWindowState.Normal;
BringToFront();
Focus();
Como ya se dijo en otra respuesta, una (por supuesto poco elegante) forma de hacerlo sería mediante el uso de user32.dll y llamar a los métodos nativos, esto puede ser válido si estamos usando algún proceso o subproceso no vinculado de la persona que llama, que era establecer en la persona que llama principal como una ventana de fondo (por ejemplo: siempre en la parte superior de la ventana que queremos más arriba).
esto fue parcialmente copiado, pero solo para simplificar:
public enum WindowPos : int
{
HWND_NOTOPMOST=-2,
HWND_TOPMOST=-1,
HWND_TOP=0,
HWND_BOTTOM=1
}
public enum WindowFlags : uint
{
SWP_NOSIZE=0x0001,
SWP_NOMOVE=0x0002,
SWP_NOZORDER=0x0004,
SWP_NOREDRAW=0x0008,
SWP_NOACTIVATE=0x0010,
SWP_FRAMECHANGED=0x0020, /* The frame changed: send WM_NCCALCSIZE */
SWP_SHOWWINDOW=0x0040,
SWP_HIDEWINDOW=0x0080,
SWP_NOCOPYBITS=0x0100,
SWP_NOOWNERZORDER=0x0200, /* Don''t do owner Z ordering */
SWP_NOSENDCHANGING=0x0400 /* Don''t send WM_WINDOWPOSCHANGING */
}
public enum ShowWindowCommands : int
{
SW_HIDE=0,
SW_SHOWNORMAL=1,
SW_NORMAL=1,
SW_SHOWMINIMIZED=2,
SW_SHOWMAXIMIZED=3,
SW_MAXIMIZE=3,
SW_SHOWNOACTIVATE=4,
SW_SHOW=5,
SW_MINIMIZE=6,
SW_SHOWMINNOACTIVE=7,
SW_SHOWNA=8,
SW_RESTORE=9,
SW_SHOWDEFAULT=10,
SW_FORCEMINIMIZE=11,
SW_MAX=11
}
private static class User32
{
[DllImport("user32.dll")]
internal static unsafe extern IntPtr SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll")]
internal static unsafe extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
[DllImport("user32.dll")]
internal static unsafe extern bool SetWindowPos(IntPtr hWnd, int hWndPutAfter, int x, int y, int cx, int cy, uint flags);
[DllImport("user32.dll")]
internal static unsafe extern IntPtr SetFocus( IntPtr hWnd );
}
public void Activate()
{
Process currentProcess = Process.GetCurrentProcess();
IntPtr hWnd = currentProcess.MainWindowHandle;
if (hWnd != IntPtr.Zero)
{
User32.SetWindowPos(hWnd, (int)WindowPos.Top, 0, 0, 0, 0, (uint)(WindowFlags.SWP_NOMOVE | WindowFlags.SWP_NOSIZE));
User32.ShowWindow(hWnd, (int)ShowWindowCommands.SW_SHOW);
User32.SetForegroundWindow(hWnd);
User32.SetFocus( hWnd );
}
}
Para completar, agregué la mayoría de las referencias de las constantes que están disponibles en el SDK de Windows
Después de muchas pruebas y errores, llegué a este código. Esto es probado. Se llama al método BringToFront en su formulario después de que se le haya pasado el foco. Esto lo hace aparecer en frente.
[DllImport("user32.dll")]
static extern bool SetForegroundWindow(IntPtr hWnd);
public static bool BringToFrontCustom(Form f)
{
bool toReturn = true;
try
{
//This is the same as the name of the executable without the .exe at the end
Process[] processes = Process.GetProcessesByName("MyFormName");
SetForegroundWindow(processes[0].MainWindowHandle);
f.BringToFront();
}
catch(Exception e)
{
toReturn = false;
MessageBox.Show("Something went wrong, Please bring the window to front manually");
}
return toReturn;
}
Después de varios intentos, descubrí la combinación de trabajo:
form.Show();
form.WindowState = FormWindowState.Normal;
form.Activate();
En lugar de usar windowstate minimiza o topmost = falso, etc. etc.
Tengo una aplicación de Winform ... lanza una rutina de automatización: quería que la aplicación se minimizara cuando se realizara la secuencia de automatización y luego se presentara nuevamente después de que se completara la secuencia de automatización.
Fue fácil: solo haz que el formulario no sea visible mientras el otro proceso / hilo / lo que esté funcionando
//hide the app
this.Visible=false;
//do something
some_form.ShowDialog();
doSomethingHere();
//reshow the app
this.visible=true;
En realidad, simplemente llame a Activate()
dentro del evento Shown
.
En su Example.Designer.cs
:
this.Shown += new System.EventHandler(this.Example_Shown);
En su Example.cs
:
private void Example_Shown(object sender, EventArgs e)
{
this.Activate();
}
Esto funcionó incluso si su formulario está siendo lanzado por otro proceso (por ejemplo, un formulario de pantalla de inicio que se ejecuta en un hilo diferente).
Establecer Form.TopMost
en true
forzará la ventana de formulario al primer plano.
Nota. A continuación, he copiado la respuesta más votada en una pregunta vinculada cerrada como duplicado a esta. Esa respuesta es la única respuesta pura de C # que he encontrado que resuelve este problema.
this.WindowState = FormWindowState.Minimized;
this.Show();
this.WindowState = FormWindowState.Normal;
Siempre trae la ventana deseada al frente de todas las demás.
Puede establecer .TopMost
en verdadero, llamar a DoEvents()
y luego establecer .TopMost
en falso. Todavía es un hack, pero si Activar y Mostrar no funcionan, es mejor que minimizar / volver a mostrar.
Tuve un problema similar, al cual
form.TopMost = true;
form.Activate();
fue una solución bastante satisfactoria.
Pero todavía no está garantizado que el formulario tenga foco, porque TopMost
podría no funcionar siempre, dependiendo de cómo el usuario haya interactuado antes con las ventanas en otros procesos:
establecer .TopMost = true
y use
ShowDialog()
private static class User32
{
[DllImport("User32.dll")]
internal static extern IntPtr SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll")]
internal static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
internal static readonly IntPtr InvalidHandleValue = IntPtr.Zero;
internal const int SW_MAXIMIZE = 3;
}
public void Activate()
{
Process currentProcess = Process.GetCurrentProcess();
IntPtr hWnd = currentProcess.MainWindowHandle;
if (hWnd != User32.InvalidHandleValue)
{
User32.SetForegroundWindow(hWnd);
User32.ShowWindow(hWnd, User32.SW_MAXIMIZE);
}
}