65.9K
CodeProject 正在变化。 阅读更多。
Home

WTL 控件的消息反射

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.08/5 (5投票s)

2001年1月26日

viewsIcon

63989

downloadIcon

989

为 Windows 控件的 WTL 包装器实现消息反射。

  • 下载演示项目 - 10 Kb
  • 下载源代码 - 1 Kb
  • 引言

    最近我需要创建一个WTL控件,使其所有功能都在控件内部处理,就像标准的MFC控件一样。

    在MFC中,要做到这一点,控件应该通过消息反射从其父窗口接收到自己的通知,这在TN061-TN062中有描述。我没有在当前版本的WTL中找到类似的功能,所以决定自己实现它。我创建了两个宏:第一个宏执行反射——它将收到的某些通知消息发送回其源窗口,第二个宏位于控件包装器中,处理这些消息。也许这种方法有点粗糙,但到目前为止,它有效且简单……;)

    这是第一个宏,“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; \
                };\
            };\
        }\
    

    要使用它,只需将其放置在任何想要反射WM_NOTIFY消息的窗口的消息映射中即可。

    这是第二个宏,“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;\
        }\
    }
    

    像使用通常的MESSAGE_HANDLERNOTIFY_HANDLER一样,将其放置在控件的消息映射中。

        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;
        }
    

    别忘了将包含宏的头文件包含到stdafx.h中。

    我怀疑在这个实现中遗漏了很多重要的东西,但对于我的需求来说,它已经足够了。如果您认为可以改进它,请随时进行改进或告诉我如何改进。

    © . All rights reserved.