Download demo project - 10 Kb
Download source - 1 Kb
Introduction
Recently I needed to create a WTL control that would handle all
its functionality inside of the control itself, like can be done in any
standard MFC control.
In MFC to do this the Control should get its own notifications back from its parent
using message reflection, which is described in TN061-TN062. I did not found
anything like this in the current version of WTL, so I decided to implement it
myself. I created two macros: the first macro does the reflection - it sends
some of the notifications received by the window back to it source, and the second macro
which resides in a control wrapper handle these messages. Maybe this
way is slightly rude but so far it works and it is simple... ;-)
Here is the first macros, "reflector":
#define WM_NOTIFY_REFLECTOR()\
if(uMsg == WM_NOTIFY)\
{\
UINT code = ((LPNMHDR)lParam)->code;\
switch(code)\
{\
case NM_SETCURSOR:\
break;\
default:\
if ((NULL != lParam) &&\
(NULL != ((LPNMHDR)lParam)->hwndFrom))\
{\
BOOL bHandled = ::SendMessage(((LPNMHDR)lParam)->hwndFrom, \
WM_NOTIFY + WM_REFLECT_BASE, wParam, lParam);\
if(bHandled) \
return TRUE; \
};\
};\
}\
To use it just place it in message map of any window which you want to reflect
WM_NOTIFY
.
Here is the second macros, "handler":
#define NOTIFY_REFLECT_CODE_HANDLER(cd, func) \
{ \
if (((WM_NOTIFY + WM_REFLECT_BASE) == uMsg) && \
(NULL != lParam) && \
(cd == ((LPNMHDR)lParam)->code)) \
{\
bHandled = FALSE;\
lResult = func((int)wParam, (LPNMHDR)lParam, bHandled);\
if(bHandled)\
return TRUE;\
}\
}
Use it just like usual MESSAGE_HANDLER
or
NOTIFY_HANDLER
in message map of
control.
BEGIN_MSG_MAP(CCusomTreeCtrl)
NOTIFY_REFLECT_CODE_HANDLER(TVN_ITEMEXPANDING, OnExpand)
END_MSG_MAP()
LRESULT OnExpand(int idCtrl, LPNMHDR pnmh, BOOL& bHandled)
{
LPNMTREEVIEW pnmtv = (LPNMTREEVIEW) pnmh;
if (pnmtv->action == TVE_EXPAND)
{
bHandled = TRUE;
return 1;
}
return 0;
}
And do not forget to put header file with macroses into stdafx.h.
I suspect that I missed a lot of important stuff in this implementation
but for my needs it works. If you feel that you can improve it just
do it or let me know how to do it.