挂钩WH_CALLWNDPROC后没有得到Window Procedure消息

时间:2012-03-22 22:31:55

标签: c++ windows winapi hook

我尝试过使用全局钩子但钩子程序只接收了程序线程的窗口过程消息,并且针对特定应用程序(线程)导致根本没有消息。

我正在使用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 个答案:

答案 0 :(得分:1)

看起来它应该有效。只需查看一些建议。

  • 32位DLL只会挂钩32位进程。而64位DLL只会挂钩64位进程。
  • 尝试将dwThreadId设置为0以制作全局挂钩,以确定其是否正常工作。
  • 确保可以找到挂钩DLL并且目标进程可以读取它。

答案 1 :(得分:1)

没有问题,挂钩安装正确。但是我不知道钩子过程是从窗口过程得到消息的进程的上下文中运行的。