简体   繁体   中英

Callback method is not called when using WinAPI WH_CALLWNDPROC hook

I want to get messages when a window is moving.

I started to write a simple c++ console application that hooks into the default notepad application of windows. One part of it contains the following code to set the hook (not all three, only one)

_hook = SetWindowsHookEx(WH_MOUSE, CallWndProc, _dllInstance, tid); //WORKS
_hook = SetWindowsHookEx(WH_KEYBOARD, CallWndProc, _dllInstance, tid); //WORKS
_hook = SetWindowsHookEx(WH_CALLWNDPROC, CallWndProc, _dllInstance, tid); //DOESNT WORK

So basically the procedure of the hooking is the same and every hook type works with the same callback function. Why does it not work with the WH_CALLWNDPROC? When applying WH_CALLWNDPROC the hook is successful like the others but it simply doesn't work.

This is the callback function

// The callback function
LRESULT CALLBACK CallWndProc(int nCode, WPARAM wParam, LPARAM lParam) {
    std::cout << "callback " << counter++ << "\n";

    //This is a must
    return CallNextHookEx(_hook, nCode, wParam, lParam);
}

But CallWndProc is never called when setting this hook.

I even tried to call the CallWndProc function inside of the DLL but this also didn't work so I removed it entirely from the DLL and now it's an empty DLL. Even if it worked, it would be of no use to me because I need to handle the messages in my application not on the target thread.

Any Tips? Here is the full code

#include "Main.h"
#include <Windows.h>

#include <iostream>


/* Variable to store the HANDLE to the hook. Don't declare it anywhere else then globally
or you will get problems since every function uses this variable. */
HHOOK _hook;

// the dll instance
HINSTANCE _dllInstance;

//HOOKPROC _dllCallback;

int counter = 0;

// The callback function
LRESULT CALLBACK CallWndProc(int nCode, WPARAM wParam, LPARAM lParam) {
    std::cout << "callback " << counter++ << "\n";

    //This is a must
    return CallNextHookEx(_hook, nCode, wParam, lParam);
}

// This functions installs a hook to a window with given title
int InstallHook(const wchar_t* title) {

    /* 1. Get window handle of given title */
    std::wcout << "INFO: Getting window handle for \"" << title << "\"...\n";
    HWND hwnd = FindWindow(NULL, title);
    if (hwnd == NULL) {
        std::cout << "ERROR: Could not find target window.\n";
        return -1;
    }
     
    /* 2. Get ThreadID (TID) of the window handle */ 
    std::wcout << "INFO: Getting TheadID (TID) of \"" << title << "\"...\n";
    DWORD pid = NULL; // If we dont know -> NULL
    DWORD tid = GetWindowThreadProcessId(hwnd, &pid);
    if (tid == NULL) {
        std::cout << "ERROR: Could not find target window.\n";
        return -2;
    }

    /* 3. Load in the DLL */
    std::wcout << "INFO: Loading the DLL\n";
    _dllInstance = LoadLibrary(TEXT("winhooks_dll.dll"));
    if (_dllInstance == NULL) {
        std::cout << "ERROR: Could not load DLL...\n";
        return -3;
    }

    /* 3.5 Get Callback function from dll*/
    //_dllCallback = (HOOKPROC)GetProcAddress(_dllInstance, "_wmProcCallback@12");
    //if (_dllCallback == NULL) {
    //  std::cout << "ERROR: Could not get Callback function from dll instance\n";
    //  return -4;
    //}

    /* 4. Install the hook and set the handle */
    std::wcout << "INFO: Setting the hook...\n";
    _hook = SetWindowsHookEx(WH_MOUSE, CallWndProc, _dllInstance, tid); // The local callback version
    //_hook = SetWindowsHookEx(WH_CALLWNDPROCRET, _dllCallback, _dllInstance, tid); // The dll callback function
    if (_dllInstance == NULL) {
        std::cout << "ERROR: Could not set hook handle\n";
        return -5;
    }

    return 0;
}

int main() {

    const wchar_t* title = L"Untitled - Notepad";

    if (InstallHook(title) != 0) {
        std::wcout << "ERROR: Could not install hook on " << title << " last error -> " << GetLastError() << "\n";
        system("pause");
        return 1;
    }

    std::wcout << "SUCCESS: Hook is successfully installed on " << title << "\n";
    std::wcout << "Running message loop..." << std::endl;

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

Firstly, source platform (32bit or 64bit) must be matched to destination platform.(In my 64bit machine, notepad is 64bit.)
Secondly,for a hook procedure in DLL, Don't verify whether it works or not by print, the same as std::out. The DLL has nowhere to print its content. The following code uses a file stream.

// The callback function
LRESULT CALLBACK CallWndProc(int nCode, WPARAM wParam, LPARAM lParam) {
    if (nCode == HC_ACTION)
    {
        if (wParam > 0)
        {
            std::cout << "sent by the current thread wParam=" << wParam;
        }
        CWPSTRUCT* s = (CWPSTRUCT*)lParam;

        //have no
        std::cout << " Index=" << nwinhooksdll++ << " s->message=" << s->message << " s->hwnd=" << s->hwnd << " s->wParam=" << s->wParam << " s->lParam=" << s->lParam << "\n";
        //MessageBox(NULL,L"CallWndProc",L"CALLBACK",0);

        //works
        myfile << " Index=" << nwinhooksdll++ << " s->message=" << s->message << " s->hwnd=" << s->hwnd << " s->wParam=" << s->wParam << " s->lParam=" << s->lParam << "\n";
    }

    //This is a must
    return CallNextHookEx(_hook, nCode, wParam, lParam);
}

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM