1

I have a simple (windows) application that launches another application using the CreateProcess function. It then gets the correct hwnd by using EnumWindows and the process id of the newly created process.

After the hwnd has been gained, the 'main loop' of my applications begins. This loop continues until the application started by CreateProcess is no longer running.

Everything works perfectly, until I try to use PeekMessage to peek at the messages being sent to the application I have launched - It seems that no messages at all are being recognized by my application, but the program that was launched (via CreateProcess) is running as normal, doing everything it should..

What I am trying to achieve, is to remove certain messages from being sent to the application, mainly various F-keys (F1, F2..F12 keys), but also, if possible, I would like to change the menu shown in the application (I dont know the technical name for the menu I mean, its the one you see what you click on the application icon in the top right corner) - I want to add a small 'about' option.

If anyone could point out what I am doing wrong within my code, or to a better alternative for stopping certain keypresses from reaching the launched application, I would be very grateful.

Many thanks in advance. :)

Here is the code I currently have:

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;
                }
            }
        }
    }
}
Dekita RPG
  • 11
  • 4

2 Answers2

5

You can't intercept another message loop like that. Remember, that process will be doing its own message pump - it's not okay for you to be dispatching its messages, and I expect things would go very weird if you do.

The correct way is to set a hook. Use the SetWindowsHookEx function to install a hook on that window.

paddy
  • 60,864
  • 6
  • 61
  • 103
  • Damn! I had started looking into setting hooks, then somehow got distracted with the message loop - thinking that would have been able to catch the messages being sent. Thanks for the information though, I guess I should redirect my attention back to that :D – Dekita RPG Jul 22 '15 at 11:50
  • Have a good read through all that MSDN documentation. It's pretty comprehensive. You may need to change how your program is designed, as you may need to inject a DLL with the handler because it needs to run in the address space of the other process. Not 100% sure on this, and it's been a while since I worked with Windows. – paddy Jul 22 '15 at 11:56
  • Yea, I am having a good read through it all now. Thanks for your help :) – Dekita RPG Jul 22 '15 at 12:13
0

PeekMessage retrieves messages only from the message queue, associated with the its calling thread. Window, which messages you are trying to peek belongs to the different thread, so PeekMessage with its handle will never give you anything. You could either install a hook, or subclass its window procedure.

Ari0nhh
  • 5,720
  • 3
  • 28
  • 33
  • Subclassing... I had not considered such a thing.. What advantage would that have compared to setting a hook? – Dekita RPG Jul 22 '15 at 11:52
  • Subclassing allows you to change target window functionality any way you like, not just filter messages, sent to the window. Disadvantage is that its much harder and require very accurate implementation to keep target window in the working condition. Also subclassing would require some sort of dll injection, since your new `WndProc` code should be in the target process address space. Creating hooks is one of the ways to achieve that. – Ari0nhh Jul 22 '15 at 12:02
  • Well, if using hooks is an easier approach, then I will pursue that route for now.. I will keep in mind though that more could be done by subclassing the window. Thanks for the info. :D – Dekita RPG Jul 22 '15 at 12:15