SetWinEventHook() es probablemente su mejor apuesta;.. se puede escuchar a cualquiera de los EVENT_SYSTEM_FOREGROUND para escuchar cambios de ventana en primer plano, o incluso EVENT_OBJECT_FOCUS para escuchar más cambios de enfoque de grano fino dentro de las aplicaciones y dentro de los controles.
Deberá usar esto con el indicador WINEVENT_OUTOFCONTEXT; esto significa que la notificación de cambio se enviará de forma asíncrona a su propia aplicación, por lo que no necesitará una DLL por separado; sin embargo, necesitará P/Invocar. Pero la notificación no será instantánea - puede haber un pequeño retraso - pero eso está implícito con asincrónico. Si desea hacer algo de manera inmediata sin demora alguna, necesitará usar C++ y un enlace en proceso (SetWinEventHook con WINEVENT_INCONTEXT o el gancho del estilo SetSetWindowsHookEx).
Aquí hay una muestra que parece para hacer lo que estás buscando:
using System;
using System.Windows;
using System.Windows.Forms;
using System.Runtime.InteropServices;
class ForegroundTracker
{
// Delegate and imports from pinvoke.net:
delegate void WinEventDelegate(IntPtr hWinEventHook, uint eventType,
IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime);
[DllImport("user32.dll")]
static extern IntPtr SetWinEventHook(uint eventMin, uint eventMax, IntPtr
hmodWinEventProc, WinEventDelegate lpfnWinEventProc, uint idProcess,
uint idThread, uint dwFlags);
[DllImport("user32.dll")]
static extern bool UnhookWinEvent(IntPtr hWinEventHook);
// Constants from winuser.h
const uint EVENT_SYSTEM_FOREGROUND = 3;
const uint WINEVENT_OUTOFCONTEXT = 0;
// Need to ensure delegate is not collected while we're using it,
// storing it in a class field is simplest way to do this.
static WinEventDelegate procDelegate = new WinEventDelegate(WinEventProc);
public static void Main()
{
// Listen for foreground changes across all processes/threads on current desktop...
IntPtr hhook = SetWinEventHook(EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_FOREGROUND, IntPtr.Zero,
procDelegate, 0, 0, WINEVENT_OUTOFCONTEXT);
// MessageBox provides the necessary mesage loop that SetWinEventHook requires.
MessageBox.Show("Tracking focus, close message box to exit.");
UnhookWinEvent(hhook);
}
static void WinEventProc(IntPtr hWinEventHook, uint eventType,
IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
{
Console.WriteLine("Foreground changed to {0:x8}", hwnd.ToInt32());
}
}
SetWindowsHookEx() con un gancho WH_SHELL le proporciona una notificación. Difícil de hacer en C#. –
No hay [es necesario agregar una firma adicional] (http://stackoverflow.com/faq#signatures) a su publicación. – Deanna