2012-03-14 1 views
0

У меня есть проблема с подключением оконной процедуры к окну.есть WNDPROC функция от ребенка класс

У меня есть базовый знак BaseWindow, который использует GWPL_USERDATA для вызова виртуальной функции, которая называется дочерними классами HandleMessage().

Однако, если я пытаюсь изменить процедуру окна, не создавая собственный класс окон, он дает ошибку типа от дочерней процедуры до длинной.

Вот код:

static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 
{ 
    BaseWindow *pThis = NULL; 

    if (uMsg == WM_NCCREATE) 
    { 
     CREATESTRUCT* pCreate = (CREATESTRUCT*)lParam; 
     pThis = (BaseWindow*)pCreate->lpCreateParams; 
     SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)pThis); 

     pThis->m_hwnd = hwnd; 
    } 
    else 
    { 
     pThis = (BaseWindow*)GetWindowLongPtr(hwnd, GWLP_USERDATA); 
    } 
    if (pThis) 
    { 
     return pThis->HandleMessage(uMsg, wParam, lParam); 
    } 
    else 
    { 
     return DefWindowProc(hwnd, uMsg, wParam, lParam); 
    } 
} 

virtual LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) 
    {return 0;}; 


PlayList Class : BaseWindow 

SetWindowLong(m_hwnd, GWL_WNDPROC,(long) HandleMessage); //Error 

LRESULT PlayList::HandleMessage(UINT message,WPARAM wParam,LPARAM lParam) //Need to  attach this window procedure 
{} 

Это работает, если процедура ребенка является статическим, однако я использовать не статические члены в этой процедуре.

Я хочу подклассифицировать общий элемент управления, используя этот базовый класс (потому что много кода избыточно), возможно ли это?

Вот весь код для базового класса: http://pastebin.com/ME8ks7XK

ответ

0

Компилятор не любит ваше объявление для HandleMessage, оно не является статическим. Его тоже не хватает CALLBACK, а не хорошо.

Не знаете, почему вы пытаетесь это сделать, вся ваша функция WindowProc() должна передать сообщение в виртуальный метод HandleMessage(). В лучшем случае вы будете использовать WindowProc в своем вызове SetWindowLong() вместо HandleMesssage. Или просто укажите его непосредственно в вызове CreateWindowEx().

+0

CALLBACK не помогает .. и handlemessage() отлично работает, если я создаю класс окна и регистрирую его (но это конкретное окно подклассифицирует системный класс [listbox]), почему я не хочу его использовать в CreateWindowEx() is beacause я хочу, чтобы он был дочерним по отношению к базовому классу, поэтому мне не нужно повторять весь код (например, pos, размер, ручка текучей среды и т. д., которая присутствует в базовом классе) –

+0

Это невозможно, Windows api - C, он не знает, как вызывать виртуальные методы C++. Вы знаете, что вы изобретаете огромное колесо? Библиотеки классов C++, которые обертывают api, многочисленны. –

+0

или я должен был бы сделать исключение для этого одного окна (или любого другого, который подклассифицирует системный класс), может ли быть любое другое решение? –

0

Из MSDN:

Приложение подклассы экземпляр окна, используя функцию SetWindowLong. Приложение передает флаг GWL_WNDPROC, дескриптор окна в подкласс и адрес процедуры подкласса SetWindowLong. Процедура подкласса может находиться в исполняемом файле приложения или в DLL.

Таким образом, вы должны написать следующее:
SetWindowLong(m_hwnd, GWL_WNDPROC,(long) & HandleMessage);

Но это не компилируется снова! причина: все нестатические функции-члены спрятали параметр this (указатель на класс владельца). Итак, вы HandleMessage не соответствуют объявлению WindowProc.

Смежные вопросы