Не получаются сообщения оконной процедуры после перехвата WH_CALLWNDPROC - PullRequest
2 голосов
/ 23 марта 2012

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

Я правильно использую функцию в DLL для нелокальной ловушки. Вот мой код приложения.

#include <Windows.h>
#include <stdio.h>

HINSTANCE hinst;
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

int main() {
    HWND notepad = FindWindow(NULL, L"Untitled - Notepad");

    if (!notepad)
        return 0;

    hinst = GetModuleHandle(NULL);

    // create a window class:
    WNDCLASS wc = {};
    wc.lpfnWndProc = WindowProc;
    wc.hInstance = hinst;
    wc.lpszClassName = L"hooking";

    // register class with operating system:
    RegisterClass(&wc);

    // create and show window:
    HWND hwnd = CreateWindow(L"hooking", L"hooking", WS_OVERLAPPEDWINDOW, 0, 0, 500, 400, NULL, NULL, hinst, NULL);

    if (hwnd == NULL) {
        return 0;
    }

    ShowWindow(hwnd, SW_SHOW);

    DWORD threadID = GetWindowThreadProcessId(notepad, NULL);

    HINSTANCE hinstDLL = LoadLibrary(TEXT("..\\Debug\\ProcHookDLL.dll"));

    void (*AttachHookProc)(DWORD);
    AttachHookProc = (void (*)(DWORD)) GetProcAddress(hinstDLL, "AttachHook"); 
    AttachHookProc(threadID);

    // handle messages:
    MSG msg = {};

    while(GetMessage(&msg, hwnd, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    printf("Done execution... press any key to exit");
    char garbage = getchar();
    return 0;
}


LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    if (uMsg == WM_DESTROY) {
        PostQuitMessage(0);
    }
    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

Вот код для DLL. Есть ли причина, по которой я не получаю никаких сообщений?

#include <Windows.h>
#include <stdio.h>

// TODO: create a mutex so this can only be loaded once
HMODULE thisModule;
HHOOK hook;
LRESULT CALLBACK LaunchListener(int nCode, WPARAM wParam, LPARAM lParam);

BOOL APIENTRY DllMain(HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
{
    thisModule = hModule;

    // Very restricted set of things that can be done in DllMain, refer to documentation
    // before adding anything here.

    switch (ul_reason_for_call) {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
        break;
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

#ifdef __cplusplus    // If used by C++ code, 
extern "C" {          // we need to export the C interface
#endif
//window message loop is necessary for hooks to work? (didn't work with console app)
//provide function pointer to execute when notepad is launched.
__declspec(dllexport) void AttachHook(DWORD threadID) {
    hook = SetWindowsHookEx(WH_CALLWNDPROC, LaunchListener, thisModule, threadID);
}
#ifdef __cplusplus
}
#endif

LRESULT CALLBACK LaunchListener(int nCode, WPARAM wParam, LPARAM lParam) {
    // process event here
    if (nCode >= 0) {
        //wparam specifies if the message was sent by the current thread or not.
        CWPSTRUCT * cwp = (CWPSTRUCT *)lParam;
        wchar_t windowName[256];
        GetWindowText(cwp->hwnd, windowName, 256);
        wprintf(L"%#8X: %s\n", cwp->message, windowName);
        if (cwp->message == WM_CREATE) {
            __debugbreak();
            wchar_t moduleName[256];
            //cwp->hwnd
            //GetModuleFileName(0, moduleName, 256);
            GetWindowText(cwp->hwnd, moduleName, 256);
            int x = 0;
            x++;
        }
    }

    return CallNextHookEx(NULL, nCode, wParam, lParam);
}

Ответы [ 2 ]

1 голос
/ 26 марта 2012

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

1 голос
/ 23 марта 2012

Похоже, это должно работать. Просто проверяю несколько предложений.

  • 32-битная DLL будет перехватывать только 32-битные процессы. А 64-битная DLL будет перехватывать только 64-битные процессы.
  • Попробуйте установить dwThreadId на 0, чтобы создать глобальный хук, чтобы посмотреть, работает ли он таким образом.
  • Убедитесь, что DLL-файл перехвата может быть найден и доступен для чтения целевым процессом.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...