0

我已经构建了一个有效的键盘记录器,现在我想将它移到课堂上,这样我就可以随时重复使用它,甚至可以在不同的语言(如 c#)上重复使用它,但是我遇到了错误,因为相同的代码在课堂内不起作用。

main.cpp(工作)

LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam);

void main()
{
    HINSTANCE h_instance = GetModuleHandle(NULL);
    SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardProc, h_instance, 0); // Works here
}

LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    // Populate typedChars
    return NULL;
}

KeyboardHook.cpp(不工作)

class KeyboardHook
{
    stringstream typedChars;

    LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
    {
        // Populate typedChars
        return NULL;
    }

    KeyboardHook()
    {
        HINSTANCE h_instance = GetModuleHandle(NULL);
        SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardProc, h_instance, 0); // Does not work
    }

public:
    std::string Get()
    {
        return typedChars.str();
    }

    void Clear()
    {
        typedChars.str(std::string());
        typedChars.clear();
    }
};

错误

C3867: 'KeyboardHook::KeyboardProc': function call missing argument list; use '&KeyboardHook::KeyboardProc' to create a pointer to member

所以我将其修改为SetWindowsHookEx(WH_KEYBOARD_LL, &KeyboardProc, h_instance, 0);,现在发生了不同的错误

C2276: '&' : illegal operation on bound member function expression

我也试过但没有成功:

SetWindowsHookEx(WH_KEYBOARD_LL, (LRESULT)&KeyboardProc, h_instance, 0);
SetWindowsHookEx(WH_KEYBOARD_LL, (LRESULT)KeyboardProc, h_instance, 0);
SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHook::KeyboardProc, h_instance, 0);
SetWindowsHookEx(WH_KEYBOARD_LL, &KeyboardHook::KeyboardProc, h_instance, 0);
4

2 回答 2

1

假设SetWindowsHookEx应该采用函数指针(我永远无法理解可怕的 Windows API 文档),您需要将指向成员函数的指针绑定到应该调用它的对象。如果你想将它绑定到指向的对象this(即KeyboardHook你当时正在创建的对象),试试这个:

using std::placeholders;
SetWindowsHookEx(WH_KEYBOARD_LL,
  std::bind(&KeyboardHook::KeyboardProc, this, _1, _2, _3),
  h_instance, 0);

或者,KeyboardProc可以声明为静态成员函数,但这意味着它将无法使用该typedChars成员。

于 2013-02-14T21:30:18.703 回答
0

您必须定义KeyboardProc为静态成员

static LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
...
}

如果它必须并且可以在没有对象的情况下调用。

于 2013-02-14T21:29:28.877 回答