Стартиране на приложение чрез 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
Е, ако използването на куки е по-лесен подход, тогава ще следвам този път засега. Ще имам предвид обаче, че може да се направи повече чрез подкласиране на прозореца. Благодаря за информацията. :Д - person Dekita RPG; 22.07.2015