Модераторы: feodorv, GremlinProg, xvr, Fixin

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> помогите разобраться с макросом HANDLE_MSG 
V
    Опции темы
yngwie19
Дата 24.12.2008, 00:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 829
Регистрация: 15.6.2008
Где: Новгород

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



Всем привет. В книге Финогенова "WIN32 Основы программирования" дошел до раздела Макрос HANDLE_MSG после прочтения которого есть несколько вопросов:

1) Правильно Я понимаю, что использование данного макроса применяется лишь для того чтобы уменьшить структуру swtch-case в оконной процедуре? В принципе можно обходиться без него?
2) В книге дается пример макроса входящего в состав WINDOWSX.H:
Код

#define HANDLE_MSG(hwnd,message,fn)\
   case(messae): return HANDLE_##message((hwnd),(wParam),(lParam),(fn))

2а) Это Я так понимаю общий вид макроса, который используется для всех сообщений. Так?
Для сообщения WM_DESTROY он преобразуется в
Код

case(WM_DESTROY): return HANDLE_WM_DESTROY((hwnd),(wParam),(lParam),(OnDestroy)) /*OnDestroy - оконная функция определенная для передачи сообщения PostQuitMessage(0) */

2б) Почему кстати hwnd,lParam,wParam и функция в отельных скобках?
Далее пишут: Для макроса HANDLE_WM_DESTROY дано следующее макроопределение:
Код

#define HANDLE_WM_DESTROY(hwnd,wParam,lParam,fn) ((fn)(hwnd),0L)
 
Подставив это определение вместо WM_DESTROY и опустив ненужные скобки получим окончательное макрорасширение
case WM_DESTROY:return (OnDetroy(hwnd,0L));

Объясните поалуйста вместо чего мы подставяем расширенный макрос WM_DESTROY и что это вообще за странный параметр "0L"?

Это сообщение отредактировал(а) yngwie19 - 24.12.2008, 00:30
PM MAIL   Вверх
jonie
Дата 24.12.2008, 01:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

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



Цитата

1) Правильно Я понимаю, что использование данного макроса применяется лишь для того чтобы уменьшить структуру swtch-case в оконной процедуре? В принципе можно обходиться без него?
да.

Цитата

2а) Это Я так понимаю общий вид макроса, который используется для всех сообщений. Так?
угу. в общем-то используется для улучшения читабельности кода... и заставляет "стандартизировать" его...

Цитата

2б) Почему кстати hwnd,lParam,wParam и функция в отельных скобках?
потому что define - зло. прикинь что будет например в макросе:
Код

//нехороший пример
#define max(x,y) x>y?x:y
int x=3;y=2;
int m = max(x+=5, y); //что вернется)?


чет я последнее не очень понял, чет там из контекста как-то урвано..


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
yngwie19
Дата 24.12.2008, 08:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 829
Регистрация: 15.6.2008
Где: Новгород

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



jonie, Спасибо за ответы.
 

Цитата(jonie @  24.12.2008,  01:04 Найти цитируемый пост)
чет я последнее не очень понял, чет там из контекста как-то урвано.. 

В книге дается расширенный вид макроса, полученный н основе  общего вида макроса:
Код

 case(WM_DESTROY): return HANDLE_WM_DESTROY((hwnd),(wParam),(lParam),(OnDestroy)) 

А также дается макроопределение для WM_DESTROY
Код

#define HANDLE_WM_DESTROY(hwnd,wParam,lParam,fn) ((fn)(hwnd),0L)

И говорят:
Цитата(yngwie19 @  24.12.2008,  00:17 Найти цитируемый пост)
Подставив это определение вместо WM_DESTROY и опустив ненужные скобки получим окончательное макрорасширение
case WM_DESTROY:return (OnDetroy(hwnd,0L));


Это чтож получается, чтобы для каждого сообщения правильно написать Марос, нужно смотреть определения в windowsx.h и все время подставлять те определения сообщений, которые нужно?
Что это за параметр 0L? 
Да и еще вопрос, зачем тут нужен return? без него макрос описывается не правиьно?

Это сообщение отредактировал(а) yngwie19 - 24.12.2008, 08:34
PM MAIL   Вверх
jonie
Дата 24.12.2008, 13:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

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



Цитата

Да и еще вопрос, зачем тут нужен return? без него макрос описывается не правиьно?
иначе выполнится следующий case


насколько я понимаю из обрывочных сведений идея авторов следующая:
"абстракция 0-ого уровня" : используем switch(umsg) { case WM_CRATE: .... break; .... }
"1-ый уровень" : 
Код

#define HANDLE_MSG(hwnd,message,fn)\
   case(messae): return HANDLE_##message((hwnd),(wParam),(lParam),(fn))
получаем :
Код

BEGIN_MSG_MAP
  HANDLE_MSG(hwnd, WM_CREATE, OnWMCreate);
  HANDLE_MSG(hwnd, WM_OTHER, OnWMOther);
END_MSG_MAP

"2-ой уровень":
Код

BEGIN_MSG_MAP
 HANDLE_WM_DESTROY(блаблабла)
END_MSG_MAP

DWORD OnDetroy(HWND hwnd, DWORD stuff)
{
 ....
}


чета типа того..


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
yngwie19
Дата 24.12.2008, 14:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 829
Регистрация: 15.6.2008
Где: Новгород

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



jonie, 
Цитата(jonie @  24.12.2008,  13:58 Найти цитируемый пост)
иначе выполнится следующий case

а почему тогда если макросы не использовать то мы вместо return пишем break

Код

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
switch(msg)
{
  case WM_DESTROY:
       PostQuitMessage(0);
       break;                           //Когда используется break, то в вызывающую функцию ничего не возвращается
  default:
       return DefWindowProc(hwnd,msg,wParam,lParam);
}
 
