Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/151.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何使用两个参数获得memfun_C++_Windows_Mem Fun - Fatal编程技术网

C++ 如何使用两个参数获得memfun

C++ 如何使用两个参数获得memfun,c++,windows,mem-fun,C++,Windows,Mem Fun,我想使用这个函数“EnumWindows(EnumWindowsProc,NULL);”。 EnumWindowsProc是一个回调函数: BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam); thisClass->ActualEnumWindowsProc(hwnd,lParam); 对于这个回调,我想使用一个类的成员函数 e、 g: 所以我想用我的函数绑定被调用的回调 我试试这个: void MyClass::test()

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

BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam);
thisClass->ActualEnumWindowsProc(hwnd,lParam);
对于这个回调,我想使用一个类的成员函数

e、 g:

所以我想用我的函数绑定被调用的回调

我试试这个:

void MyClass::test()
{
    EnumWindowsProc ptrFunc = mem_fun(&MyClass::My_EnumWindowsProc);
    EnumWindows(ptrFunc, NULL);
}
这是行不通的,“mem_fun”只能接受一个论点! 有可能吗?你还知道别的解决办法吗?
(使用Boost::bind可能会有一个解决方案)

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

BOOL CALLBACK My_EnumWindowsProc(MyClass* this, HWND hwnd, LPARAM lParam);
现在清楚了吗?这意味着您不能在此上下文中使用它

您需要创建一个,例如:

#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;
}
#包括
#包括
#包括
使用名称空间std;
类MyCallback
{
公众:
MyCallback():count_(0){};
静态BOOL回调回调适配器(HWND、LPARAM);
BOOL回调(HWND);
无符号计数;
};
BOOL MyCallback::Callback(HWND-wnd)
{
字符标题[1025]={};
GetWindowText(wnd,title,sizeof(title)-1);

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

SetWindowLong(handle,GWL_USERDATA,(DWORD)this);
然后在EnumWindowsProc(静态)中执行以下操作:

MyClass* thisClass = (MyClass*)GetWindowLong(hwnd,GWL_USERDATA);
现在你有了对象指针。你可以用它来调用一个非静态函数:

BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam);
thisClass->ActualEnumWindowsProc(hwnd,lParam);

别介意我最初的回答:你需要做的基本上是:

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);
}

伙计们,适配器对我来说工作得很好,下面是我的代码示例,我在EnumChildWindow中使用它来执行自动保存

头文件:

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);
}
boolcamInframe::InitInstance()
{
设置计时器(0,5*60*1000,空);
返回TRUE;
}
void CMainFrame::OnTimer(UINT nIDEvent)
{
::EnumChildWindows(m_-hWnd和CMainFrame::CallbackAdapter,NULL);
}
boolcmainframe::AutosaveTimerChildProc(HWND-HWND)
{
if(DYNAMIC_DOWNCAST(CVISIONView,CWnd::FromHandle(hwnd))!=NULL)
{
::PostMessage(hwnd,WM_MYVIEW_AUTOSAVETIMER,0,0);
}
返回TRUE;
}
boolcmainframe::CallbackAdapter(HWND-wnd,LPARAM-lp)
{
CMainFrame*that=重新解释铸件(lp);
返回该->AutosaveTimerChildProc(wnd);
}

我尝试了您的代码,但它不起作用,您的问题与我相同,错误是:“EnumWindows”:无法将参数1从“BOOL(u cdecl*)(HWND,LPARAM)转换'至'WNDENUMPROC'@Jaguar:我修复了声明中阻止32位编译器搜索我的代码的问题。请注意对
静态BOOL CallbackAdapter(HWND,LPARAM);
声明的更改,然后重试。(我添加了
CALLBACK
)谢谢John,这个方法工作得很好,但是我想尝试删除reinterpret_cast,用静态方法创建一个新类,并创建一个包含“this”的静态MyCallback*value…@Jaguar:不幸的是,您将无法消除reinterpret_强制转换,因为回调必须采用LPRAM。这正是在WINAPI@Jaguar:您可以使用C样式转换替换reinterpret_转换,如
(MyCallback*)lparam
,但它与reinterpret_cast的功能相同。reinterpret_cast在意图方面更具表现力,因此我坚持使用它。我需要一个方法来捕获桌面上所有已启动窗口的所有信息,这就是为什么我必须这样做的原因!您没有阅读我编写的内容吗?方法有+1个参数,您的回调必须有2Response只是说,在这种情况下,他不能使用成员函数作为回调函数。它没有显示如何完成需要完成的任务。@Jan:是的,我需要这样做,John Dibling的答案是正确的!