﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-WEI GT</title><link>http://www.cppblog.com/weigt/</link><description>专注于图形界面开发</description><language>zh-cn</language><lastBuildDate>Tue, 09 Jun 2026 17:40:15 GMT</lastBuildDate><pubDate>Tue, 09 Jun 2026 17:40:15 GMT</pubDate><ttl>60</ttl><item><title>仿MFC消息映射</title><link>http://www.cppblog.com/weigt/archive/2015/01/11/209475.html</link><dc:creator>wei_gt</dc:creator><author>wei_gt</author><pubDate>Sun, 11 Jan 2015 12:00:00 GMT</pubDate><guid>http://www.cppblog.com/weigt/archive/2015/01/11/209475.html</guid><wfw:comment>http://www.cppblog.com/weigt/comments/209475.html</wfw:comment><comments>http://www.cppblog.com/weigt/archive/2015/01/11/209475.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/weigt/comments/commentRss/209475.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/weigt/services/trackbacks/209475.html</trackback:ping><description><![CDATA[在开发图形界面（GUI）程序时，对于无句柄的图形控件的框架，在编写响应消息的代码时，可以采用虚函数的方法，在界面框架基类里面调用这些函数，而在子类重写这些虚函数，就可以得到消息的响应。但是，由于windows的消息众多，对应需要编写的虚函数就有很多，这样无疑加大了资源开销，效率也降低。而在MFC消息映射框架里，没有使用虚函数，而是使用了一大堆宏，减少了内存开销，提高了效率。本文提取了MFC消息映射框架，将窗口（CWnd）换成自己的图元（Element），实现了与MFC相同形式的消息映射。<br />在本代码中，Element是所有界面元素的基类，地位相当与MFC的CWnd。<br />消息响应函数类型定义的枚举：<br /><div style="font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all; background-color: #eeeeee;"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">enum</span>&nbsp;ESig<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;ESig_end&nbsp;=&nbsp;0,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;[marks&nbsp;end&nbsp;of&nbsp;message&nbsp;map]</span><span style="color: #008000; "><br /></span><br />&nbsp;&nbsp;&nbsp;&nbsp;ESig_b_D_v,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;BOOL&nbsp;(CDC*)</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;ESig_b_b_v,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;BOOL&nbsp;(BOOL)</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;ESig_b_u_v,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000;">//</span><span style="color: #008000; ">&nbsp;BOOL&nbsp;(UINT)</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;ESig_b_h_v,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;BOOL&nbsp;(HANDLE)</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;ESig_b_W_uu,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;BOOL&nbsp;(CWnd*,&nbsp;UINT,&nbsp;UINT)</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;ESig_b_W_COPYDATASTRUCT,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;BOOL&nbsp;(CWnd*,&nbsp;COPYDATASTRUCT*)</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;ESig_b_v_HELPINFO,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;BOOL&nbsp;(LPHELPINFO);</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;ESig_CTLCOLOR,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;HBRUSH&nbsp;(CDC*,&nbsp;CWnd*,&nbsp;UINT)</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;ESig_CTLCOLOR_REFLECT,&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;HBRUSH&nbsp;(CDC*,&nbsp;UINT)</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;ESig_i_u_W_u,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;int&nbsp;(UINT,&nbsp;CWnd*,&nbsp;UINT)&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;?TOITEM</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;ESig_i_uu_v,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;int&nbsp;(UINT,&nbsp;UINT)</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;ESig_i_W_uu,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;int&nbsp;(CWnd*,&nbsp;UINT,&nbsp;UINT)</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;ESig_i_v_s,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;int&nbsp;(LPTSTR)</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;ESig_l_w_l,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;LRESULT&nbsp;(WPARAM,&nbsp;LPARAM)</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;ESig_l_uu_M,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;LRESULT&nbsp;(UINT,&nbsp;UINT,&nbsp;CMenu*)</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;ESig_v_b_h,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;void&nbsp;(BOOL,&nbsp;HANDLE)</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;ESig_v_h_v,<br />&nbsp;&nbsp;&nbsp;<img src="http://www.cppblog.com/Images/dot.gif"  alt="" /><br />};</div>这里只列举了部分响应函数类型。<br /><br />基类消息映射函数回调函数定义：<br /><div style="font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all; background-color: #eeeeee;"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->typedef&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;(Element::*pEMsgFun)(<span style="color: #0000FF; ">void</span>);</div><br />消息映射入口结构体，各个域的含义与MFC类似。<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">struct</span>&nbsp;EMsgMap_Entery<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;UINT&nbsp;nMessage;<br />&nbsp;&nbsp;&nbsp;&nbsp;UINT&nbsp;nCode;<br />&nbsp;&nbsp;&nbsp;&nbsp;UINT&nbsp;nID;<br />&nbsp;&nbsp;&nbsp;&nbsp;UINT&nbsp;nLastID;<br />&nbsp;&nbsp;&nbsp;&nbsp;UINT_PTR&nbsp;nSig;<br />&nbsp;&nbsp;&nbsp;&nbsp;pEMsgFun&nbsp;pfn;<br />};</div><br />消息映射列表结构体。<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">struct</span>&nbsp;EMsgMap<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;EMsgMap*&nbsp;(*pfnGetMessageMap)();<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;EMsgMap_Entery*&nbsp;lpEnteries;<br />};</div><br />消息映射声明与定义。<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">#define</span>&nbsp;BEGIN_EMSG_MAP(theClass)\<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;EMsgMap*&nbsp;theClass::GetMessageMap()&nbsp;<span style="color: #0000FF; ">const</span>\<br />{&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;GetThisMessageMap();&nbsp;}\<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;EMsgMap*&nbsp;theClass::GetThisMessageMap()\<br />{\<br />&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;theClass&nbsp;ThisClass;\<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">static</span>&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;EMsgMap_Entery&nbsp;_messageEntries[]=\<br />{<br /><br /><span style="color: #0000FF; ">#define</span>&nbsp;END_EMSG_MAP()\<br />{0,&nbsp;0,&nbsp;0,&nbsp;0,&nbsp;ESig_end,&nbsp;(pEMsgFun)0}\<br />};\<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">static</span>&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;EMsgMap&nbsp;messageMap=\<br />{&nbsp;0,&nbsp;&amp;_messageEntries[0]&nbsp;};\<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;&amp;messageMap;\<br />&nbsp;&nbsp;&nbsp;&nbsp;\<br />}</div><br />部分已经实现的消息映射。<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">#define</span>&nbsp;ON_EM_PAINT()&nbsp;\<br />{&nbsp;WM_PAINT,&nbsp;0,&nbsp;0,&nbsp;0,&nbsp;ESig_vv,&nbsp;\<br />&nbsp;&nbsp;&nbsp;&nbsp;(pEMsgFun)&nbsp;\<br />&nbsp;&nbsp;&nbsp;&nbsp;(static_cast&lt;&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;(Element::*)(<span style="color: #0000FF; ">void</span>)&nbsp;&gt;&nbsp;(&nbsp;&amp;ThisClass&nbsp;::&nbsp;OnPaint))&nbsp;},<br /><br /><span style="color: #0000FF; ">#define</span>&nbsp;ON_EM_LBUTTONDOWN()\<br />{WM_LBUTTONDOWN,&nbsp;0,&nbsp;0,&nbsp;0,&nbsp;ESig_vwp,\<br />&nbsp;&nbsp;&nbsp;&nbsp;(pEMsgFun)\<br />&nbsp;&nbsp;&nbsp;&nbsp;(static_cast&lt;<span style="color: #0000FF; ">void</span>(Element::*)(UINT,&nbsp;POINT)&gt;(&amp;ThisClass::OnLButtonDown))},<br /><br /><span style="color: #0000FF; ">#define</span>&nbsp;ON_EM_LBUTTONUP()&nbsp;\<br />{&nbsp;WM_LBUTTONUP,&nbsp;0,&nbsp;0,&nbsp;0,&nbsp;ESig_vwp,&nbsp;\<br />&nbsp;&nbsp;&nbsp;&nbsp;(pEMsgFun)&nbsp;\<br />&nbsp;&nbsp;&nbsp;&nbsp;(static_cast&lt;&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;(&nbsp;Element::*)(UINT,&nbsp;POINT)&nbsp;&gt;&nbsp;(&nbsp;&amp;ThisClass&nbsp;::&nbsp;OnLButtonUp))&nbsp;},<br /><br /><br /><span style="color: #0000FF; ">#define</span>&nbsp;ON_EM_MOUSEMOVE()&nbsp;\<br />{&nbsp;WM_MOUSEMOVE,&nbsp;0,&nbsp;0,&nbsp;0,&nbsp;ESig_vwp,&nbsp;\<br />&nbsp;&nbsp;&nbsp;&nbsp;(pEMsgFun)&nbsp;\<br />&nbsp;&nbsp;&nbsp;&nbsp;(static_cast&lt;&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;(&nbsp;Element::*)(UINT,&nbsp;POINT)&nbsp;&gt;&nbsp;(&nbsp;&amp;ThisClass&nbsp;::&nbsp;OnMouseMove))&nbsp;},<br /><br /><span style="color: #0000FF; ">#define</span>&nbsp;ON_EM_MOUSELEAVE()&nbsp;\<br />{&nbsp;WM_MOUSELEAVE,&nbsp;0,&nbsp;0,&nbsp;0,&nbsp;ESig_vv,&nbsp;\<br />&nbsp;&nbsp;&nbsp;&nbsp;(pEMsgFun)&nbsp;\<br />&nbsp;&nbsp;&nbsp;&nbsp;(static_cast&lt;&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;(Element::*)(<span style="color: #0000FF; ">void</span>)&nbsp;&gt;&nbsp;(&nbsp;&amp;ThisClass&nbsp;::&nbsp;OnMouseLeave))&nbsp;},<br /><br /><span style="color: #0000FF; ">#define</span>&nbsp;ON_EM_SIZE()&nbsp;\<br />{&nbsp;WM_SIZE,&nbsp;0,&nbsp;0,&nbsp;0,&nbsp;ESig_vwii,&nbsp;\<br />&nbsp;&nbsp;&nbsp;&nbsp;(pEMsgFun)&nbsp;\<br />&nbsp;&nbsp;&nbsp;&nbsp;(static_cast&lt;&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;(&nbsp;Element::*)(UINT,&nbsp;<span style="color: #0000FF; ">int</span>,&nbsp;<span style="color: #0000FF; ">int</span>)&nbsp;&gt;&nbsp;(&nbsp;&amp;ThisClass&nbsp;::&nbsp;OnSize))&nbsp;},<br /><br /><span style="color: #0000FF; ">#define</span>&nbsp;efx_msg</div><br />消息处理过程函数，只实现了部分。<br /><div style="font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all; background-color: #eeeeee;"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->LRESULT&nbsp;Element::HandleMessage(&nbsp;UINT&nbsp;uMsg,&nbsp;WPARAM&nbsp;wParam,&nbsp;LPARAM&nbsp;lParam&nbsp;)<br />{<br /><span style="color: #0000ff;">&nbsp; &nbsp; const</span>&nbsp;EMsgMap*&nbsp;pMsgMap&nbsp;=&nbsp;GetMessageMap();<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(pMsgMap&nbsp;==&nbsp;NULL)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;<span style="color: #0000FF; ">false</span>;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;EMsgMap_Entery*&nbsp;pEntry&nbsp;=&nbsp;pMsgMap-&gt;lpEnteries;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;i&nbsp;=&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>(pEntry[i].nSig&nbsp;!=&nbsp;ESig_end)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(pEntry[i].nMessage&nbsp;==&nbsp;uMsg)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">switch</span>(pEntry[i].nSig)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">case</span>&nbsp;ESig_vwp:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;POINT&nbsp;pt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pt.x&nbsp;=&nbsp;LOWORD(lParam);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pt.y&nbsp;=&nbsp;HIWORD(lParam);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span style="color: #0000FF; ">this</span>-&gt;*(reinterpret_cast&lt;<span style="color: #0000FF; ">void</span>(Element::*)(UINT,&nbsp;POINT)&gt;(pEntry[i].pfn)))((UINT)wParam,&nbsp;pt);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">break</span>;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">case</span>&nbsp;ESig_vv:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span style="color: #0000FF; ">this</span>-&gt;*(reinterpret_cast&lt;<span style="color: #0000FF; ">void</span>(Element::*)()&gt;(pEntry[i].pfn)))();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">break</span>;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">case</span>&nbsp;ESig_vwii:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span style="color: #0000FF; ">this</span>-&gt;*(reinterpret_cast&lt;<span style="color: #0000FF; ">void</span>(Element::*)(UINT,&nbsp;<span style="color: #0000FF; ">int</span>,&nbsp;<span style="color: #0000FF; ">int</span>)&gt;(pEntry[i].pfn)))((UINT)wParam,&nbsp;LOWORD(lParam),&nbsp;HIWORD(lParam));<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">break</span>;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">default</span>:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i++;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;1;<br />}</div><br />使用方法。<br />声明：<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">class</span>&nbsp;Element<br />{<br /><span style="color: #008000; ">//</span><span style="color: #008000; "><img src="http://www.cppblog.com/Images/dot.gif"  alt="" /></span><span style="color: #008000; "><br /></span>DECLARE_EMSG_MAP();<br /><span style="color: #008000; ">//</span><span style="color: #008000; "><img src="http://www.cppblog.com/Images/dot.gif"  alt="" /></span><span style="color: #008000; "><br /></span><br /><span style="color: #0000FF; ">protected</span>:<br />&nbsp;&nbsp;&nbsp;&nbsp;efx_msg&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;OnPaint();<br />&nbsp;&nbsp;&nbsp;&nbsp;efx_msg&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;OnMouseMove(UINT&nbsp;nFlag,&nbsp;POINT&nbsp;pt);<br />&nbsp;&nbsp;&nbsp;&nbsp;efx_msg&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;OnMouseLeave();<br />&nbsp;&nbsp;&nbsp;&nbsp;efx_msg&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;OnLButtonDown(UINT&nbsp;uFlag,&nbsp;POINT&nbsp;pt);<br />&nbsp;&nbsp;&nbsp;&nbsp;efx_msg&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;OnLButtonUp(UINT&nbsp;uFlag,&nbsp;POINT&nbsp;pt);<br /><span style="color: #008000; ">//</span><span style="color: #008000; "><img src="http://www.cppblog.com/Images/dot.gif"  alt="" /></span><span style="color: #008000; "><br /></span>};</div><br />实现：<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->BEGIN_EMSG_MAP(Element)<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">{</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;ON_EM_PAINT()<br />&nbsp;&nbsp;&nbsp;&nbsp;ON_EM_MOUSEMOVE()<br />&nbsp;&nbsp;&nbsp;&nbsp;ON_EM_MOUSELEAVE()<br />&nbsp;&nbsp;&nbsp;&nbsp;ON_EM_LBUTTONDOWN()<br />&nbsp;&nbsp;&nbsp;&nbsp;ON_EM_LBUTTONUP()<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">}</span><span style="color: #008000; "><br /></span>END_EMSG_MAP()</div><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">void</span>&nbsp;Element::OnMouseMove(&nbsp;UINT&nbsp;nFlag,&nbsp;POINT&nbsp;pt&nbsp;)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;TRACE(TEXT("%ld::Element::OnMouseMove"),&nbsp;<span style="color: #0000FF; ">this</span>);<br />}<br /><br /><span style="color: #0000FF; ">void</span>&nbsp;Element::OnMouseLeave()<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;TRACE(TEXT("%ld::Element::OnMouseLeave"),&nbsp;<span style="color: #0000FF; ">this</span>);<br />}<br /><br /><span style="color: #0000FF; ">void</span>&nbsp;Element::OnLButtonDown(&nbsp;UINT&nbsp;uFlag,&nbsp;POINT&nbsp;pt&nbsp;)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;TRACE(TEXT("%ld::Element::OnLButtonDown"),&nbsp;<span style="color: #0000FF; ">this</span>);<br />}<br /><br /><span style="color: #0000FF; ">void</span>&nbsp;Element::OnLButtonUp(&nbsp;UINT&nbsp;uFlag,&nbsp;POINT&nbsp;pt&nbsp;)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;TRACE(TEXT("%ld::Element::OnLButtonUp"),&nbsp;<span style="color: #0000FF; ">this</span>);<br />}</div><br />这样可以按照以上的思路，不断完善消息映射函数类型。<br />由于Element是无窗口的图元元素，没有系统的窗口消息的分发支持，所以要想真正实现这些功能，还需要一个图元管理器，用于度量的坐标，消息的分发等等。<br /><img src ="http://www.cppblog.com/weigt/aggbug/209475.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/weigt/" target="_blank">wei_gt</a> 2015-01-11 20:00 <a href="http://www.cppblog.com/weigt/archive/2015/01/11/209475.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>