а при использовании макроса мы получаем
Код

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
   case WM_DESTROY:
      return OnDestroy(hwnd);  // Здесь оконная процедура возвращает результат работы функции OnDestroy, а он равен void
   default: 
      return DefWindowProc(hwnd,msg,wParam,lParam);
}

и еще вопрос:

Цитата(yngwie19 @  24.12.2008,  08:32 Найти цитируемый пост)
Цитата(yngwie19 @  24.12.2008,  00:17 )
Подставив это определение вместо WM_DESTROY и опустив ненужные скобки получим окончательное макрорасширение
case WM_DESTROY:return (OnDetroy(hwnd,0L));

что это за параметр 0L для чего он тут используется,нам он вообще нужен?
PM MAIL   Вверх
mes
Дата 24.12.2008, 15:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(yngwie19 @  24.12.2008,  14:48 Найти цитируемый пост)

а почему тогда если макросы не использовать то мы вместо return пишем break

не так.. если используем ретурн то брейк ставить не надо.
а ретурн ставим для возвращения результа функции ассоцированной с сообщением

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

Добавлено через 35 секунд
Цитата(yngwie19 @  24.12.2008,  14:48 Найти цитируемый пост)

что это за параметр 0L

L означает что тип long.


--------------------
PM MAIL WWW   Вверх
GremlinProg
Дата 24.12.2008, 15:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

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



yngwie19, я так понимаю, ты спрашиваешь параметр функции, определенной в WTL или MFC, а здесь API
переместить тему?
или я не прав?

вобщем, тема мигрировала в Visual C++/MFC/WTL

Это сообщение отредактировал(а) GremlinProg - 24.12.2008, 15:42


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
yngwie19
Дата 25.12.2008, 00:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 829
Регистрация: 15.6.2008
Где: Новгород

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



GremlinProg, Это макрос чистого WINAPI, зачем перенесли?

Цитата(mes @  24.12.2008,  15:12 Найти цитируемый пост)
L означает что тип long. 

для какой переменной?
PM MAIL   Вверх
mes
Дата 25.12.2008, 13:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(yngwie19 @  25.12.2008,  00:11 Найти цитируемый пост)
для какой переменной? 

для числовых констант
Код

5 - значение типа int
5.0 - значение типа double
5L - значение типа long


Добавлено через 1 минуту и 15 секунд
Цитата(yngwie19 @  25.12.2008,  00:11 Найти цитируемый пост)
Это макрос чистого WINAPI,

A в какой библиотеке определен данный макрос?  smile 


--------------------
PM MAIL WWW   Вверх
yngwie19
Дата 25.12.2008, 20:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 829
Регистрация: 15.6.2008
Где: Новгород

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



Цитата(mes @  25.12.2008,  13:56 Найти цитируемый пост)
A в какой библиотеке определен данный макрос? 

windowsx.h
PM MAIL   Вверх
Earnest
Дата 25.12.2008, 21:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

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



Возврашаю тему в WinAPI - это таки оно.


--------------------
...
PM   Вверх
GremlinProg
Дата 25.12.2008, 21:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

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



HANDLE_MSG, теперь оно )

yngwie19, нули здесь нужны для того, чтобы обработчики сообщений, пересылающие менее трех параметров, можно было задать в одной форме:
Код

LRESULT (*HANDLER)(HWND,WPARAM,LPARAM);

т.е. как раз для того, чтобы не смотреть определения в windowsx.h и не искать, какой тип функции передать макросу в параметре fn, т.е. для HANDLE_MSG, все обработчики имеют 3 параметра

Это сообщение отредактировал(а) GremlinProg - 26.12.2008, 00:51


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
yngwie19
Дата 26.12.2008, 00:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 829
Регистрация: 15.6.2008
Где: Новгород

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



Ребят а вообще в практике, часто используют макросы?
PM MAIL   Вверх
yngwie19
Дата 26.12.2008, 00:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 829
Регистрация: 15.6.2008
Где: Новгород

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



И еще вопросик при использовании макроса для функции WM_PAINT.
Скажите пожалуйста когда мы описываем функцию OnDestroy для макроса HANDLE_MSG(hwnd,WM_DESTROY,OnDestroy), то мы знаем, что она будет вызована в случае если мы например закроем окно. А что касается использования функции WM_PAINT, то Я так понял, что ее винда вызывает сама. Дело в том что в книге дано описание макроса HANDLE_MSG(hwnd,WM_PAINT,OnPaint), но нигде явно не указывается, что мы ее каким-либо образом вызываем. Т.е получается мы ее просто описали, а вызываем не мы. Поясите пожалуйста когда и кто посылает данное собщение в обработчик сообщений, а главное в какой момент.

Это сообщение отредактировал(а) yngwie19 - 26.12.2008, 00:39
PM MAIL   Вверх
mes
Дата 26.12.2008, 03:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(yngwie19 @  26.12.2008,  00:38 Найти цитируемый пост)
Поясите пожалуйста когда и кто посылает данное собщение в обработчик сообщений, а главное в какой момент.

WM_PAINT посылается виндой окну, когда она считает, что оно(или его часть) должно перерисоваться.  
Т.е когда (становиться) видна часть окна помеченная как невалидная. (т.е та часть окна которая по каким то причинам предполагается, что была затерта и сейчас нужно показать ее юзеру)
Программа сама может инициировать перерисовку (точнее сказать посылку окну сообщения WM_PAINT) путем "инвалидования" определенной области.

подробнее тут:
http://msdn.microsoft.com/en-us/library/ms534870.aspx







--------------------
PM MAIL WWW   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

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


 




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


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

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