Search code examples
c#console-applicationactive-window

Detect active window changed using C# with a console application


This question is very similar to this one (Detect active window changed using C# without polling), and the code on that accepted answer works fine with a Windows Forms Application, but no way with a Console Application.

¿How can I detect that active window has changed without doing infinite iterations (or any type of polling) with a Console Application?

Thanks in advance.


Solution

  • It can be changed to run as a console application with a few changes. Here is a working code.

    using System;
    using System.Runtime.InteropServices;
    using System.Text;
    using System.Windows.Forms;
    
    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                dele = new WinEventDelegate(WinEventProc);
                IntPtr m_hhook = SetWinEventHook(EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_FOREGROUND, IntPtr.Zero, dele, 0, 0, WINEVENT_OUTOFCONTEXT);
                Application.Run(); //<----
            }
    
            static WinEventDelegate dele = null; //STATIC
    
            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);
    
            private const uint WINEVENT_OUTOFCONTEXT = 0;
            private const uint EVENT_SYSTEM_FOREGROUND = 3;
    
            [DllImport("user32.dll")]
            static extern IntPtr GetForegroundWindow();
    
            [DllImport("user32.dll")]
            static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);
    
            private static string GetActiveWindowTitle() //STATIC
            {
                const int nChars = 256;
                IntPtr handle = IntPtr.Zero;
                StringBuilder Buff = new StringBuilder(nChars);
                handle = GetForegroundWindow();
    
                if (GetWindowText(handle, Buff, nChars) > 0)
                {
                    return Buff.ToString();
                }
                return null;
            }
    
            public static void WinEventProc(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime) //STATIC
            {
                Console.WriteLine(GetActiveWindowTitle());
            }
        }
    }