Проблема при захвате события активного окна, измененного - PullRequest
4 голосов
/ 28 июля 2011

Я пытаюсь зафиксировать событие изменения окна активного окна. Допустим, если пользователь работает над VS и он переключается на IE, я хочу записать это событие активного изменения окна. Я искал в интернете и нашел много примеров, но, кажется, ничего не работает для меня.

Это код, который я написал до сих пор, я не уверен, что не так в этом. Я не могу захватить требуемое событие через это

class Program
{
    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;

    static void Main(string[] args)
    {
        WinEventDelegate dele = new WinEventDelegate(WinEventProc);
        IntPtr m_hhook = SetWinEventHook(EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_FOREGROUND, IntPtr.Zero, dele, 0, 0, WINEVENT_OUTOFCONTEXT);
        Console.ReadKey();
    }

    static void WinEventProc(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
    {
        Console.WriteLine("Something");
    }
}

WinEventProc никогда не звонят, кто-нибудь может определить, что я делаю неправильно программно или концептуально? Я использую Windows 7

Ответы [ 2 ]

5 голосов
/ 28 июля 2011

Чтобы получать WinEvents, вам нужно прокачивать сообщения, а Console.ReadKey (), скорее всего, этого не делает. Попробуйте вместо этого использовать MessageBox для тестирования - и замените его соответствующим циклом сообщений позже.

С MSDN :

Примечания:
...
Поток клиента, который вызывает SetWinEventHook, должен иметь цикл сообщений для получения событий
0 голосов
/ 21 июня 2013

добавить цикл обработки событий и вызвать его в void man. Я немного изменил ваш код и теперь он работает нормально .

public  class Program
{
    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;

    static void Main(string[] args)
    {
        WinEventDelegate dele = new WinEventDelegate(WinEventProc);
        IntPtr m_hhook = SetWinEventHook(EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_FOREGROUND, IntPtr.Zero, dele, 0, 0, WINEVENT_OUTOFCONTEXT);
        EventLoop.Run();
      //  Console.ReadKey();
    }

    static void WinEventProc(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
    {
        Console.WriteLine(hwnd.ToString());
    }
}
   public static class EventLoop
    {
        public static void Run()
        {
            MSG msg;

            while (true)
            {

                if (PeekMessage(out msg, IntPtr.Zero, 0, 0, PM_REMOVE))
                {
                    if (msg.Message == WM_QUIT)
                        break;

                    TranslateMessage(ref msg);
                    DispatchMessage(ref msg);
                }
            }
        }

        [StructLayout(LayoutKind.Sequential)]
        private struct MSG
        {
            public IntPtr Hwnd;
            public uint Message;
            public IntPtr WParam;
            public IntPtr LParam;
            public uint Time;
        }

        const uint PM_NOREMOVE = 0;
        const uint PM_REMOVE = 1;

        const uint WM_QUIT = 0x0012;

        [DllImport("user32.dll")]
        private static extern bool PeekMessage(out MSG lpMsg, IntPtr hwnd, uint wMsgFilterMin, uint wMsgFilterMax, uint wRemoveMsg);
        [DllImport("user32.dll")]
        private static extern bool TranslateMessage(ref MSG lpMsg);
        [DllImport("user32.dll")]
        private static extern IntPtr DispatchMessage(ref MSG lpMsg);
    }
}e
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...