首页 文章

使用类回调进行自定义控件?

提问于
浏览
3

我正在创建一个自定义控件类,因为我想完全控制它,我注册了类并希望使用该类

LRESULT CALLBACK OGLTOOLBAR :: ToolProc(HWND,UINT,WPARAM,LPARAM)

但它不会让我失望 .

我正在做:

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;

}

这样做的正确方法是什么?

谢谢

编译器说:错误1错误C2440:'type cast':无法从'overloaded-function'转换为'WNDPROC'

2 回答

  • 3

    ToolProc是静态成员吗?您不能将成员函数指针或仿函数作为函数指针传递 . C API仅适用于函数指针 .

    通常有一种方法可以将“客户端数据”绑定到一个对象,以便在触发时将其传递给回调 . 您可以使用该信息来携带特定于实例的数据,以便静态或全局函数可以在正确的类中调用成员变量 .

  • 0

    如果ToolProc不是静态成员,则不能将成员函数指针作为回调传递,假设您希望ToolProc是非静态函数,您可以创建静态成员函数,并使用GetWindowLong / SetWindowLong和GWL_USERDATA区域,存储指向当前对象的指针(this),并具有静态回调调用单个对象的回调函数,即可以利用单个对象的数据成员 .

    假设ToolProc不是OGLTOOLBAR类的静态成员,则必须将对象的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));
    }
    

    然后你有一个静态WndProc(或ToolProc)成员函数,如下所示:

    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 );
    }
    

    然后当你在 OGLTOOLBAR::create 中调用 CreateWindow 函数时,将 reinterpret_cast<void*>(this) 作为 lpParam 参数传递(最后一个) .

    然后,每个OGLTOOLBAR对象将通过StaticToolProc函数为每个实例调用自己的ToolProc . 或者至少我相信这应该有效 .

相关问题