home *** CD-ROM | disk | FTP | other *** search
- // Pavel Zolnikov[http://www.codeproject.com/script/profile/whos_who.asp?id=35980], 2002
-
- using System;
- using System.Diagnostics;
- using System.Windows.Forms;
- using System.ComponentModel;
- using System.Security.Permissions;
- using System.Runtime.InteropServices;
-
- namespace ZCommon
- {
- /// <summary>
- /// Tracks changes in the current foreground window / active application.
- /// </summary>
- /// <remarks>
- /// Uses accessibility API (SetWinEventHook). Also plays with WM_NCACTIVATE message of the main explorer window so
- /// it looks OK when Command Prompt Bar is active.
- /// </remarks>
- class ForegroundWatcher : NativeWindow
- {
- bool isForeground;
- IntPtr hook;
- WINEVENTPROC hookDelegate;
-
- public void Start(IntPtr appWindowHandle)
- {
- ReleaseHandle();
- AssignHandle(appWindowHandle);
- }
-
- public ForegroundWatcher()
- {
- HookMe();
- }
-
- ~ForegroundWatcher()
- {
- UnhookMe();
- }
-
- public void HookMe()
- {
- GC.KeepAlive(this);//FxCop
-
- hookDelegate = new WINEVENTPROC(WinEventProc);
-
- hook = SetWinEventHook(
- EVENT_SYSTEM_FOREGROUND,
- EVENT_SYSTEM_FOREGROUND,
- IntPtr.Zero,
- hookDelegate,
- 0, 0, 0 );
- }
-
- public void UnhookMe()
- {
- GC.KeepAlive(this);
-
- if( hook != IntPtr.Zero )
- UnhookWinEvent( hook );
-
- hookDelegate = null;
- hook = IntPtr.Zero;
- }
-
- public bool ConsoleFocused
- {
- get
- {
- return consoleFocused;
- }
- }bool consoleFocused;
-
- [SecurityPermission(SecurityAction.LinkDemand, Unrestricted=true)]
- protected override void WndProc(ref System.Windows.Forms.Message m)
- {
- if( m.Msg == WM_NCACTIVATE )
- {
- m.WParam = (IntPtr)(isForeground ? 1 : 0);
- }
-
- base.WndProc(ref m);
- }
-
- void WinEventProc(
- IntPtr winEventHook,
- Int32 eventId,
- IntPtr hwnd,
- Int32 bjectId,
- Int32 childId,
- Int32 eventThread,
- Int32 eventTime
- )
- {
- if( ConsoleCtrl.ConsoleOwner!=null && ConsoleCtrl.ConsoleOwner.MainWindowHandle == Handle )
- {//process event only if we own console
- bool wasFocused = consoleFocused;
- consoleFocused = hwnd == ConsoleCtrl.ConsoleWindowHandle && Win32.GetFocus() == IntPtr.Zero;
- isForeground = ( ConsoleFocused || hwnd == Handle);
-
- Win32.SendMessage( Handle, WM_NCACTIVATE, 0, 0);
-
- if( wasFocused != consoleFocused )
- {
- if(consoleFocused)
- {
- IntPtr h = Handle;//ensure that we set topmost and nontopmost the same window
- Win32.SetWindowPos( h, (IntPtr)(-1), 0, 0, 0, 0, 0x13 );
- Win32.SetWindowPos( h, (IntPtr)(-2), 0, 0, 0, 0, 0x13 );
-
- if(ConsoleGotFocus!=null) ConsoleGotFocus(null, EventArgs.Empty);
- }
- else
- {
- if(ConsoleLostFocus!=null) ConsoleLostFocus(null, EventArgs.Empty);
- }
- }
- }
- }
-
- public event EventHandler ConsoleLostFocus;
- public event EventHandler ConsoleGotFocus;
-
- delegate void WINEVENTPROC(
- IntPtr winEventHook,
- Int32 eventId,
- IntPtr hwnd,
- Int32 objectId,
- Int32 childId,
- Int32 eventThread,
- Int32 eventTime
- );
-
- const int EVENT_SYSTEM_FOREGROUND = 0x0003;
- const int WM_NCACTIVATE = 0x0086;
-
- [DllImport("user32.dll")]
- extern static IntPtr SetWinEventHook(
- UInt32 eventMin,
- UInt32 eventMax,
- IntPtr hmodWinEventProc,
- WINEVENTPROC winEventProc,
- Int32 processId,
- Int32 threadId,
- UInt32 flags
- );
- [DllImport("user32.dll")]
- extern static bool UnhookWinEvent( IntPtr winEventHook );
- }
- }