John Kenedy
John Kenedy

Reputation: 574

Pass method in a class as argument

I have a class like this

class Keyboard
{
public:
    Keyboard(void);
    ~Keyboard(void);
    void SetHook(HINSTANCE hInstance);
    LRESULT CALLBACK keyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam);
};


LRESULT CALLBACK Keyboard::keyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    bool bControlKeyDown=0;
    bool caps = GetKeyState(VK_CAPITAL) < 0;

...

void Keyboard::SetHook(HINSTANCE hInstance)
{
    KeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, Keyboard::keyboardHookProc, hInstance, NULL);
}

But the statement

KeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, Keyboard::keyboardHookProc, hInstance, NULL);

Result in compile error

Error   7   error C3867: 'Keyboard::keyboardHookProc': function call missing argument list; use '&Keyboard::keyboardHookProc' to create a pointer to member

If I change to '&Keyboard::keyboardHookProc' it also error, also when I cast to '(HOOKPROC) &Keyboard::keyboardHookProc' it also error

Anyone please help

Upvotes: 2

Views: 1564

Answers (1)

PiotrNycz
PiotrNycz

Reputation: 24430

This is common mistake for C-callbacks.

Keyboard::keyboardHookProc must be static.

[UPDATE]

You must find some other way to get Keyboard object to this static method if you want to operate on Keyboard object in static Keyboard::keyboardHookProc. If you have one Keyboard you might use singleton pattern, If not then every static method must have its own Keyboard object.

[UPDATE2]

One of the way to link object with global function is by template object reference. But this work only for global objects:

class Keyboard
{
public:
    Keyboard();
    ~Keyboard(void);
    LRESULT keyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam);
};

LRESULT Keyboard::keyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
}
// global function interface 
template <Keyboard& k>
LRESULT CALLBACK keyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
   return k.keyboardHookProc(nCode, wParam, lParam);
}


Keyboard k; // global keyboard

int main()
{
   // this works
   SetWindowsHookEx(0, keyboardHookProc<k>, NULL, NULL);
}  

Upvotes: 3

Related Questions