Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Привязка CALLBACK функции к оконному классу.

1.8K
23 октября 2003 года
SeregaLBN
62 / / 03.10.2003
Есть класс наследуемый от CWnd:

class CMyWnd : public CWnd
{
...
}

Для некоторых экземпляров класса мне нужно привязать CALLBACK функцию, например hook функцию обработки мыши:

LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam) {
if (nCode < 0)
return CallNextHookEx(CTerminalView::hHookMouse, nCode, wParam, lParam);

// моя обработка...

return CallNextHookEx(CTerminalView::hHookMouse, nCode, wParam, lParam);
}

Сначала я разместил эту ф-цию внутри класса CMyWnd. Но при установке хука
void CMyWnd::DoDataExchange(CDataExchange* pDX)
{
//...
hHookMouse = SetWindowsHookEx(WH_MOUSE, this->MouseProc, NULL, ::GetCurrentThreadId());
}
возникает error C2664: 'SetWindowsHookEx': cannot convert parameter 2 from 'long (int,unsigned int,long)' to 'long (__stdcall *)(int,unsigned int,long)'
Т.е., насколько я понимаю, макрос CALLBACK (когда ф-ция определена внутри класса) игнорируется.
Поэтому мне пришлось вынести CALLBACK функцию из описания класса.
И здесь возникает другая проблема - экземпляров класса много, а CALLBACK функция одна. Т.е. я не могу определить из CALLBACK функции к какому экземпляру класса она привязана.

Вопрос:
1. Можно ли как то определить CALLBACK ф-цию внутри класса, и вызывать её без ошибки?
2. Ели первое нельзя, то как можно определить из CALLBACK функции c каким экземпляром класса она связана?
3
23 октября 2003 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by SeregaLBN
Есть класс наследуемый от CWnd:

class CMyWnd : public CWnd
{
...
}

Для некоторых экземпляров класса мне нужно привязать CALLBACK функцию, например hook функцию обработки мыши:

LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam) {
if (nCode < 0)
return CallNextHookEx(CTerminalView::hHookMouse, nCode, wParam, lParam);

// моя обработка...

return CallNextHookEx(CTerminalView::hHookMouse, nCode, wParam, lParam);
}

Сначала я разместил эту ф-цию внутри класса CMyWnd. Но при установке хука
void CMyWnd::DoDataExchange(CDataExchange* pDX)
{
//...
hHookMouse = SetWindowsHookEx(WH_MOUSE, this->MouseProc, NULL, ::GetCurrentThreadId());
}
возникает error C2664: 'SetWindowsHookEx': cannot convert parameter 2 from 'long (int,unsigned int,long)' to 'long (__stdcall *)(int,unsigned int,long)'
Т.е., насколько я понимаю, макрос CALLBACK (когда ф-ция определена внутри класса) игнорируется.
Поэтому мне пришлось вынести CALLBACK функцию из описания класса.
И здесь возникает другая проблема - экземпляров класса много, а CALLBACK функция одна. Т.е. я не могу определить из CALLBACK функции к какому экземпляру класса она привязана.

Вопрос:
1. Можно ли как то определить CALLBACK ф-цию внутри класса, и вызывать её без ошибки?
2. Ели первое нельзя, то как можно определить из CALLBACK функции c каким экземпляром класса она связана?



1. Только, как static.
2. ОС ничего о твоих классах и экземплярах не знает, ОС оперирует (в данном случае) HWND. Его можно получить из lParam:

((MOUSEHOOKSTRUCT*)lParam)->hwnd

Далее, используя HWND можно связаться с твоим экземпляром несколькими способами, один из них - положить указатель на экземпляр в GWL_USERDATA (См. SetWindowLong) при инициализации окна (WM_CREATE или SubclassWindow).

1.8K
24 октября 2003 года
SeregaLBN
62 / / 03.10.2003
Цитата:
Originally posted by Green


1. Только, как static.
2. ОС ничего о твоих классах и экземплярах не знает, ОС оперирует (в данном случае) HWND. Его можно получить из lParam:

((MOUSEHOOKSTRUCT*)lParam)->hwnd

Далее, используя HWND можно связаться с твоим экземпляром несколькими способами, один из них - положить указатель на экземпляр в GWL_USERDATA (См. SetWindowLong) при инициализации окна (WM_CREATE или SubclassWindow).



Спасибо за ответ. Сохранение указателя на экземпляр в GWL_USERDATA я уже выполнял. И с этим пробле нет. Но как быть, если CALLBACK функция является, например, не hook функцией обработки мыши (где можно выбрать HWND), а hook функцией обработки клавиатуры (где нельзя выбрать HWND)?
LRESULT CALLBACK KeyboardProc(
int code, // hook code
WPARAM wParam, // virtual-key code
LPARAM lParam // keystroke-message information
);

3
24 октября 2003 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by SeregaLBN

Спасибо за ответ. Сохранение указателя на экземпляр в GWL_USERDATA я уже выполнял. И с этим пробле нет. Но как быть, если CALLBACK функция является, например, не hook функцией обработки мыши (где можно выбрать HWND), а hook функцией обработки клавиатуры (где нельзя выбрать HWND)?
LRESULT CALLBACK KeyboardProc(
int code, // hook code
WPARAM wParam, // virtual-key code
LPARAM lParam // keystroke-message information
);



В разных случиях по-разному. В данном случае, наверное, надо определить в каком окне находиться фокус GetFocus().

1.8K
24 октября 2003 года
SeregaLBN
62 / / 03.10.2003
Цитата:
Originally posted by Green


В разных случиях по-разному. В данном случае, наверное, надо определить в каком окне находиться фокус GetFocus().



Да, согласен, - это уникальное решение для ф-ции LRESULT CALLBACK KeyboardProc(...)
Скорее всего оно мне сейчас и поможет. Спасибо.
Но хотелось бы, на будущее, получить универсальное решение для всех CALLBACK ф-ций.

Кстати, для ф-ции обработки хука мыши, приходящий хендл окна не всегда яляется хендлом окна моего экземпляра класса. Так что нужно ещё анализировать результат вызова GetWindowLong(hwnd, GWL_USERDATA) :(.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог