Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > Помогите разобраться с макросом HANDLE_MSG


Автор: Волод 8.8.2005, 09:05
Помогите разобраться с макросом HANDLE_MSG.
В одной из книг библиотеки системного программиста предлагается использовать этот макрос следующим образом:
Код

LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{    
    switch(iMsg)
    {
        HANDLE_MSG(hwnd, WM_SIZE, Cls_OnSize);    
        HANDLE_MSG(hwnd, WM_PAINT, Cls_OnPaint);    
        HANDLE_MSG(hwnd, WM_DESTROY, Cls_OnDestroy);    
        default:  
            return DefWindowProc(hwnd, iMsg, wParam, lParam);
    }



При этом функция, переданные через HANDLE_MSG, должна быть такой же, как (цитата)…и обычная функция, за одним исключением - она должна оканчиваться вызовом макрокоманды FORWARD_<имя сообщения> в операторе return (даже если функция имеет тип void)

То есть, например, Cls_OnDestroy описывается так:
Код
 
void Cls_OnDestroy(HWND hwnd)
{
PostQuitMessage(0);
return FORWARD_WM_DESTROY(hwnd, DefWindowProc); 
}


Весь этот код замечательно работает на Си, где не важно, что возвращает функция, но при попытке перенести этот код в C++ компилятор сразу выдает ошибку, что void-функция Cls_OnDestroy не может возвращать значение. Хорошо, DefWindowProc у нас возвращает результат типа LRESULT, и я пытаюсь переопределить проблемную функцию так:
(LRESULT) Cls_OnDestroy(HWND hwnd);
Но выскакивает новая ошибка – оказывается, макросы типа FORWARD_* разворачиваются в код, который в конечном итоге преобразуется к типу void. То есть в сокращенном варианте на языке С вся функция выглядит как:
void Cls_OnDestroy(HWND hwnd){return void} – и на С это компилируется, а на C++ - такой код, получается, вообще нельзя преобразовать? Приведешь к LRESULT – будет ругаться, что возвращаем void, приведешь к void - ругается, что вообще что-то возвращаем…..
Это, собственно, и есть первый вопрос – как коррекно перевести Cи-шный код в код C++ ? - и второй, тоже по теме:
Я тут посмотрел, что большинство подобных функций возвращают вызов ф. DefWindowProc, тогда почему не рекомендуется (по крайней мере, нигде не встретил) описать CALLBLACK - функцию окна так?:
Код

LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{    
    switch(iMsg)
    {
        HANDLE_MSG(hwnd, WM_SIZE, Cls_OnSize);    
        HANDLE_MSG(hwnd, WM_PAINT, Cls_OnPaint);    
        HANDLE_MSG(hwnd, WM_DESTROY, Cls_OnDestroy);    
    }
    return DefWindowProc(hwnd, iMsg, wParam, lParam);



Автор: Волод 8.8.2005, 09:28
Пока для себя я пришел к выводу, что раз ф. возвращает пустое значение, правильнее всего будет преобразовать все указанные в макросе HANDLE_MSG функции к типу BOOL и вместо void возвращать NULL, FORWARD_* не вызывать совсем, а DefWindowProc, как показано в последнем листинге, вынести за оператор switch... – только вот насколько это правильно?

Автор: Fixin 8.8.2005, 17:35
Если возврат - воид, то просто вызови ворвард без ретурна. Вообще, необходимости в его вызове - не вижу.

Автор: Glad 16.8.2005, 21:12
Кстати у меня тоже проблема с этим макросом. На С++ он у меня работает. Но я никак не могу понять принцип его работы. Если обрабатываю сообщение WM_CREATE скажем то нужно одно у функции (типа ON_CREATE) 2 параметра. Если обрабатываю другое сообщение у функции неизвестно уже сколько параметров. В МСДНе не нашел smile

Автор: Fixin 17.8.2005, 20:27
Смотри <WIndowsX.h>. Если нужна функция, скажем, OnPaint, то ищи в этом файле Cls_OnPaint и смотри параметры.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)