Non-static parameter inside a static function

Go To StackoverFlow.com

0

I have this static callback function in MyClass, and I try to call another static function from it. There is a problem however, one of the arguments that Register() takes is a non-static class variable.

I thought of using the "this" keyword to overcome this problem but it seems I am unable to ('this' : can only be referenced inside non-static member functions). Here is my code:

class MyClass
{
...
    static LRESULT CALLBACK klHkProc(int nCode, WPARAM wParam, LPARAM lParam);
    static BOOL Register(DWORD vKey,KEYBLOCK* ptrKEYBLOCK);
    KEYBLOCK *kb;       
...

}
LRESULT CALLBACK MyClass::klHkProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT) (lParam);
    if (wParam == WM_KEYDOWN) 
    {
        MyClass::Register(p->vkCode,this->kb);
    }
    return CallNextHookEx(NULL, nCode, wParam, lParam);
}

Any suggestions?

2012-04-05 16:08
by ᴘᴀɴᴀʏɪᴏᴛɪs
Static functions can't access instance members. Where do you want to get the instance from - David Heffernan 2012-04-05 16:10
Do you have a place to pass extra data into wherever you register your callback? If so, you can pass this in there - Nate 2012-04-05 16:12


1

Given what you wrote it is hard to answer this without more information.

However, assuming that all instances of MyClass should be processed, I suggest adding a static std::list<MyClass *> into which you place each instance's this pointer in the constructor for MyClass and then in the destructor of MyClass to remove the this from this list.

Then in your static klHkProc() you would iterate over the static list of all instances of MyClass and for each one call MyClass::Register() with the kb of each such registered instance of MyClass.

Here is a rough outline of the code to do this:

class MyClass
{
...
public:
    static LRESULT CALLBACK klHkProc(int nCode, WPARAM wParam, LPARAM lParam);
    static BOOL Register(DWORD vKey,KEYBLOCK* ptrKEYBLOCK);
    static std::list<MyClass *> allInstances;
    KEYBLOCK *kb;

    MyClass() {
      ...
      allInstances.push_back(this);
      ...
    }
    ~MyClass() {
      ...
      // Assumes not a huge list of instances as this is O(n) and thus destruction
      // of all instances of MyClass in O(n^2) on the number of instances.
      allInstances.remove(this);
      ...
    }

...
};

LRESULT CALLBACK MyClass::klHkProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT) (lParam);
    if (wParam == WM_KEYDOWN)
    {
        std::list<MyClass *> itr = allInstances.begin();
        std::list<MyClass *> end = allInstances.end();
        for (; itr != end; ++itr) {
          MyClass *current = *itr;
          MyClass::Register(p->vkCode, current->kb);
        }
    }
    return CallNextHookEx(NULL, nCode, wParam, lParam);
}
2012-04-05 16:13
by WilliamKF
Each instance of the class would have a pointer to the current KeyBlock object, this needs to be different for every instance, as each instance uses different keyblocks. I want to use the Register function to record a keypress into the KeyBlock object of the specific instanc - ᴘᴀɴᴀʏɪᴏᴛɪs 2012-04-05 16:20
So this is a keypress event from the user and upon each keypress event you wish to take the registered action - WilliamKF 2012-04-05 16:23
Yes that's what I wan - ᴘᴀɴᴀʏɪᴏᴛɪs 2012-04-05 16:25
How do you know which instance of MyClass should be the target of the keypress event? Also, on the keypress is klHkProc() being called or is something being done with the registered item - WilliamKF 2012-04-05 16:27
I have each class create it's own thread and capturing keystrokes at the same time, so basically all instances. klHkProc is set via SetWindowsHookE - ᴘᴀɴᴀʏɪᴏᴛɪs 2012-04-05 16:32
Do I understand correctly that all threads in your application are supposed to process each keystroke event - WilliamKF 2012-04-05 16:34
Yes that is the cas - ᴘᴀɴᴀʏɪᴏᴛɪs 2012-04-05 16:35


0

There is no implicit connection between a static member and any particular object instance.

You could pass a pointer or reference to a MyClass object to klHkProc(), which it can then pass to Register().

2012-04-05 16:13
by Grimm The Opiner


0

Generally speaking, If KEYBLOCK *kb is not static you cannot reference it inside the static function. the 'this' pointer only makes sense inside an instance of an object. So, if KEYBLOCK *kb only makes sense inside an instantiated object then, you would have to instantiate a MyClass inside Register or klHkProc. It would be easier to determine whether the latter makes sense to instantiate MyClass inside Register or not if you gave us a better context of what Register is supposed to be doing rather than just the showing the caller.

2012-04-05 16:16
by Ahmed Masud
Ads