почему OnMsg(UINT, WPARAM, LPARAM, BOOL&)
От: Аноним  
Дата: 26.02.09 21:15
Оценка:
для какой цели в сигнатуре функций, подставляемых в макрос MESSAGE_HANDLER, присутствует параметр UINT uMsg? зачем он нужен? ведь создавая обработчик мы явно указываем идентификатор сообщения. единственное применение этой сигнатуры я вижу таким:
BEGIN_MSG_MAP(widget)
    MESSAGE_HANDLER(WM_ERASEBKGND, OnPaint)
    MESSAGE_HANDLER(WM_PAINT, OnPaint)
END_MSG_MAP()
LRESULT                OnPaint(UINT uMsg, WPARAM, LPARAM, BOOL&)
{
    if(uMsg == WM_ERASEBKGND)
    {
        // TO DO
    }
    else if(uMsg == WM_PAINT)
    {
        // TO DO
    }
    return TRUE;
}
но логично ли оно, такое применение? в нем мы делаем двойную проверку if(uMsg == WM_XXX), сначала внутри макроса, а затем внутри обработчика.
Re: почему OnMsg(UINT, WPARAM, LPARAM, BOOL&)
От: byleas  
Дата: 27.02.09 09:11
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>единственное применение этой сигнатуры я вижу таким:

Так и есть.

А>но логично ли оно, такое применение?

Именно такое не логично. Когда для нескольких сообщений один обработчик, то подразумевается некая общая работа. А номер сообщения проверяется для специфичных участков.
По-другому можно было бы записать так (приближённо):
BEGIN_MSG_MAP(widget)
    MESSAGE_HANDLER(WM_ERASEBKGND, OnErase)
    MESSAGE_HANDLER(WM_PAINT, OnPaint)
END_MSG_MAP()

void OnCommonPaint(CDCHandle);

LRESULT OnPaint(UINT uMsg, WPARAM, LPARAM, BOOL&)
{
  CPaintDC dc(m_hWnd);
  OnCommonPaint(dc);
  // specific functions
  ...
  return 0;
}
LRESULT OnErase(UINT uMsg, WPARAM wParam, LPARAM, BOOL&)
{
  // erase specific code
  ...
  // common paint
  OnCommonPaint((HDC)wParam);
  return !0;
}
Re[2]: почему OnMsg(UINT, WPARAM, LPARAM, BOOL&)
От: Аноним  
Дата: 27.02.09 12:58
Оценка:
Здравствуйте, byleas, Вы писали:
B>По-другому можно было бы записать так (приближённо):
B>
B>BEGIN_MSG_MAP(widget)
B>    MESSAGE_HANDLER(WM_ERASEBKGND, OnErase)
B>    MESSAGE_HANDLER(WM_PAINT, OnPaint)
B>END_MSG_MAP()

B>void OnCommonPaint(CDCHandle);

B>LRESULT OnPaint(UINT uMsg, WPARAM, LPARAM, BOOL&)
B>{
B>  CPaintDC dc(m_hWnd);
B>  OnCommonPaint(dc);
B>  // specific functions
B>  ...
B>  return 0;
B>}
B>LRESULT OnErase(UINT uMsg, WPARAM wParam, LPARAM, BOOL&)
B>{
B>  // erase specific code
B>  ...
B>  // common paint
B>  OnCommonPaint((HDC)wParam);
B>  return !0;
B>}
B>

я не совсем понял суть приведенного кода. может быть, речь шла о таком применении?
void OnCommonPaint(UINT uMsg, CDCHandle)
{
    if(uMsg == WM_ERASEBKGND)
    {
        // TO DO ERASEBKGND
        return TRUE;
    }
    // TO DO PAINT
    return FALSE;
}

