Using a class callback for a custom control?
I am creating a custom management class and since I want to have complete control over it I register the class and want to use the class
LRESULT CALLBACK OGLTOOLBAR :: ToolProc (HWND, UINT, WPARAM, LPARAM)
but that doesn't let me.
I am doing:
HWND OGLTOOLBAR::create(HWND parent,HINSTANCE hInst, int *toolWidthPtr)
{
if (toolhWnd != NULL)
{
return toolhWnd;
}
toolWidth = toolWidthPtr;
ZeroMemory(&rwc,sizeof(rwc));
rwc.lpszClassName = TEXT("OGLTool");
rwc.hbrBackground = GetSysColorBrush(COLOR_BTNSHADOW);
rwc.lpfnWndProc = (WNDPROC)ToolProc;
rwc.hCursor = LoadCursor(0, IDC_ARROW);
RegisterClass(&rwc);
toolhWnd = CreateWindowEx(NULL, rwc.lpszClassName,NULL,
WS_CHILD | WS_VISIBLE,
0, 0, *toolWidth, 900, parent, 0, NULL, 0);
return toolhWnd;
}
What is the correct way to do this?
thanks
the compiler says: Error 1 error C2440: "type cast": cannot convert from "overloaded function" to "WNDPROC"
a source to share
If ToolProc is not a static member, you cannot pass a pointer to a member function as a callback, assuming the ToolProc is not a static function, you can create a static member function and use GetWindowLong / SetWindowLong and GWL_USERDATA to store a pointer to the current object (this one), and have a static callback that calls the individual object callback function, which can use the individual objects' data members.
Assuming ToolProc is not a static member of your OGLTOOLBAR class, you must bind this object pointer to a window handle, you can do it like this:
void OGLTOOLBAR::SetObjectToHWnd( HWND hWnd, LPARAM lParam )
{
LPCREATESTRUCT cs = reinterpret_cast<LPCREATESTRUCT>(lParam);
OGLTOOLBAR *pWnd = reinterpret_cast<OGLTOOLBAR*>(cs->lpCreateParams);
SetLastError( 0 );
if( !SetWindowLong( hWnd, GWL_USERDATA, reinterpret_cast<long>(pWnd) )
&& GetLastError() )
//Do something about the error
}
OGLTOOLBAR *OGLTOOLBAR::GetObjectFromHWnd( HWND hWnd )
{
return reinterpret_cast<OGLTOOLBAR*>(GetWindowLong(hWnd,GWL_USERDATA));
}
And then you have a static member function WndProc (or ToolProc) like this:
LRESULT OGLTOOLBAR::StaticToolProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
if( uMsg == WM_NCCREATE )
SetObjectToHwnd( hWnd, lParam );
Window *pWnd = GetObjectFromWnd( hWnd );
if( pWnd )
return pWnd->ToolProc( hWnd, uMsg, wParam, lParam );
else
return DefWindowProc( hWnd, uMsg, wParam, lParam );
}
And then when you call the function CreateWindow
in OGLTOOLBAR::create
, pass (the last one) reinterpret_cast<void*>(this)
as an argument lpParam
.
And each OGLTOOLBAR object will have its own ToolProc, which is called for each instance via the StaticToolProc function. Or at least I believe it should work.
a source to share
Is ToolProc a static member? You cannot pass function pointers or functors as function pointers. C APIs work only in function pointers.
There is usually a way to bind "client data" to an object so that it is passed to the callback when triggered. You can use this information to transfer instance data so that a static or global function calls a member variable in the correct class.
a source to share