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"

+2


a source to share


2 answers


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.

+2


a source


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.

0


a source







All Articles