2011-08-23 9 views
35

Nota: Hay un very similar question, pero es específico de WPF; este no esDetermine si la aplicación actual está activada (tiene foco)

¿Cómo puedo determinar si la aplicación actual está activada (es decir, tiene foco)?

+0

¿Estás hablando de tu aplicación personal de Windows o arbitraria? – Tigran

+0

como este? http://stackoverflow.com/questions/2183541/c-detecting-which-application-has-focus –

+0

Personal - por lo tanto "aplicación actual" ;-) – Cameron

Respuesta

61

Esto funciona:

/// <summary>Returns true if the current application has focus, false otherwise</summary> 
public static bool ApplicationIsActivated() 
{ 
    var activatedHandle = GetForegroundWindow(); 
    if (activatedHandle == IntPtr.Zero) { 
     return false;  // No window is currently activated 
    } 

    var procId = Process.GetCurrentProcess().Id; 
    int activeProcId; 
    GetWindowThreadProcessId(activatedHandle, out activeProcId); 

    return activeProcId == procId; 
} 


[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] 
private static extern IntPtr GetForegroundWindow(); 

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
private static extern int GetWindowThreadProcessId(IntPtr handle, out int processId); 

Tiene la ventaja de ser seguro para subprocesos, que no requieren la forma principal (o su mango) y no es WPF o WinForms específico. Funcionará con ventanas secundarias (incluso las independientes creadas en un hilo separado). Además, no se requiere configuración.

La desventaja es que utiliza un poco de P/Invoke, pero puedo vivir con eso :-)

+0

Esto puede 'funcionar' con 'ventanas secundarias' pero no diferencia entre ellas y sus padres. – Chris

+2

@Chris: Sí, ese es el punto. Una ventana secundaria todavía es parte de la aplicación. Supongo que por 'aplicación actual' realmente quise decir 'proceso actual'. – Cameron

0

En primer lugar obtener el mango, ya sea usando:

IntPtr myWindowHandle;

myWindowHandle = new WindowInteropHelper(Application.Current.MainWindow).Handle; 

o

HwndSource source = (HwndSource)HwndSource.FromVisual(this); 
myWindowHandle = source.Handle; 

Luego compare Whethers es el ForeGroundWindow:

if (myWindowHandle == GetForegroundWindow()) 
{ 
    // Do stuff! 

} 

[DllImport("user32.dll")] 
private static extern IntPtr GetForegroundWindow(); 
+0

¿Qué pasa si una ventana secundaria es la ventana en primer plano? La aplicación todavía tiene foco, pero no la ventana principal. – Cameron

+0

@cameron, cierto, pero te imaginaste tanto, tan triste por el voto negativo :-) ¿no se aplica la crítica a las otras respuestas sugeridas también? – Cilvic

+0

No bajé ni voté a nadie, pero las respuestas "activadas" funcionarían siempre que la ventana principal sea un padre (o un abuelo) de todos los demás. – Cameron

0

En WPF la forma más sencilla de comprobar si una ventana está activa es:

if(this.IsActive) 
{ 
//the window is active 
} 
1

La solución que encontré que requiere llamadas ni los nativos ni requiere el manejo de eventos es comprobar Form.ActiveForm. En mis pruebas, eso fue null cuando no se enfocó ninguna ventana en la aplicación y de lo contrario no era nula.

var windowInApplicationIsFocused = Form.ActiveForm != null; 

Ah, esto es específico para winforms. Pero eso se aplica a mi situación ;-).

Cuestiones relacionadas