Как я могу заставить мою функцию обратного вызова работать? - PullRequest
3 голосов
/ 14 октября 2011

Я получаю информацию о мониторе, используя 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 должен быть класс / структура / объединение.Что я должен сделать здесь, чтобы обойти эту проблему (я хочу, чтобы обратный вызов записывал данные в classVar)?

Ответы [ 4 ]

4 голосов
/ 14 октября 2011

Последний параметр 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));
  ...
}
2 голосов
/ 14 октября 2011

Используйте 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);
  ...
}
1 голос
/ 14 октября 2011

Вы можете использовать аргумент 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);
  ...
}
0 голосов
/ 14 октября 2011

У меня иногда возникает эта проблема, и обычно я решаю ее с помощью функциональных объектов , они более универсальны, чем статические функции, и вы можете создать такой, который может запомнить любой параметр перед передачей в MonitorEnumProc.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...