Страница 1 из 1
Определить адресс функции
Добавлено: 14 сен 2009, 23:17
l.rod
Вообщем хочу сделать небольшую обертку для winAPI, и появились проблема. В моем классе есть оконная функция (WndProc), а как определить ее адресс, чтоб указать его в структуре WNDCLASSEX?
и еще один вопрос - скажем есть класс A и создаем 2 новых класса на основе А
class B : public A.......
так вот, в классе А есть функция, которую определить нужно в классах В и С
где то так.
Код: Выделить всё
class A
{
void f(void);
};
class В : public A
{
void f(void)
{
int i = 1+1;
}
};
class С : public A
{
void f(void)
{
int i = 4+5;
}
};
при этом будет ли определена функция в класса-потомках - не извесно
Re: Определить адресс функции
Добавлено: 15 сен 2009, 08:50
WinMain
В моем классе есть оконная функция (WndProc), а как определить ее адресс, чтоб указать его в структуре WNDCLASSEX?
Функция
GetClassInfo используется для получения информации об уже существующем (зарегистрированном) классе.
Если сам создаёшь оконный класс, то полю
lpfnWndProc структуры WNDCLASS просто указываешь имя твоей функции - это и есть её адрес.
Re: Определить адресс функции
Добавлено: 15 сен 2009, 13:46
l.rod
видимо не так обьяснил, вот что мне нужно:
я создал свой класс Window, у которого есть метод
LRESULT CALLBACK Window::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
и свойство WNDCLASS wc;
так вот, как что мне указать в полу этой структуры?
если написать
компилятор говорит, что ошибка и надо написать так
но тогда пишет что несоответствие типов
Re: Определить адресс функции
Добавлено: 15 сен 2009, 15:59
Romeo
Сделай так:
Код: Выделить всё
static LRESULT CALLBACK Window::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
А this прикрепи к окну с помощью SetWindowLong и параметра GWL_USERDATA.
Re: Определить адресс функции
Добавлено: 15 сен 2009, 16:54
l.rod
Romeo писал(а):Сделай так:
Код: Выделить всё
static LRESULT CALLBACK Window::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
А this прикрепи к окну с помощью SetWindowLong и параметра GWL_USERDATA.
а как поможет GWL_USERDATA и this? может тогда уж нужно GWL_WNDPROC ???
Re: Определить адресс функции
Добавлено: 15 сен 2009, 17:31
Romeo
Если ты хочешь, чтобы для данного окна вызвались функции данного объекта класса, то нужно каким-то образом связать this и окно. Так как, функция-обработчик оконных сообщений обязана быть статической (в силу строго задания её прототипа), то единственное, как можно привязать this к окну, это через GWL_USERDATA. Если не ошибаюсь, то именно так выполняет привязку MFC.
Подход состоит в следующем:
Код: Выделить всё
class CMyWindow
{
public:
void CreateWindow( /* some parameters, i.g. window title */)
{
WNDCLASSEX wcl;
wcl.lpfnWndProc = &GlobalWndProc;
...
HWND hWnd = ::CreateWindowEx( /* do not set WS_VISIBLE style */ , wcl, ...);
::SetWindowLong(hWnd, GWL_USERDATA, (long)this);
::ShowWindow(hWnd, SW_SHOW);
}
private:
static LRESULT CALLBACK GlobalWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
long nThis = GetWindowLong(hWnd, GWL_USERDATA);
CMyWindow* pThis = (CMyWindow*)nThis;
if (pThis)
{
return pThis->WndProc(hWnd, message, wParam, lParam);
}
return ::WindowProc(hWnd, message, wParam, lParam);
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
// your impelentation
}
}
При таком подходе есть свои тонкости, например, WM_CREATE твоя процедура не получит. Это можно обойти, если послать в CreateWindow в качестве последнего параметра тоже this и предусмотреть этот вариант развития событий в GlobalWndProc.
Re: Определить адресс функции
Добавлено: 15 сен 2009, 19:46
l.rod
вот теперь понял, только непонятно, кочему моя функция не получит сообщение WM_CREATE, ведь все, что получит глобальная, передастся WndProc?
да, а это почему?
/* do not set WS_VISIBLE style */
и как я понял, глобальная функция даже не должна быть членом класса?
Re: Определить адресс функции
Добавлено: 16 сен 2009, 12:43
Romeo
Дело в том, что нету возможности проставить User Data для окна до его создания. Так, как WM_CREATE генерируется внутри функции CreateWindow сразу после физического создания окна , то это сообщение прилетит в GlobalWndProc ещё до того, как this был проставлен в User Data. Как следствие, твоя WndProc не будет вызвана. Решить эту проблему можно, передав в CreateWindow указатель на this в качестве последнего параметра и корректно обработав эту ситуацию внутри GlobalWndProc.
По поводу WS_VISIBLE. Если ты установишь этот стиль, то помимо сообщения WM_CREATE ты пропустишь ещё массу сообщений: WM_SIZE, WM_SHOWWINDOW, WM_PAINT и т.д., которые будут сгенерированы операционной системой в момент показа окна.
Re: Определить адресс функции
Добавлено: 25 сен 2009, 20:11
l.rod
снято с обсуждения
