Click here to Skip to main content
15,884,099 members
Articles / Desktop Programming / WTL
Article

Message Reflection for WTL Controls

Rate me:
Please Sign up or sign in to vote.
4.08/5 (5 votes)
25 Jan 2001 62.7K   985   18   3
Impementation of message reflection for WTL wrappers for Windows Controls
  • 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)
    {
        // disable expanding
        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.

    License

    This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

    A list of licenses authors might use can be found here


    Written By
    Web Developer SEO
    Russian Federation Russian Federation
    AlexF's Blog in Russian
    Owner Spy competition analysis
    Rating Burner Rating of blogs

    Comments and Discussions

     
    Generaldidn't work for me Pin
    Bobby Paulose8-Jul-04 14:31
    Bobby Paulose8-Jul-04 14:31 
    GeneralATL REFLECT_NOTIFICATIONS Pin
    Maximilian Hänel27-Jan-01 4:13
    Maximilian Hänel27-Jan-01 4:13 
    GeneralRe: ATL REFLECT_NOTIFICATIONS Pin
    9-Apr-01 7:36
    suss9-Apr-01 7:36 

    General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

    Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.