Использование обратного вызова класса для пользовательского элемента управления? - PullRequest
3 голосов
/ 17 мая 2010

Я создаю собственный класс управления и, так как я хочу получить полный контроль над ним, я регистрирую класс и хочу использовать класс

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: «приведение типа»: невозможно преобразовать из «перегруженной функции» в «WNDPROC»

Ответы [ 2 ]

3 голосов
/ 17 мая 2010

Если ToolProc не является статическим членом, вы не можете передать указатель на функцию-член в виде обратного вызова, если вы хотите, чтобы ToolProc был нестатической функцией, вы можете создать статическую функцию-член и использовать GetWindowLong / SetWindowLong и область GWL_USERDATA для хранения указателя на текущий объект (this) и статического обратного вызова для вызова функции обратного вызова отдельных объектов, которая может использовать элементы данных отдельных объектов.

Предполагая, что ToolProc не является статическим членом вашего класса OGLTOOLBAR, вы должны привязать указатель этого объекта к дескриптору окна, вы можете сделать это так:

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

И затем, когда вы вызываете функцию CreateWindow в OGLTOOLBAR::create, передайте reinterpret_cast<void*>(this) в качестве аргумента lpParam (последний).

И каждый объект OGLTOOLBAR будет иметь свой собственный ToolProc, вызываемый для каждого экземпляра через функцию StaticToolProc. Или, по крайней мере, я считаю, что это должно сработать.

0 голосов
/ 17 мая 2010

Является ли ToolProc статическим членом? Вы не можете передавать указатели на функции-члены или функторы как указатели на функции. API C работают только в указателях функций.

Обычно существует способ привязать «данные клиента» к объекту, чтобы они передавались обратному вызову при запуске. Вы можете использовать эту информацию для переноса конкретных данных экземпляра, чтобы статическая или глобальная функция могла вызывать переменную-член в правильном классе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...