Can I use member function as first argument to EnumWindows? I don't see any workaround in this case even with boost::bind.
            Asked
            
        
        
            Active
            
        
            Viewed 1,296 times
        
    4
            
            
         
    
    
        hmjd
        
- 120,187
- 20
- 207
- 252
 
    
    
        FrozenHeart
        
- 19,844
- 33
- 126
- 242
- 
                    1Or you can make your own `bind` function (with right calling convention) using `lParam` to pass it a pointer to member function... – Adriano Repetti Dec 11 '13 at 14:05
- 
                    @hmjd Visual Studio 2013 – FrozenHeart Dec 11 '13 at 14:07
- 
                    @FrozenHeart, you should be able to use a lambda (I don't have access to a VS compiler at the moment). – hmjd Dec 11 '13 at 14:08
- 
                    @hmjd Capturing lambdas cannot be converted to free functions. – Raymond Chen Dec 11 '13 at 14:15
- 
                    @hmjd It's clear that capturing lambdas cannot be converted to free functions because how would it know where to get its captured variables from? – Raymond Chen Dec 11 '13 at 14:29
- 
                    @RaymondChen: trampoline. But that might be hard on exotic hardware. – MSalters Dec 11 '13 at 14:33
- 
                    @MSalters C++ has no provision for dynamic code generation. (Harvard architecture does not support it, for example. NX for another.) C++ is based on the principle that all code generation occurs at compile time. – Raymond Chen Dec 11 '13 at 14:48
2 Answers
7
            Given this normal callback function:
BOOL CALLBACK EnumWindowsProc(HWND wnd, LPARAM lParam);
You can invoke EnumWindows using lParam to pass it a pointer to your class:
EnumWindows(EnumWindowsProc, reinterpret_cast<LPARAM>(this));
In EnumWindowsProc you can simply call member function (casting lParam to your class type). Like this:
BOOL CALLBACK EnumWindowsProc(HWND wnd, LPARAM lParam)
{
    return reinterpret_cast<MyClass*>(lParam)->EnumWindows(wnd);
}
If you don't want to make your class method public you can:
- Pack a struct to contain both class instance and pointer to member.
- Use a library for delegates.
- Use boost std:bind(in this case it'll work well because you do it on your own class member, it has not to be__stdcall).
Whatever you will use you can find more details in this post here on SO.
 
    
    
        Community
        
- 1
- 1
 
    
    
        Adriano Repetti
        
- 65,416
- 20
- 137
- 208
- 
                    
- 
                    
- 
                    @manuell pretty right, fixed...price to pay for uncompiled snippets wrote here! – Adriano Repetti Dec 11 '13 at 14:37
- 
                    @Adriano I really would like to see the code for the std::bind case (bonus, it's in the OP question) – manuell Dec 11 '13 at 15:50
- 
                    @manuell just look John's answer (or link in my answer to another SO post). It's little bit too prolix but more or less it's that. – Adriano Repetti Dec 11 '13 at 15:52
- 
                    @Adriano That's using the LPARAM... Sigh... I hoped for some magic. Never mind. – manuell Dec 11 '13 at 15:58
- 
                    
3
            
            
        EnumWindows takes a callback that looks like this
BOOL CALLBACK EnumWindowsProc(HWND hwnd,LPARAM lParam);
You cannot use either a member function or a lambda that has a capture. You do this instead.
typedef std::function<bool(HWND hwnd)> func_type;
BOOL CALLBACK MyEnumProc(HWND hwnd, LPARAM lparam)
{
    auto& func = *reinterpret_cast<func_type*>(lparam);
    if(func(hwnd))return TRUE;
    else return FALSE;
}
You would use it like this
auto f = std::make_shared<func_type>(std::bind(&mymemberfunction,this));
EnumWindows(MyEnumProc,reinterpret_cast<LPARAM>(f.get()));
//Make sure to keep the shared_ptr around until you are done enumerating
 
    
    
        John Bandela
        
- 2,416
- 12
- 19