Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Message Map, обработка виндовских сообщений 
:(
    Опции темы
RAN
Дата 9.10.2003, 08:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Экс. модератор
Сообщений: 709
Регистрация: 14.3.2003
Где: Щёлково Моск.обл.

Репутация: 5
Всего: 6



Хочу ещё поблагодарить за интересную тему. Она мне подсказала интересное решение в моём приложении (по крайней мере, мне нравиться). Суть в следующем:

Есть оконный класс (свой собственный, естественно). Сделан он так, как я описывал выше. Т.е. в классе есть статическая функция, выполняющая роль оконной процедуры. Эта функция получает указатель на объект класса по дескриптору окна (GetWindowLong). Потом вызывается соответствующая сообщению функция.
Так вот в окне можно кое-что "перетаскивать" мышкой. Возникла идея написать две разные функции для обработки события WM_MOUSEMOVE. Скажем, OnMouseMove1() и OnMouseMove2(). Ввожу переменную для хранения указателя на текущюю функцию обработки. Меняю значение этой переменной в зависимости от обстоятельств.

Код

class CWnd {
private:
.......................................................
static LRESULT CALLBACK Proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
.......................................................
void (CWnd::*OnMouseMove)(int ,int );
void OnMouseMove1(int xPos, int yPos);
void OnMouseMove2(int xPos, int yPos);
.......................................................
};

LRESULT CALLBACK CWnd::Proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch( uMsg )
{
.............................................................................................
case WM_MOUSEMOVE:
 {
  CWnd* p = (CWnd*)GetWindowLong(hwnd, 0);
  void (CWnd::*MouseProc)(int ,int );
  MouseProc = p->OnMouseMove;
  (p->*MouseProc)(LOWORD(lParam), HIWORD(lParam));
 }
 break;
.................................................................................................
}
return( DefWindowProc( hwnd, uMsg, wParam, lParam ) );
}


Всё работает. Но если не вводить дополнительную переменную MouseProc, то компилятор VC ругается

(p->*OnMouseMove)(LOWORD(lParam), HIWORD(lParam));
error C2597: illegal reference to data member 'CWnd::OnMouseMove' in a static member function
error C2568: '->*' : unable to resolve function overload

В другом месте в не статической функции другая проблема:
(*OnMouseMove)(xPos, yPos);
error C2171: '*' : illegal on operands of type 'void (__thiscall CWnd::*)(int,int)'
error C2064: term does not evaluate to a function

Написал (this->*OnMouseMove)(xPos, yPos); и всё OK.



Может кто объяснит логику происходящего


PM MAIL ICQ   Вверх
Jcs
Дата 9.10.2003, 15:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 156
Регистрация: 1.10.2003

Репутация: нет
Всего: нет



В первом случае ты пытаешься из статической фунуции обратиться к нестатическому члену класса, а во втором случае я не уверен, но, как мне кажется, функция должна знать адрес конкретного экземпляра класса, для корректного вызова.
PM   Вверх
RAN
Дата 9.10.2003, 15:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Экс. модератор
Сообщений: 709
Регистрация: 14.3.2003
Где: Щёлково Моск.обл.

Репутация: 5
Всего: 6



Цитата
ты пытаешься из статической фунуции обратиться к нестатическому члену класса

Ну да. И в чём проблема. Я постоянно обращаюсь и нет проблем. А вызвать функцию по указателю - нелегальная ссылка, видите ли.
PM MAIL ICQ   Вверх
RAN
Дата 9.10.2003, 16:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Экс. модератор
Сообщений: 709
Регистрация: 14.3.2003
Где: Щёлково Моск.обл.

Репутация: 5
Всего: 6



Но я и сам понял.
Цитата

функция должна знать адрес конкретного экземпляра класса, для корректного вызова

Так и есть

Начну со второго примера.
Пишу (*OnMouseMove)(xPos, yPos);. VC думает, что я пытаюсь разыменовать переменную типа 'void (__thiscall CWnd::*)(int,int)'. "Нет, - говорит, - нельзя. Без this не можно так делать."
Исправляю на (this->*OnMouseMove). "Ага, - говорит VC, - это другое дело. Вызвать можно. this - указатель на CWnd, две переменные типа int в качестве параметров. Всё OK."

А в первом случае из-за этого же другая проблема.
Надо было писать так:
(p->*(p->OnMouseMove))(LOWORD(lParam), HIWORD(lParam));
Так и написал. Всё понял.

P.S. Это однозначно надо в FAQ.
ВЕЛИК И МОГУЧ ЯЗЫК C++


PM MAIL ICQ   Вверх
Страницы: (3) Все 1 2 [3] 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0455 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.