Reputation: 33931
I'm getting monitor information using 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
is static (if it isn't I get error C2352: illegal call of non-static function). This however causes problems with classVar
: error C2228: left of '.appendData must have class/struct/union'. What should I be doing here to get around this problem (I want the callback to write data to classVar
)?
Upvotes: 3
Views: 2090
Reputation: 998
I sometimes have this problem, and usually solve it through function objects, they are more versatile that static functions, and you can create one which can memorize any parameter before being passed to MonitorEnumProc.
Upvotes: 0
Reputation: 16769
Use LPARAM dwData to provide pointer to the object. If there's more data to provide to callback then use auxiliary struct to put all data together and pass pointer to this struct.
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);
...
}
EDIT: With auxiliary struct:
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);
...
}
Upvotes: 2
Reputation: 45274
The last parameter of EnumDisplayMonitors()
is an extra pointer reserved for use by the caller. It is passed uninterpreted to the callback function. Pass a pointer to the class instance.
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));
...
}
Upvotes: 4
Reputation: 7164
You can use the dwData argument to pass in a pointer to your class instance, i.e. something like this (note: callback won't need to be static anymore - actually it becomes obsolete):
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);
...
}
Upvotes: 1