如何让我的回调函数工作?

时间:2011-10-14 13:52:35

标签: c++ callback

我正在使用EnumDisplayMonitors获取监控信息:

BOOL CALLBACK MonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData){
  Class::callback(hMonitor,hdcMonitor,lprcMonitor,dwData);
  return true;
}

bool Class::callback(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData){
  classVar.appendData("callback");
  return true;
}

bool Class::f(){
  ...
  EnumDisplayMonitors(NULL,NULL,MonitorEnumProc,NULL);
  ...
}

Class::callback是静态的(如果不是我得到错误C2352:非静态调用非静态函数)。但是这会导致classVar出现问题:错误C2228:'。appendData必须有class / struct / union'。我应该在这里做些什么来解决这个问题(我希望回调将数据写入classVar)?

4 个答案:

答案 0 :(得分:4)

EnumDisplayMonitors()的最后一个参数是保留供调用者使用的额外指针。它被解释为未回溯到回调函数。传递指向类实例的指针。

BOOL CALLBACK MonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData){
  reinterpret_cast<Class*>(dwData)->callback(hMonitor,hdcMonitor,lprcMonitor);
  return true;
}

bool Class::callback(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor){
  classVar.appendData("callback");
  return true;
}

bool Class::f(){
  ...
  EnumDisplayMonitors(NULL,NULL,MonitorEnumProc,reinterpret_cast<LPARAM>(this));
  ...
}

答案 1 :(得分:2)

使用LPARAM dwData提供指向对象的指针。如果要为回调提供更多数据,则使用辅助结构将所有数据放在一起并将指针传递给此结构。

BOOL CALLBACK MonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData)
{
  ((Class*)dwData)->callback(hMonitor,hdcMonitor,lprcMonitor);
  return true;
}

bool Class::callback(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor)
{
  classVar.appendData("callback");
  return true;
}

bool Class::f()
{
  ...
  EnumDisplayMonitors(NULL,NULL,MonitorEnumProc, (LPARAM)this);
  ...
}

编辑:使用辅助结构:

BOOL CALLBACK MonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData)
{
  Class theClass = ((Auxiliary*)dwData)->theClass;
  RestOfData theRest = ((Auxiliary*)dwData)->theRest;

  theClass->callback(hMonitor,hdcMonitor,lprcMonitor, theRest);
  return true;
}

bool Class::callback(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, RestOfData* theRest)
{
  // use theRest
  classVar.appendData("callback");
  return true;
}

bool Class::f()
{
  ...
  Auxiliary theBundle(this, theRest);
  EnumDisplayMonitors(NULL,NULL,MonitorEnumProc, (LPARAM)theBundle);
  ...
}

答案 2 :(得分:1)

您可以使用dwData参数传入指向类实例的指针,例如:(注意:回调不再需要是静态的 - 实际上它已经过时了):

BOOL CALLBACK MonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData){
  ((Class*)dwData)->callback(hMonitor,hdcMonitor,lprcMonitor);
  return true;
}

bool Class::callback(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor){
  appendData("callback");
  return true;
}

bool Class::f(){
  ...
  EnumDisplayMonitors(NULL,NULL,MonitorEnumProc,this);
  ...
}

答案 3 :(得分:0)

我有时遇到这个问题,通常通过function objects解决它,它们比静态函数更通用,你可以创建一个可以在传递给MonitorEnumProc之前记住任何参数。