2

我想使用这个函数“EnumWindows(EnumWindowsProc, NULL);”。EnumWindowsProc 是一个回调函数:

BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam);

对于这个回调,我想使用一个类的成员函数。

例如:

Class MyClass
{
    BOOL CALLBACK My_EnumWindowsProc(HWND hwnd, LPARAM lParam);
    void          test();
};

所以我想将调用的回调与我的函数绑定!!!

我试试这个:

void MyClass::test()
{
    EnumWindowsProc ptrFunc = mem_fun(&MyClass::My_EnumWindowsProc);
    EnumWindows(ptrFunc, NULL);
}

这是行不通的,“mem_fun”只能接受一个参数!有可能这样做吗?否则你知道另一种解决方案吗?(也许使用 Boost::bind 可以解决)

4

5 回答 5

3

您需要创建一个Adapter,例如:

#include <windows.h>
#include <iostream>
#include <string>
using namespace std;

class MyCallback
{
public:
    MyCallback() : count_(0) {};
    static BOOL CALLBACK CallbackAdapter(HWND, LPARAM);
    BOOL Callback(HWND);
    unsigned count_;
};

BOOL MyCallback::Callback(HWND wnd)
{
    char title[1025] = {};
    GetWindowText(wnd, title, sizeof(title)-1);
    cout << wnd << "= '" << title << "'" << endl;
    ++count_;
    return TRUE;
}

BOOL MyCallback::CallbackAdapter(HWND wnd, LPARAM lp)
{
    MyCallback* that = reinterpret_cast<MyCallback*>(lp);
    return that->Callback(wnd);
}

int main()
{
    MyCallback cb;
    EnumWindows(&MyCallback::CallbackAdapter, reinterpret_cast<LPARAM>(&cb));
    cout << "Windows Found: " << cb.count_;
    return 0;
}
于 2010-03-04T18:46:29.617 回答
0

不幸的是 EnumWindowsProc 需要是静态的以避免添加隐藏的“this”指针并使其与回调原型不兼容。我过去通过在使用此调用创建窗口后保存 this 指针来处理此问题:

SetWindowLong(handle,GWL_USERDATA,(DWORD)this);

然后在 EnumWindowsProc (它是静态的)里面做这样的事情:

MyClass* thisClass = (MyClass*)GetWindowLong(hwnd,GWL_USERDATA);

现在你有了对象指针。您可以使用它来调用非静态函数:

thisClass->ActualEnumWindowsProc(hwnd,lParam);
于 2010-03-04T19:12:56.270 回答
0

没关系我原来的答案:你需要做的基本上是这样的:

struct InfoINeed {
 MyClass * mThis;
 ...
};

BOOL MyCallback(HWND hwnd, LPARAM lParam) {
 InfoINeed* info = (InfoINeed*)hwnd;
 // do your stuff, i.e. info->mThis->MyImplementationForCallback(lParam)
 // note that you won't need to pass hwnd further, it's a pointer to your own context
}

void MyClass::test()
{
    InfoINeed Info = {this, ...};
    EnumWindows(MyCallback, &Info);
}
于 2010-03-04T19:15:20.983 回答
0

伙计们,适配器对我很有用,这是我的代码示例,我使用 EnumChildWindow 来执行 AutoSave。

头文件:

public:

    BOOL AutosaveTimerChildProc( HWND hwnd );
    static BOOL CALLBACK CallbackAdapter(HWND wnd, LPARAM lp);
...

C++ 文件:

BOOL CMainFrame::InitInstance()
{
    SetTimer(0, 5 * 60 * 1000,NULL);
    return TRUE;
}

void CMainFrame::OnTimer(UINT nIDEvent)
{
    ::EnumChildWindows(m_hWnd,&CMainFrame::CallbackAdapter,NULL);
}

BOOL CMainFrame::AutosaveTimerChildProc(HWND hwnd)
{
    if(DYNAMIC_DOWNCAST(CVISIONView,CWnd::FromHandle(hwnd)) != NULL)
    {
        ::PostMessage(hwnd,WM_MYVIEW_AUTOSAVETIMER,0,0);
    }

    return TRUE;
}

BOOL CMainFrame::CallbackAdapter(HWND wnd, LPARAM lp)
{
    CMainFrame* that = reinterpret_cast<CMainFrame*>(lp);
    return that->AutosaveTimerChildProc(wnd);
}
于 2013-03-12T12:22:23.517 回答
-1

看,每个类的非静态方法还有一个隐藏参数(第一个)this,它是指向类实例的指针。所以认为真正的签名是:

BOOL CALLBACK My_EnumWindowsProc(MyClass* this, HWND hwnd, LPARAM lParam);

现在更清楚了吗?这意味着您不能在这种情况下使用它

于 2010-03-04T18:36:33.450 回答