Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 对自定义控件使用类回调?_C++_C_Winapi - Fatal编程技术网

C++ 对自定义控件使用类回调?

C++ 对自定义控件使用类回调?,c++,c,winapi,C++,C,Winapi,我正在创建一个自定义控件类,因为我想完全控制它,所以我注册了该类并想使用该类的 LRESULT回调OGLTOOLBAR::ToolProc(HWND、UINT、WPARAM、LPARAM) 但它不让我 我正在做: HWND OGLTOOLBAR::create(HWND parent,HINSTANCE hInst, int *toolWidthPtr) { if (toolhWnd != NULL) { return toolhWnd; } to

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

LRESULT回调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:“类型转换”:无法从“重载函数”转换为“WNDPROC”

ToolProc是静态成员吗?不能将成员函数指针或函子作为函数指针传递。C API只在函数指针中工作


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

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

假设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));
}
然后,当调用
OGLTOOLBAR::create
中的
CreateWindow
函数时,将
重新解释(this)
作为
lpParam
参数(最后一个参数)


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

实际上,您可以使用GetWindowLongPtr/SetWindowLongPtr来保存指向实例对象的指针。无需将其存储在某种外部映射中。索引设置为DWLP_USER。你不知道这篇文章对我有多有用。
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 );
}