/// <summary> /// A Window procedure - handles window messages for a window. /// Pass this method to HwndSource.AddHook(). /// </summary> /// <param name="hwnd">The window handle.</param> /// <param name="msg">The message.</param> /// <param name="wParam">Message data.</param> /// <param name="lParam">Message data.</param> /// <param name="handled">Set to true if the message has been handled</param> /// <returns>The message result.</returns> public IntPtr WindowProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) { switch ((WindowsApi.WindowMessages)msg) { case WindowsApi.WindowMessages.WM_CLIPBOARDUPDATE: // The clipboard has been updated. this.gotClipboard.Set(); handled = true; break; default: if (msg == this.shellMessage) { // A window has been activated. if (wParam.ToInt32() == WindowsApi.HSHELL_WINDOWACTIVATED || wParam.ToInt32() == WindowsApi.HSHELL_RUDEAPPACTIVATED) { // The activated window is passed via lParam, but this wasn't accurate // for Modern UI apps. IntPtr window = WindowsApi.GetForegroundWindow(); if (this.activeWindow != window) { this.activeWindow = window; // Ignore the application's window WindowsApi.GetWindowThreadProcessId(window, out uint pid); if (pid != this.processId && pid != 0) { this.lastWindow = window; } this.activeWindowChanged.Set(); } } } break; } return(IntPtr.Zero); }
/// <summary> /// Activates a window, does not return until it is activated. /// </summary> /// <param name="hwnd">The handle of the window to activate.</param> private void ActivateWindow(IntPtr hwnd) { if (hwnd != IntPtr.Zero) { // Activate the window, if it's not already. IntPtr active = WindowsApi.GetForegroundWindow(); if (active != hwnd) { // Wait for it to be activated. For unknown reasons, activating the window the first time causes // no window to be activated. The second attempt works. const int timeout = 2000; int start = Environment.TickCount; int timespent = 0; do { WindowsApi.SetForegroundWindow(hwnd); this.activeWindowChanged.Reset(); this.activeWindowChanged.WaitOne(timeout - timespent); timespent = Environment.TickCount - start; } while (this.activeWindow != hwnd && timespent <= timeout); } } }