home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2005 November / PCWELT_11_2005.ISO / pcwsoft / Commandbar-Source.z.exe / ConsoleCtrl / ForegroundWatcher.cs < prev   
Encoding:
Text File  |  2002-06-10  |  3.5 KB  |  150 lines

  1. // Pavel Zolnikov[http://www.codeproject.com/script/profile/whos_who.asp?id=35980], 2002
  2.  
  3. using System;
  4. using System.Diagnostics;
  5. using System.Windows.Forms;
  6. using System.ComponentModel;
  7. using System.Security.Permissions;
  8. using System.Runtime.InteropServices;
  9.  
  10. namespace ZCommon
  11. {
  12.     /// <summary>
  13.     /// Tracks changes in the current foreground window / active application. 
  14.     /// </summary>
  15.     /// <remarks>
  16.     /// Uses accessibility API (SetWinEventHook). Also plays with WM_NCACTIVATE message of the main explorer window so
  17.     /// it looks OK when Command Prompt Bar is active.
  18.     /// </remarks>
  19.     class ForegroundWatcher : NativeWindow
  20.     {
  21.         bool            isForeground;
  22.         IntPtr            hook;
  23.         WINEVENTPROC    hookDelegate;
  24.  
  25.         public void Start(IntPtr appWindowHandle)
  26.         {
  27.             ReleaseHandle();
  28.             AssignHandle(appWindowHandle);
  29.         }
  30.  
  31.         public ForegroundWatcher()
  32.         {
  33.             HookMe();
  34.         }
  35.  
  36.         ~ForegroundWatcher()
  37.         {
  38.             UnhookMe();
  39.         }
  40.         
  41.         public void HookMe()
  42.         {
  43.             GC.KeepAlive(this);//FxCop
  44.  
  45.             hookDelegate = new WINEVENTPROC(WinEventProc);
  46.  
  47.             hook = SetWinEventHook( 
  48.                 EVENT_SYSTEM_FOREGROUND,
  49.                 EVENT_SYSTEM_FOREGROUND,
  50.                 IntPtr.Zero,
  51.                 hookDelegate,
  52.                 0, 0, 0 );
  53.         }
  54.  
  55.         public void UnhookMe()
  56.         {
  57.             GC.KeepAlive(this);
  58.  
  59.             if( hook != IntPtr.Zero )
  60.                 UnhookWinEvent( hook );
  61.  
  62.             hookDelegate = null;
  63.             hook = IntPtr.Zero;
  64.         }
  65.  
  66.         public bool ConsoleFocused
  67.         {
  68.             get 
  69.             {
  70.                 return consoleFocused; 
  71.             }
  72.         }bool consoleFocused;
  73.  
  74.         [SecurityPermission(SecurityAction.LinkDemand, Unrestricted=true)]
  75.         protected override void WndProc(ref System.Windows.Forms.Message m)
  76.         {
  77.             if( m.Msg == WM_NCACTIVATE )
  78.             {
  79.                 m.WParam = (IntPtr)(isForeground ? 1 : 0);
  80.             }
  81.  
  82.             base.WndProc(ref m);
  83.         }
  84.  
  85.         void WinEventProc(
  86.             IntPtr winEventHook,
  87.             Int32 eventId,
  88.             IntPtr hwnd,
  89.             Int32 bjectId,
  90.             Int32 childId,
  91.             Int32 eventThread,
  92.             Int32 eventTime
  93.             )
  94.         {
  95.             if( ConsoleCtrl.ConsoleOwner!=null && ConsoleCtrl.ConsoleOwner.MainWindowHandle == Handle )
  96.             {//process event only if we own console
  97.                 bool wasFocused = consoleFocused;
  98.                 consoleFocused = hwnd == ConsoleCtrl.ConsoleWindowHandle && Win32.GetFocus() == IntPtr.Zero;
  99.                 isForeground = ( ConsoleFocused || hwnd == Handle);
  100.  
  101.                 Win32.SendMessage( Handle, WM_NCACTIVATE, 0, 0);
  102.  
  103.                 if( wasFocused != consoleFocused )
  104.                 {
  105.                     if(consoleFocused)
  106.                     {
  107.                         IntPtr h = Handle;//ensure that we set topmost and nontopmost the same window
  108.                         Win32.SetWindowPos( h, (IntPtr)(-1), 0, 0, 0, 0, 0x13 );
  109.                         Win32.SetWindowPos( h, (IntPtr)(-2), 0, 0, 0, 0, 0x13 );
  110.                         
  111.                         if(ConsoleGotFocus!=null) ConsoleGotFocus(null, EventArgs.Empty);
  112.                     }
  113.                     else
  114.                     {
  115.                         if(ConsoleLostFocus!=null) ConsoleLostFocus(null, EventArgs.Empty);
  116.                     }
  117.                 }
  118.             }
  119.         }
  120.  
  121.         public event EventHandler ConsoleLostFocus;
  122.         public event EventHandler ConsoleGotFocus;
  123.  
  124.         delegate void WINEVENTPROC(
  125.             IntPtr winEventHook,
  126.             Int32 eventId,
  127.             IntPtr hwnd,
  128.             Int32 objectId,
  129.             Int32 childId,
  130.             Int32 eventThread,
  131.             Int32 eventTime
  132.             );
  133.  
  134.         const int EVENT_SYSTEM_FOREGROUND    = 0x0003;
  135.         const int WM_NCACTIVATE                = 0x0086;
  136.  
  137.         [DllImport("user32.dll")]
  138.         extern static IntPtr SetWinEventHook(
  139.             UInt32 eventMin,
  140.             UInt32 eventMax,
  141.             IntPtr    hmodWinEventProc,
  142.             WINEVENTPROC winEventProc,
  143.             Int32    processId,
  144.             Int32    threadId,
  145.             UInt32    flags
  146.             );
  147.         [DllImport("user32.dll")]
  148.         extern static bool UnhookWinEvent( IntPtr winEventHook );
  149.     }
  150. }