LRESULT            OnPaint(UINT uMsg, WPARAM, LPARAM, BOOL&)
{
    CPaintDC dc(m_hWnd);
    OnCommonPaint(uMsg, dc);
    // specific functions
    ...
    return 0;
}
LRESULT            OnErase(UINT uMsg, WPARAM wParam, LPARAM, BOOL&)
{
    // erase specific code
    ...
    // common paint
    OnCommonPaint(uMsg, (HDC)wParam);
    return !0;
}
но, даже, если так, то зачем делать обобщенный обработчик (OnMsg(UINT, WPARAM, LPARAM, BOOL&)) в библиотеке с открытым кодом? почему не отдать решение неких общих, а на самом деле достаточно редких (частных), задач на откуп конечному разработчику?
например, полагая что макрос MESSAGE_HANDLER реализован так:
#define MESSAGE_HANDLER(msg, func) \
    if(uMsg == msg) \
    { \
        bHandled = TRUE; \
        lResult = func(wParam, lParam, bHandled); \
        if(bHandled) \
            return TRUE; \
    }
, конечный разработчик в любой момент времени сможет реализовать свой собственный макрос:
#define USER_MESSAGE_HANDLER(msg, func) \
    if(uMsg == msg) \
    { \
        bHandled = TRUE; \
        lResult = func(uMsg, wParam, lParam, bHandled); \
        if(bHandled) \
            return TRUE; \
    }
, ну, или сделать так:
BEGIN_MSG_MAP(widget)
    if(uMsg == WM_ERASEBKGND)
        OnErase(uMsg, wParam, lParam, bHandled);
    else if(uMsg == WM_PAINT)
        OnPaint(uMsg, wParam, lParam, bHandled);
END_MSG_MAP()
Re[3]: почему OnMsg(UINT, WPARAM, LPARAM, BOOL&)
От: Аноним  
Дата: 27.02.09 13:09
Оценка:
пардон, вношу поправку в последний блок кода
BEGIN_MSG_MAP(widget)
    if(uMsg == WM_ERASEBKGND)
        return OnErase(uMsg, wParam, lParam, bHandled);
    if(uMsg == WM_PAINT)
        return OnPaint(uMsg, wParam, lParam, bHandled);
END_MSG_MAP()
Re[3]: почему OnMsg(UINT, WPARAM, LPARAM, BOOL&)
От: byleas  
Дата: 28.02.09 08:26
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>я не совсем понял суть приведенного кода. может быть, речь шла о таком применении?

Нет. Суть в том, что OnCommonPaint выполняет общую для paint & erase работу вне зависимости сообщения. Конечно, выбор paint & erase неудачен, но можно взять любые другие сообщения: WM_CLOSE & WM_QUERYENDSESSION, WM_DESTROY & WM_ENDSESSION, etc.


А>почему не отдать решение неких общих, а на самом деле достаточно редких (частных), задач на откуп конечному разработчику?

С этим согласен, по умолчанию этот параметр (сообщение) не нужен. С другой стороны, WTL — это достаточно тонкая прослойка. Хотите хардкора — есть atlcrack.h

А>конечный разработчик в любой момент времени сможет реализовать свой собственный макрос:

Да достаточно просто двух версий макроса положить в библиотеку, имхо. MESSAGE_HANDLER & CUSTOM_MESSAGE_HANDLER, например. Впрочем, см. выше про atlcrack.
Re: почему OnMsg(UINT, WPARAM, LPARAM, BOOL&)
От: Alexander G Украина  
Дата: 28.02.09 14:50
Оценка: 1 (1)
Здравствуйте, Аноним, Вы писали:

А>для какой цели в сигнатуре функций, подставляемых в макрос MESSAGE_HANDLER, присутствует параметр UINT uMsg? зачем он нужен? ведь создавая обработчик мы явно указываем идентификатор сообщения. единственное применение этой сигнатуры я вижу таким:

...
Например
здесь
Автор: Alexander G
Дата: 02.02.09

3. Все от WM_MOUSEFIRST до WM_MOUSELAST передаются в TTM_RELAYEVENT.

Нужен MESSAGE_RANGE_HANDLER, в обработчике нужны все параметры.
Русский военный корабль идёт ко дну!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.