Запускаете приложение через CreateProcess, но не видите PeekMessage?

У меня есть простое приложение (Windows), которое запускает другое приложение с помощью функции CreateProcess. Затем он получает правильный hwnd, используя EnumWindows и идентификатор вновь созданного процесса.

После получения hwnd начинается «основной цикл» моих приложений. Этот цикл продолжается до тех пор, пока приложение, запущенное CreateProcess, не перестанет работать.

Все работает отлично, пока я не попытаюсь использовать PeekMessage для просмотра сообщений, отправляемых в приложение, которое я запустил. Кажется, что мое приложение вообще не распознает сообщения, но запущенная программа (через CreateProcess) работает. как обычно, делаю все, что надо ..

То, что я пытаюсь достичь, - это удалить определенные сообщения из отправки в приложение, в основном различные F-клавиши (клавиши F1, F2..F12), но также, если возможно, я хотел бы изменить меню, показанное в приложение (я не знаю технического названия для меню, я имею в виду, это то, что вы видите, что вы нажимаете на значок приложения в правом верхнем углу) - я хочу добавить небольшую опцию «о».

Если бы кто-нибудь мог указать на то, что я делаю неправильно в своем коде, или на лучшую альтернативу для предотвращения попадания определенных нажатий клавиш в запущенное приложение, я был бы очень благодарен.

Спасибо заранее. :)

Вот код, который у меня сейчас есть:

VOID PerformLaunch(LPWSTR lpAppName, LPTSTR lpCmdLine) {
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    DWORD dwLoopExitCode = NULL;
    BOOL cpBool = FALSE;
    BOOL finishedLoop = FALSE;
    MSG message = { 0 };

    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
    ZeroMemory(&si, sizeof(STARTUPINFO));
    si.cb = sizeof(STARTUPINFO);

    cpBool = CreateProcess(lpAppName, lpCmdLine, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
    if (!cpBool) {
        MessageBox(Game_HWND, L"Could not start process!", L"Error:", MB_OK | MB_ICONERROR);
    }

    //-- Enumerate windows until Game_HWND && Game_Hook are not NULL.
    while (Game_Hook == NULL) {
        EnumWindows(MainEnumGameWindProc, pi.dwProcessId);
    }

    while (!finishedLoop) {
        DWORD dwWC = WaitForSingleObject(pi.hProcess, 0);
        if ((dwWC == WAIT_FAILED) || (dwWC == WAIT_OBJECT_0)|| (dwWC == WAIT_ABANDONED)) {
            DWORD dwExitCode;
            GetExitCodeProcess(pi.hProcess, &dwExitCode);
            CloseHandle(pi.hThread);
            CloseHandle(pi.hProcess);
            dwLoopExitCode = dwExitCode;
            finishedLoop = TRUE;
        }
        else {
            if (PeekMessage(&message, Game_HWND, 0, 0, PM_REMOVE)) {
                TranslateMessage(&message);
                DispatchMessage(&message);
                if (WM_QUIT == message.message) {
                    finishedLoop = TRUE;
                    break;
                }
            }
        }
    }
}

person Dekita RPG    schedule 22.07.2015    source источник


Ответы (2)


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

Правильный способ - поставить крючок. Используйте функцию SetWindowsHookEx, чтобы установить ловушку для этого окна.

person paddy    schedule 22.07.2015
comment
Проклятие! Я начал изучать установку хуков, а затем как-то отвлекся на цикл сообщений - подумал, что это могло бы перехватить отправляемые сообщения. Тем не менее, спасибо за информацию, я думаю, мне следует снова обратить внимание на это: D - person Dekita RPG; 22.07.2015
comment
Внимательно прочтите всю документацию MSDN. Это довольно полно. Возможно, вам потребуется изменить способ разработки вашей программы, поскольку вам может потребоваться внедрить DLL с обработчиком, поскольку он должен запускаться в адресном пространстве другого процесса. Не уверен на 100% в этом, и я давно не работал с Windows. - person paddy; 22.07.2015
comment
Да, я сейчас хорошо все это читаю. Спасибо за вашу помощь :) - person Dekita RPG; 22.07.2015

PeekMessage извлекает сообщения только из очереди сообщений, связанной с вызывающим потоком. Окно, сообщения которого вы пытаетесь просмотреть, принадлежит другому потоку, поэтому PeekMessage с его дескриптором никогда ничего вам не даст. Вы можете установить ловушку или подкласс его оконной процедуры.

person Ari0nhh    schedule 22.07.2015
comment
Создание подклассов ... Я не рассматривал такую ​​вещь .. Какое преимущество это было бы по сравнению с установкой крючка? - person Dekita RPG; 22.07.2015
comment
Создание подклассов позволяет вам изменять функциональность целевого окна как угодно, а не только фильтровать сообщения, отправленные в окно. Недостатком является то, что это намного сложнее и требует очень точной реализации, чтобы поддерживать целевое окно в рабочем состоянии. Также для создания подклассов потребуется некоторая инъекция dll, поскольку ваш новый код WndProc должен находиться в адресном пространстве целевого процесса. Создание крючков - один из способов добиться этого. - person Ari0nhh; 22.07.2015
comment
Что ж, если использование хуков - более простой подход, тогда я буду следовать этому пути… Я буду иметь в виду, что можно сделать больше, создав подкласс окна. Спасибо за информацию. : D - person Dekita RPG; 22.07.2015