PostMessage для текущего активного процесса не работает для всех процессов? - PullRequest
0 голосов
/ 12 октября 2011

У меня есть этот код:

    const UInt32 WM_KEYDOWN = 0x0100;

    const int VK_DOWN = 0x28;
    const int VK_UP = 0x26;

    [DllImport("user32.dll")]
    static extern bool PostMessage(IntPtr hWnd, UInt32 Msg, int wParam, int lParam);

    [DllImport("user32.dll")]
    private static extern IntPtr GetForegroundWindow();

    [DllImport("user32.dll")]
    private static extern Int32 GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);

    private static Process GetProcessByHandle(IntPtr hwnd)
    {
        try
        {
            uint processID;
            GetWindowThreadProcessId(hwnd, out processID);
            return Process.GetProcessById((int)processID);
        }
        catch { return null; }
    }

    public static Process GetActiveProcess()
    {
        IntPtr hwnd = GetForegroundWindow();
        return hwnd != null ? GetProcessByHandle(hwnd) : null;
    }

    public static void KeyUp()
    {
        PostMessage(GetActiveProcess().MainWindowHandle, WM_KEYDOWN, VK_UP, 0);
    }

    public static void KeyDown()
    {
        PostMessage(GetActiveProcess().MainWindowHandle, WM_KEYDOWN, VK_DOWN, 0);
    }

Когда я вызываю KeyUp / KeyDown, он работает только на некотором процессе, таком как текстовые редакторы, Visual Studio.

Но не работаетна Explorer.exe, iTunes.exe, Chrome.exe, Outlook.exe, FileZilla.exe и т. д.

Я запустил отладку на консоли:

    while (true)
    {
        Process currentProcess = GetActiveProcess();
        if (currentProcess != null)
            Console.WriteLine(currentProcess.MainWindowTitle);
        Thread.Sleep(1000);
    }

Вот что я получаю отнекоторые приложения:

ProjName - Microsoft Visual Studio (Administrator)
?PostMessage to Current Active Proccess doesn't work for all proccess ? - StackOverFlow - Google Chrome?
FileZilla
Inbox - Outlook Data File - Microsoft Outlook

И на Explorer.exe я получаю пустую строку ..

1 Ответ

2 голосов
/ 12 октября 2011

Существует несколько способов считывания состояния клавиатуры в приложении Windows, и ответы на WM_KEYDOWN и WM_KEYUP являются лишь одним из них. Приложения также могут использовать GetKeyState или GetAsyncKeyState . Приложения также могут отвечать на сообщения WM_CHAR , WM_SYSKEYDOWN и WM_SYSKEYUP . Разные приложения будут использовать разные методы, и если вы не имитируете тот, который ищет приложение, оно не будет отвечать.

Проблема, с которой вы столкнулись, немного отличается от той, которая была поставлена ​​в вопросе, с которым связался Рэймонд, но решение может быть таким же. А именно, используя SendInput вместо PostMessage

...