﻿<?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++博客-一路向北-随笔分类-C++</title><link>http://www.cppblog.com/deane/category/11120.html</link><description>                    追逐梦想，永不停步......</description><language>zh-cn</language><lastBuildDate>Mon, 01 Mar 2010 21:22:02 GMT</lastBuildDate><pubDate>Mon, 01 Mar 2010 21:22:02 GMT</pubDate><ttl>60</ttl><item><title>关于C++中的临时对象问题</title><link>http://www.cppblog.com/deane/archive/2010/02/25/108428.html</link><dc:creator>李阳</dc:creator><author>李阳</author><pubDate>Thu, 25 Feb 2010 06:44:00 GMT</pubDate><guid>http://www.cppblog.com/deane/archive/2010/02/25/108428.html</guid><wfw:comment>http://www.cppblog.com/deane/comments/108428.html</wfw:comment><comments>http://www.cppblog.com/deane/archive/2010/02/25/108428.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/deane/comments/commentRss/108428.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/deane/services/trackbacks/108428.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;C++中真正的临时对象是看不见的，它们不出现在你的源代码中，临时对象的产生在如下几个时刻:&nbsp;1.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 用构造函数作为隐式类型转换函数时，会创建临时对象。例：&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class Integer&nbsp;&nb...&nbsp;&nbsp;<a href='http://www.cppblog.com/deane/archive/2010/02/25/108428.html'>阅读全文</a><img src ="http://www.cppblog.com/deane/aggbug/108428.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/deane/" target="_blank">李阳</a> 2010-02-25 14:44 <a href="http://www.cppblog.com/deane/archive/2010/02/25/108428.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>剖析Windows消息处理机制</title><link>http://www.cppblog.com/deane/archive/2010/01/07/105099.html</link><dc:creator>李阳</dc:creator><author>李阳</author><pubDate>Thu, 07 Jan 2010 08:17:00 GMT</pubDate><guid>http://www.cppblog.com/deane/archive/2010/01/07/105099.html</guid><wfw:comment>http://www.cppblog.com/deane/comments/105099.html</wfw:comment><comments>http://www.cppblog.com/deane/archive/2010/01/07/105099.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/deane/comments/commentRss/105099.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/deane/services/trackbacks/105099.html</trackback:ping><description><![CDATA[<p><br>前一段，帮人写了个小控件，又温习了一遍Windows消息处理机制，现在把一些知识点总结出来，供大家参考.<br><br><br>1.窗口<br>&nbsp;&nbsp; Windows程序是由一系列的窗口构成的，每个窗口都有自己的窗口过程，窗口过程就是一个拥有有固定 Signature 的 C函数，具体格式如下：</p>
<p>&nbsp;&nbsp; LRESULT CALLBACK WindowProc(HWND hwnd,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UINT uMsg,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WPARAM wParam,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LPARAM lParam<br>&nbsp;&nbsp; );<br>&nbsp;&nbsp; <br>&nbsp;&nbsp; 窗口类型：<br>&nbsp;&nbsp; 可重叠窗口(Overlapped Window)，<br>&nbsp;&nbsp; 弹出窗口(Pop-up Window)，<br>&nbsp;&nbsp; 子窗口(Child Window)<br>&nbsp;&nbsp; <br>&nbsp;&nbsp; 窗口之间的关系: 父子关系，拥有关系，前后关系。<br>&nbsp;&nbsp; <br>2.线程<br>&nbsp;&nbsp;&nbsp; 一个进程至少拥有一个线程，称为主线程，如果一个线程创建了窗口，拥有GUI资源，那么也称该线程为GUI线程,否则就为工作线程。窗口是由线程创建的，<br>&nbsp;创建窗口的线程就拥有该窗口。这种线程拥有关系的概念对窗口有重要的意义：建立窗口的线程必须是为窗口处理所有消息的线程。为了使这个概念更加明<br>&nbsp;确具体，可以想像一个线程建立了一个窗口，然后就结束了。在这种情况下，窗口不会收到一个WM_DESTROY或WM_NCDESTROY消息，因为线程已经结束，不可<br>&nbsp;能被用来使窗口接收和处理这些消息。每个线程，如果它至少建立了一个窗口，都由系统对它分配一个消息队列。这个队列用于窗口消息的派送(dispatch)。<br>&nbsp;为了使窗口接收这些消息，线程必须有它自己的消息循环，消息循环一般如下：<br>&nbsp;<br>&nbsp;MSG msg;<br>&nbsp;while( GetMessage(&amp;msg, NULL, 0, 0) )<br>&nbsp;{<br>&nbsp;&nbsp;TranslateMessage (&amp;msg);<br>&nbsp;&nbsp;DispatchMessage (&amp;msg);<br>&nbsp;}<br>&nbsp;<br>&nbsp;应用程序不断的从消息队列中获取消息,然后系统通过DispatchMessage函数分派消息到相应窗口的窗口过程，使得消息得到处理。当获取到WM_QUIT消息时，<br>&nbsp;GetMessage返回0，循环结束。<br>&nbsp;<br>3.消息<br>&nbsp;消息，就是指Windows发出的一个通知，告诉应用程序某个事情发生了。例如，单击鼠标、改变窗口尺寸、按下键盘上的一个键都会使Windows发送一个消息<br>&nbsp;给应用程序，它被定义为：<br>&nbsp;&nbsp;typedef struct {<br>&nbsp;&nbsp;HWND hwnd;&nbsp;&nbsp;&nbsp;&nbsp;//窗口句柄, 发生在哪个窗口上<br>&nbsp;&nbsp;UINT message;&nbsp;&nbsp;&nbsp;//消息标识号 ( WM_MOUSEMOVE, WM_LBUTTONDOWN, ... )<br>&nbsp;&nbsp;WPARAM wParam;&nbsp;&nbsp;&nbsp;//消息参数1<br>&nbsp;&nbsp;LPARAM lParam;&nbsp;&nbsp;&nbsp;//消息参数2<br>&nbsp;&nbsp;DWORD time;<br>&nbsp;&nbsp;POINT pt;<br>&nbsp;} MSG, *PMSG;<br>&nbsp;一个消息结构体包含了该事件 所有完备信息，当应用程序收到该消息时，就可以做出相应处理了。<br>&nbsp;<br>&nbsp;消息分类</p>
<p>&nbsp;&lt;1&gt;.队列消息和非队列消息 </p>
<p>&nbsp;&nbsp;从消息的发送途径上看，消息分两种：队列消息和非队列消息。<br>&nbsp;&nbsp;队列消息送到系统消息队列，然后到线程消息队列；非队列消息直接送给目的窗口过程。</p>
<p>&nbsp;&nbsp;这里，对消息队列阐述如下：<br>&nbsp;&nbsp;Windows维护一个系统消息队列(System message queue)，每个GUI线程有一个线程消息队列(Thread message queue)。鼠标、键盘事件由鼠标或键盘驱动<br>&nbsp;&nbsp;程序转换成输入消息并把消息放进系统消息队列，例如WM_MOUSEMOVE、WM_LBUTTONUP、WM_KEYDOWN、WM_CHAR等等。Windows每次从系统消息队列移走一个<br>&nbsp;&nbsp;消息，确定它是送给哪个窗口的和这个窗口是由哪个线程创建的，然后，把它放进窗口创建线程的线程消息队列。线程消息队列接收送给该线程所创建窗口<br>&nbsp;&nbsp;的消息。线程从消息队列取出消息，通过Windows把它送给适当的窗口过程来处理。<br>&nbsp;&nbsp;<br>&nbsp;&nbsp;除了键盘、鼠标消息以外，队列消息还有WM_PAINT、WM_TIMER和WM_QUIT。这些队列消息以外的绝大多数消息是非队列消息。</p>
<p><br>&nbsp;&lt;2&gt;.系统消息和应用程序消息 </p>
<p>&nbsp;&nbsp;从消息的来源来看，可以分为：系统定义的消息和应用程序定义的消息。</p>
<p>&nbsp;&nbsp;系统消息ID的范围是从0到WM_USER-1，或0X80000到0XBFFFF；应用程序消息从WM_USER(0X0400)到0X7FFF，或0XC000到0XFFFF；WM_USER到0X7FFF范围的消息<br>&nbsp;&nbsp;由应用程序自己使用；0XC000到0XFFFF范围的消息用来和其他应用程序通信，为了ID的唯一性，使用::RegisterWindowMessage来得到该范围的消息ID。<br>&nbsp;<br>&nbsp;&lt;3&gt;.窗口消息，命令消息，控件通知消息<br>&nbsp;&nbsp;根据处理过程的不同,可以分为三类：窗口消息，命令消息，控件通知消息。<br>&nbsp;&nbsp;<br>&nbsp;&nbsp;(1).窗口消息<br>&nbsp;&nbsp;&nbsp;一般以WM_开头，如WM_CREATE, WM_SIZE, WM_MOUSEMOVE等标准的Windows消息, 用于窗口相关的事件通知，窗口消息将由系统分配到该窗口的窗口过程处理。<br>&nbsp;&nbsp;(2).命令消息 (WM_COMMAND)<br>&nbsp;&nbsp;&nbsp;一种特殊的窗口消息，它从一个窗口发送到另一个窗口以处理来自用户的请求，通常是从子窗口发送到父窗口，例如，点击按钮时，按钮的父窗口会收到<br>&nbsp;&nbsp;&nbsp;WM_COMMAND消息，用以通知父窗口按钮被点击，经测试：子窗口向父窗口发送WM_COMMAND消息，或者称为父窗口会收到WM_COMMAND消息，操作系统并不是<br>&nbsp;&nbsp;&nbsp;通过将WM_COMMAND消息放入到父窗口的消息队列中去，而是直接调用了父窗口的窗口过程，以 WM_COMMAND 为消息标识参数(UINT uMsg)，实现这个功能的<br>&nbsp;&nbsp;&nbsp;API函数正是:&nbsp;LRESULT DispatchMessage(const MSG *lpmsg);<br>&nbsp;&nbsp;(3).控件通知消息<br>&nbsp;&nbsp;&nbsp;WM_NOTIFY消息，当用户与控件交互(Edit, Button...)时，通知消息会从控件窗口发送到父窗口，这种消息的目的不是为了处理用户命令，而是为了让父窗<br>&nbsp;&nbsp;&nbsp;口能够适时的改变控件。<br>&nbsp;&nbsp;</p>
<p>4.测试<br>&nbsp;&lt;1&gt;.测试代码:<br>&nbsp;<br>&nbsp;&nbsp;消息循环中，将从消息队列中取出的消息逐一打印出来，<br></p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000">(GetMessage(</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">msg,&nbsp;NULL,&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">))<br><img id=Codehighlighter1_38_255_Open_Image onclick="this.style.display='none'; Codehighlighter1_38_255_Open_Text.style.display='none'; Codehighlighter1_38_255_Closed_Image.style.display='inline'; Codehighlighter1_38_255_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_38_255_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_38_255_Closed_Text.style.display='none'; Codehighlighter1_38_255_Open_Image.style.display='inline'; Codehighlighter1_38_255_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top>&nbsp;&nbsp;</span><span id=Codehighlighter1_38_255_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_38_255_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">&nbsp;buf[</span><span style="COLOR: #000000">1024</span><span style="COLOR: #000000">];<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;sprintf_s(buf,&nbsp;</span><span style="COLOR: #000000">1024</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">hWnd:%d&nbsp;uMsg:&nbsp;%d&nbsp;WParam:&nbsp;%d&nbsp;&nbsp;LParam:&nbsp;%d\n</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;msg.hwnd,&nbsp;msg.message,&nbsp;msg.wParam,&nbsp;msg.lParam);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;std::cout</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">buf;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;TranslateMessage(</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">msg);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;DispatchMessage(</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">msg);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span></div>
<p><br>&nbsp;&nbsp;在窗口过程中，如果收到 WM_COMMAND 消息，就在窗口上输入来。<br></p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">LRESULT&nbsp;CALLBACK&nbsp;WndProc&nbsp;(HWND&nbsp;hwnd,&nbsp;UINT&nbsp;message,&nbsp;WPARAM&nbsp;wParam,&nbsp;LPARAM&nbsp;lParam)<br><img id=Codehighlighter1_83_621_Open_Image onclick="this.style.display='none'; Codehighlighter1_83_621_Open_Text.style.display='none'; Codehighlighter1_83_621_Closed_Image.style.display='inline'; Codehighlighter1_83_621_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_83_621_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_83_621_Closed_Text.style.display='none'; Codehighlighter1_83_621_Open_Image.style.display='inline'; Codehighlighter1_83_621_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top>&nbsp;&nbsp;</span><span id=Codehighlighter1_83_621_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_83_621_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">switch</span><span style="COLOR: #000000">&nbsp;(message)<br><img id=Codehighlighter1_108_555_Open_Image onclick="this.style.display='none'; Codehighlighter1_108_555_Open_Text.style.display='none'; Codehighlighter1_108_555_Closed_Image.style.display='inline'; Codehighlighter1_108_555_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_108_555_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_108_555_Closed_Text.style.display='none'; Codehighlighter1_108_555_Open_Image.style.display='inline'; Codehighlighter1_108_555_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_108_555_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_108_555_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">case</span><span style="COLOR: #000000">&nbsp;WM_COMMAND:<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;HDhdc&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;GetDC&nbsp;(hwnd)&nbsp;;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;SelectObject&nbsp;(hdc,&nbsp;GetStockObject&nbsp;(SYSTEM_FIXED_FONT))&nbsp;;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;TextOut(hdc,&nbsp;</span><span style="COLOR: #000000">24</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;cxChar,&nbsp;cyChar&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;(rect.bottom&nbsp;</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">&nbsp;cyChar&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">),<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;szBuffer,<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;wsprintf(szBuffer,&nbsp;szFormat,<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TEXT&nbsp;(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">WM_COMMAND</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">),<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HIWORD(wParam),&nbsp;LOWORD(wParam),<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HIWORD(lParam),&nbsp;LOWORD(lParam))<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;ReleaseDC&nbsp;(hwnd,&nbsp;hdc)&nbsp;;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;ValidateRect&nbsp;(hwnd,&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">rect)&nbsp;;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">break</span><span style="COLOR: #000000">&nbsp;;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;<img src="http://www.cppblog.com/Images/dot.gif"><img src="http://www.cppblog.com/Images/dot.gif"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;<img src="http://www.cppblog.com/Images/dot.gif"><img src="http://www.cppblog.com/Images/dot.gif"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;<img src="http://www.cppblog.com/Images/dot.gif"><img src="http://www.cppblog.com/Images/dot.gif"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;DefWindowProc&nbsp;(hwnd,&nbsp;message,&nbsp;wParam,&nbsp;lParam)&nbsp;;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span></div>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;2&gt;.运行结果<br>&nbsp;&nbsp;&nbsp;&nbsp;一个窗口，窗口上有一个按钮子窗口，然后还有一个控制台，输出消息循环中的每条消息，当父窗口收到 WM_COMMAND 消息时，<br>&nbsp;&nbsp;&nbsp; 会在屏幕上输出。<br><br><img style="WIDTH: 901px; HEIGHT: 655px" height=655 alt="" src="http://www.cppblog.com/images/cppblog_com/deane/messageImg/5.jpg" width=901 border=0><br><br><br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(1). 当鼠标在父窗口上移动时：<br>&nbsp;&nbsp;&nbsp;<br><img height=201 alt="" src="http://www.cppblog.com/images/cppblog_com/deane/messageImg/1.JPG" width=589 border=0><br><br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;可见父窗口 hWnd:&nbsp;461982，uMsg : 521 ( WM_MOUSEMOVE )，从线程消息队列中取出的。<br><br><br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(2). 当鼠标在按钮子窗口上移动时：<br><br><img height=224 alt="" src="http://www.cppblog.com/images/cppblog_com/deane/messageImg/3.jpg" width=589 border=0><br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;可见按钮 hWnd:&nbsp;462118，uMsg : 521 ( WM_MOUSEMOVE)，从线程消息队列中取出的。<br><br><br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(3). 当鼠标在父窗口上点击时：<br><br><img height=163 alt="" src="http://www.cppblog.com/images/cppblog_com/deane/messageImg/2.JPG" width=559 border=0><br><br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;父窗口收到了&nbsp;513(WM_LBUTTONDOWN), 514(WM_LBUTTONUP) 消息，从线程消息队列中取出的。<br><br><br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(4). 当鼠标在按钮窗口上点击时：<br><br><img height=191 alt="" src="http://www.cppblog.com/images/cppblog_com/deane/messageImg/4.JPG" width=761 border=0><br><br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;按钮窗口从线程的消息队列中取出了 513(WM_LBUTTONDOWN), 514(WM_LBUTTONUP) 消息，父窗口收到了WM_COMMAND<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;消息，TextOut 绘制出 WM_COMMAND 文本。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;我在 WM_COMMAND 的消息处理语句处打有断点，看下图:<br><br><img height=464 alt="" src="http://www.cppblog.com/images/cppblog_com/deane/messageImg/6.jpg" width=554 border=0><br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&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;&nbsp;&nbsp;&nbsp; hwnd:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x00070c9e，十进制就是461982，父窗口句柄；<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;message:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;273 (WM_COMMAND)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;wParam:&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;&nbsp;&nbsp;&nbsp;&nbsp; lParam:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;具体是WinMain中的哪一个函数中最后调用了 窗口过程 WndProc 呢，见下图：<br><br><br><br><img height=325 alt="" src="http://www.cppblog.com/images/cppblog_com/deane/messageImg/8.JPG" width=761 border=0><br><br><br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;原来是在 DispatchMessage 函数中，再看看参数的值：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;msg.hwnd:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x00070d26，十进制是462118，是按钮窗口的句柄;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;msg.message:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;514 (&nbsp; WM_LBUTTONUP&nbsp; )<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;哦~~~~，原来是操作系统在从该线程的消息队列中取出按钮的 WM_LBUTTONUP (鼠标左键释放) 消息后，调用<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DispatchMessage&nbsp;分派消息，DispatchMessage 会先将 WM_LBUTTONUP 消息分派到按钮的窗口过程(系统默认有)，<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;参数， WM_COMMAND 为窗口过程的第二个参数 调用了&nbsp;父窗口的窗口过程，也就是将 WM_COMMAND<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;消息分发到了父窗口，从而使父窗口得到了通知。这些，都是 Windows 来完成的，应用程序只需要在相应的窗口<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;过程中处理相应的消息。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;从上面，我们还可以看出，WM_COMMAND 是非队列消息，直接分派到目的窗口过程，而不是放入到消息队列中，<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;让消息循环去取。<br><br><br><br>&nbsp;总结:<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;简而言之，&nbsp;标准Windows消息发送到产生窗口，通知消息(WM_COMMAND, WM_NOTIFY)发送到父窗口，这是Windows<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;的标准消息处理过程，MFC对 Window API 进行了封装，有自己的一套消息处理流程， 消息顺着一条路径流动，需要<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;处理的对象可以添加消息响应函数处理之，对于命令消息，它有 CView , CDocument,&nbsp; CMainFram ,&nbsp; CWinApp 一系列处理<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 节点，对于通知消息，MFC还加入一种很好的机制：消息反射，就是父窗口收到子窗口发出的通知消息后，会将此消息<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 发送给子窗口，先让子窗口处理，如果子窗口不处理，父窗口再处理之，这样有利于将所有消息处理代码都集成了子窗口<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 中，有利于控件的开发。MFC的消息处理，我不予详细讨论了，有兴趣的可以参考侯捷的&lt;&lt;深入浅出MFC&gt;&gt;。<br><br><br><br><br><br><br><br><br><br>
<img src ="http://www.cppblog.com/deane/aggbug/105099.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/deane/" target="_blank">李阳</a> 2010-01-07 16:17 <a href="http://www.cppblog.com/deane/archive/2010/01/07/105099.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于 return void()</title><link>http://www.cppblog.com/deane/archive/2009/07/08/89536.html</link><dc:creator>李阳</dc:creator><author>李阳</author><pubDate>Wed, 08 Jul 2009 03:54:00 GMT</pubDate><guid>http://www.cppblog.com/deane/archive/2009/07/08/89536.html</guid><wfw:comment>http://www.cppblog.com/deane/comments/89536.html</wfw:comment><comments>http://www.cppblog.com/deane/archive/2009/07/08/89536.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/deane/comments/commentRss/89536.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/deane/services/trackbacks/89536.html</trackback:ping><description><![CDATA[<br><br>大家都知道，return 用来在函数里返回，有两种形式：一是 直接用return; 或者省略，表示无返回值。二是 return expression; 返回一个值。<br>今天测试时我发现两种以前没注意的方式，也是正确的。<br><br><br>&lt;1&gt;.&nbsp;&nbsp; <br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;FuncA()<br><img id=Codehighlighter1_13_42_Open_Image onclick="this.style.display='none'; Codehighlighter1_13_42_Open_Text.style.display='none'; Codehighlighter1_13_42_Closed_Image.style.display='inline'; Codehighlighter1_13_42_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_13_42_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_13_42_Closed_Text.style.display='none'; Codehighlighter1_13_42_Open_Image.style.display='inline'; Codehighlighter1_13_42_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_13_42_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_13_42_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">();&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">正确的，同：return;</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top></span><span style="COLOR: #000000">}</span></span></div>
<br><br>&lt;2&gt;.<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;FuncB()<br><img id=Codehighlighter1_13_52_Open_Image onclick="this.style.display='none'; Codehighlighter1_13_52_Open_Text.style.display='none'; Codehighlighter1_13_52_Closed_Image.style.display='inline'; Codehighlighter1_13_52_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_13_52_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_13_52_Closed_Text.style.display='none'; Codehighlighter1_13_52_Open_Image.style.display='inline'; Codehighlighter1_13_52_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_13_52_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_13_52_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;FuncA();</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">也可以，同：&nbsp;FuncA();</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top></span><span style="COLOR: #000000">}</span></span></div>
<br><br><br>这两种特性在某些情况下，是很有用的。比如，我要写一个函数模板，以 任意的模板参数类型 T 为返回值。<br><br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">template&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">typename&nbsp;T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>T&nbsp;FuncC()<br><img id=Codehighlighter1_32_67_Open_Image onclick="this.style.display='none'; Codehighlighter1_32_67_Open_Text.style.display='none'; Codehighlighter1_32_67_Closed_Image.style.display='inline'; Codehighlighter1_32_67_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_32_67_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_32_67_Closed_Text.style.display='none'; Codehighlighter1_32_67_Open_Image.style.display='inline'; Codehighlighter1_32_67_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_32_67_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_32_67_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;T();&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">这里举例返回&nbsp;T();</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top></span><span style="COLOR: #000000">}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>template&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">typename&nbsp;T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>T&nbsp;FuncD()<br><img id=Codehighlighter1_102_127_Open_Image onclick="this.style.display='none'; Codehighlighter1_102_127_Open_Text.style.display='none'; Codehighlighter1_102_127_Closed_Image.style.display='inline'; Codehighlighter1_102_127_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_102_127_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_102_127_Closed_Text.style.display='none'; Codehighlighter1_102_127_Open_Image.style.display='inline'; Codehighlighter1_102_127_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_102_127_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_102_127_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;FuncC</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span></div>
<br><br>所以即使对于 返回值 为 void 的情况，FuncD&lt;void&gt;(); 也是适用的。<br>如果编译器不支持这种特性。那么当我们就得针对void返回类型进行特化，或者函数重载，示例代码如下：<br><br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #008000">//</span><span style="COLOR: #008000">一般处理</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">template&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">typename&nbsp;T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>T&nbsp;FuncE()<br><img id=Codehighlighter1_39_64_Open_Image onclick="this.style.display='none'; Codehighlighter1_39_64_Open_Text.style.display='none'; Codehighlighter1_39_64_Closed_Image.style.display='inline'; Codehighlighter1_39_64_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_39_64_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_39_64_Closed_Text.style.display='none'; Codehighlighter1_39_64_Open_Image.style.display='inline'; Codehighlighter1_39_64_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_39_64_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_39_64_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;FuncC</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">特化版本</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">template</span><span style="COLOR: #000000">&lt;&gt;</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;FuncE</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">()<br><img id=Codehighlighter1_104_125_Open_Image onclick="this.style.display='none'; Codehighlighter1_104_125_Open_Text.style.display='none'; Codehighlighter1_104_125_Closed_Image.style.display='inline'; Codehighlighter1_104_125_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_104_125_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_104_125_Closed_Text.style.display='none'; Codehighlighter1_104_125_Open_Image.style.display='inline'; Codehighlighter1_104_125_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_104_125_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_104_125_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;FuncC</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">或者进行重载亦可</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;FuncE()<br><img id=Codehighlighter1_152_172_Open_Image onclick="this.style.display='none'; Codehighlighter1_152_172_Open_Text.style.display='none'; Codehighlighter1_152_172_Closed_Image.style.display='inline'; Codehighlighter1_152_172_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_152_172_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_152_172_Closed_Text.style.display='none'; Codehighlighter1_152_172_Open_Image.style.display='inline'; Codehighlighter1_152_172_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_152_172_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_152_172_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;FuncC</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;Test()<br><img id=Codehighlighter1_188_274_Open_Image onclick="this.style.display='none'; Codehighlighter1_188_274_Open_Text.style.display='none'; Codehighlighter1_188_274_Closed_Image.style.display='inline'; Codehighlighter1_188_274_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_188_274_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_188_274_Closed_Text.style.display='none'; Codehighlighter1_188_274_Open_Image.style.display='inline'; Codehighlighter1_188_274_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_188_274_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_188_274_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;FuncE</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">();&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">泛化版本</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;FuncE</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">();&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">特化版本</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;FuncE();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">重载版本</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top></span><span style="COLOR: #000000">}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>FuncE函数没有参数，可以特化或者重载，但如果它还有其他模板参数的话，由于函数模板不支持部分特化，就只能使用重载模板函数了。<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span></div>
<br><br>发现这种方式后，为我省了很多事，原来为了识别一个模板参数是否为void，我模拟stl 搞了个 templeate &lt;typename T&gt; Return_Type_Trait {}，然后利用类模板的特化来专门定义一些类型，以到达识别返回类型的目的。现在看来，都是多余的。可以使用这个特性来实现。<br><br><br><br>
<img src ="http://www.cppblog.com/deane/aggbug/89536.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/deane/" target="_blank">李阳</a> 2009-07-08 11:54 <a href="http://www.cppblog.com/deane/archive/2009/07/08/89536.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>