«SendMessage» для 3 разных процессов в C ++ - PullRequest
2 голосов
/ 25 марта 2012

Я хочу отправить нажатия клавиш нескольким процессам. Например, если я нажимаю «1», то я хочу отправить «1» на 3 «окна блокнота». Фрист Я хочу попробовать отправить нажатие клавиши в блокнот, но это не удается на HWND:

    //HANDLE hWin; 
    HWND windowHandle = FindWindowA(NULL, "Notepad");   //Can’t find a proccess

    //Send a key
    if( windowHandle ) //This one fails
    {
        while(true)
        {
            if( GetAsyncKeyState(VK_F12) != 0 )
            {
                SendMessageA(windowHandle, WM_KEYDOWN, VK_NUMPAD1, 0); 
                Sleep(1000); 
                SendMessageA(windowHandle, WM_KEYUP, VK_NUMPAD1, 0);
            }
                    Sleep(100);
        }
    }

Но метод FindWindow недостаточно хорош для моей программы. Также нет способа получить 3 разных процесса с одинаковыми именами. Итак, как я могу сделать 3 дескриптора для 3 разных процессов с одинаковым именем? И как я могу отправить ключи процессам?

Ответы [ 3 ]

3 голосов
/ 25 марта 2012

Вы можете использовать EnumWindows для перечисления всех окон верхнего уровня в системе. Затем вам нужно отфильтровать эти окна, чтобы получить те, которые вас интересуют. Имя класса, вероятно, является лучшим выбором для фильтрации, а не имени окна. Вот пример кода (не проверенного) того, что я имею в виду:

BOOL CALLBACK BroadcastToNotepad(HWND hwnd, LPARAM lParam)
{
    wchar_t lpClassName[16];

    /*
     * More reliable to filter by class name. We could additionally filter
     * by caption name too if necessary.
     */
    if(GetClassName(hwnd, lpClassName, _countof(lpClassName))) {
        if(wcscmp(lpClassName, L"Notepad") == 0) {
            SendMessage(hwnd, WM_KEYDOWN, (WPARAM)lParam, 0);
            Sleep(1000);
            SendMessage(hwnd, WM_KEYUP, (WPARAM)lParam, 0);
        }
    }

    return TRUE;
}

// Some handler which gets invoked when your hotkey is hit.
void handlerKey1(...)
{
    EnumWindows(BroadcastToNotepad, (lParam)VK_NUMPAD1)
}

Обратите внимание на использование BroadcastToNotepad и на то, как разные обработчики могут передавать разные lParam.

И последнее, что следует отметить, это то, что PostMessage / SendMessage не является надежным способом имитации ввода с клавиатуры. Это замечено Раймондом Ченом здесь . SendInput является предпочтительным способом ввода данных. Однако, чтобы использовать это, вам нужно убедиться, что окно, в которое вы хотите отправить, имеет фокус клавиатуры.

Я смутно припоминаю, что играл с чем-то похожим на то, что вы делали в прошлом. Если я правильно помню, вам нужно отправить в дочернее окно Блокнота (имя класса = Edit). Поэтому приведенный выше код необходимо изменить следующим образом:

if(wcscmp(lpClassName, L"Notepad") == 0) {
    HWND hwndChild = FindWindowEx(hwnd, NULL, L"Edit", NULL);

    SendMessage(hwndChild, WM_KEYDOWN, (WPARAM)lParam, 0);
    Sleep(1000);
    SendMessage(hwndChild, WM_KEYUP, (WPARAM)lParam, 0);
}
1 голос
/ 25 марта 2012

Сначала установите Spy ++ из Visual Studio, которая позволяет просматривать все окна HWND в иерархии (и какому процессу они принадлежат).

Тогда вы увидите, почему ваше FindWindow не работает. Вы также будете знать точную иерархию вызовов для FindWindow и GetWindow ().

Имейте в виду, что начиная с Vista некоторые HWND защищены, и вы не можете отправлять их, но блокнот, вероятно, в порядке.

Для отправки ключа вы можете просто использовать PostMessage, чтобы запустить и забыть.

0 голосов
/ 25 марта 2012

Прежде всего, почему там есть время (true)?Разве вы не хотите активировать программное обеспечение нажатием клавиши F12, чем бесконечный цикл?Знаете, этот дескриптор недействителен вечно.

Во-вторых, вы, вероятно, захотите использовать EnumWindows , чтобы пройти через все окна и найти то, что вас интересует. Тогда выреализовать функцию обратного вызова, которая должна будет определенным образом решить, будет ли она действовать в каком-либо окне или нет (будь то имя или что-то еще).

SendMessage / SendMessageA / SendMessageW должно работать очень хорошо, когдаВы нашли правильный дескриптор для окна, для которого хотите настроить таргетинг (за исключением некоторых специальных окон, которые защищены от этого).

...