2011-02-01 51 views
5

Estoy tratando de traer un primer plano de la ventana. Estoy usando este código Pero no está funcionando. ¿Podría alguien ayudarme?¿Cómo traer un primer plano de ventana usando C#?

ShowWindowAsync(wnd.hWnd, SW_SHOW); 

SetForegroundWindow(wnd.hWnd); 
// Code from Karl E. Peterson, www.mvps.org/vb/sample.htm 
// Converted to Delphi by Ray Lischner 
// Published in The Delphi Magazine 55, page 16 
// Converted to C# by Kevin Gale 
IntPtr foregroundWindow = GetForegroundWindow(); 
IntPtr Dummy = IntPtr.Zero; 

uint foregroundThreadId = GetWindowThreadProcessId(foregroundWindow, Dummy); 
uint thisThreadId = GetWindowThreadProcessId(wnd.hWnd, Dummy); 

if (AttachThreadInput(thisThreadId, foregroundThreadId, true)) 
{ 
    BringWindowToTop(wnd.hWnd); // IE 5.5 related hack 
    SetForegroundWindow(wnd.hWnd); 
    AttachThreadInput(thisThreadId, foregroundThreadId, false); 
} 

if (GetForegroundWindow() != wnd.hWnd) 
{ 
    // Code by Daniel P. Stasinski 
    // Converted to C# by Kevin Gale 
    IntPtr Timeout = IntPtr.Zero; 
    SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, Timeout, 0); 
    SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, Dummy, SPIF_SENDCHANGE); 
    BringWindowToTop(wnd.hWnd); // IE 5.5 related hack 
    SetForegroundWindow(wnd.hWnd); 
    SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, Timeout, SPIF_SENDCHANGE); 
} 

del Código explicó

Realización de una ventana de la ventana en primer plano requiere algo más que llamar a la API SetForegroundWindow. Debe primero determinar el hilo de primer plano y conectarlo a su ventana, usando AttachThreadInput, luego llame al SetForegroundWindow. De esa forma pueden compartir estados de entrada.

Primero llamo GetForegroundWindow a obtengo el control de la ventana actual de primer plano . A continuación, algunas llamadas a GetWindowThreadProcessId recuperan los hilos asociados con la ventana actual de primer plano y la ventana I desea poner en primer plano. Si estos hilos son los mismos, una llamada simple a SetForegroundWindow es todo que es necesario. De lo contrario, el hilo de primer plano se adjunta a la ventana que traigo al frente y se separó de lo que era la ventana actual de primer plano . La API AttachThreadInput se encarga de esto.

Contenido tomado de here Gracias.

+2

Código malvado, votando para cerrar. –

+0

No puedo entender el código también. Pero creo que el tema no estaría cerrado. Estoy esperando por posibles soluciones –

+0

@Nikil, mayb solo guarde el título y elimine (olvide) ese código? –

Respuesta

0

seré breve: Form.BringToFront()

+0

Esto es para formularios en su propia aplicación, no cualquier aplicación que ejecute –

11

He utilizado este método antes:

[DllImport("user32.dll")] 
    static extern bool SetForegroundWindow(IntPtr hWnd); 

    Process[] processes = Process.GetProcessesByName("processname"); 
    SetForegroundWindow(processes[0].MainWindowHandle); 

Más información: http://pinvoke.net/default.aspx/user32.SetForegroundWindow

+0

También debe traer la restauración del formulario si está minimizado. –

0

A partir de Windows 7 estas características no se comportan tan bien. Si hay una aplicación como Excel frente a la aplicación que desea traer al frente, Windows 7 bloquea esto y muestra la ventana. Puede establecer una configuración de tiempo de espera de registro ForegroundLockTimeout = 0 en HKEY_CURRENT_USER \ Control Panel \ Desktop, pero esto se conoce como robo de foco. Para establecer el comportamiento de cómo debe "comportarse" XP y se comportará en Windows 7 de forma predeterminada, puede crear/establecer el valor en 0x00030D40 (200000ms). Me gustaría saber cuál es la solución preferida para las aplicaciones confiables de Windows. p.ej. Si confío en la aplicación B para tomar el foco cuando hago doble clic en algo en la Solicitud A y alguna otra aplicación está ocultando la ventana de Aplicación B.

6

Este código restaura y establecer el foco en una ventana:

[DllImport("User32.dll")] 
    static extern int SetForegroundWindow(IntPtr hWnd); 

    [DllImport("user32.dll")] 
    internal static extern bool SendMessage(IntPtr hWnd, Int32 msg, Int32 wParam, Int32 lParam); 
    static Int32 WM_SYSCOMMAND = 0x0112; 
    static Int32 SC_RESTORE = 0xF120; 

y utilizar de esta manera:

var proc = Process.GetProcessesByName("YourProgram").FirstOrDefault(); 

    if (proc != null) 
    { 
     var pointer = proc.MainWindowHandle; 

     SetForegroundWindow(pointer); 
     SendMessage(pointer, WM_SYSCOMMAND, SC_RESTORE, 0); 
    } 
2

para que SetForegroundWindow a trabajar de forma constante, lo que tiene que meet a few criteria.El primero es que su proceso que ejecutará el comando debe estar en primer plano. Solo el proceso en primer plano puede hacer que otro proceso se ponga en primer plano. Para hacer primero su proceso en primer plano, debe llevar la ventana principal al frente, si no es así. Lo minimizas primero y luego SetForegroundWindow, para ponerlo en primer plano. Ahora encuentra el proceso de destino y llevarlo a la parte delantera

Los pasos son

I've got an example, aunque es un caso de uso ligeramente diferente.

Cuestiones relacionadas