﻿<?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++博客-Sukhoi</title><link>http://www.cppblog.com/zgysx/</link><description>两岸猿声啼不住 轻舟已过万重山</description><language>zh-cn</language><lastBuildDate>Sat, 18 Apr 2026 03:39:53 GMT</lastBuildDate><pubDate>Sat, 18 Apr 2026 03:39:53 GMT</pubDate><ttl>60</ttl><item><title>boost之scope_exit</title><link>http://www.cppblog.com/zgysx/archive/2013/07/15/201826.html</link><dc:creator>永遇乐</dc:creator><author>永遇乐</author><pubDate>Mon, 15 Jul 2013 09:30:00 GMT</pubDate><guid>http://www.cppblog.com/zgysx/archive/2013/07/15/201826.html</guid><wfw:comment>http://www.cppblog.com/zgysx/comments/201826.html</wfw:comment><comments>http://www.cppblog.com/zgysx/archive/2013/07/15/201826.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zgysx/comments/commentRss/201826.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zgysx/services/trackbacks/201826.html</trackback:ping><description><![CDATA[<div>在写程序的时候，经常要做一步就要判断这一步是否成功，如果不成功，则程序不能继续往下走了，得删除当前申请的资源。<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; ">void</span>&nbsp;Fun()<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;*&nbsp;p&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;<span style="color: #0000FF; ">int</span>;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>(&nbsp;error&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delete&nbsp;p;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">float</span>&nbsp;*&nbsp;p1&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;<span style="color: #0000FF; ">float</span>;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>(&nbsp;error1&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delete&nbsp;p;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delete&nbsp;p1;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp; &nbsp; &nbsp;.......<br />&nbsp; &nbsp; &nbsp;.......<br />}</div>检查是否发生错误与删除资源的代码会越来越多，看上去十分之臃肿，boost提供了一个socp_exit，可以帮助我们解决上面之困。<br /><div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 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;Fun()<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;*&nbsp;pInt&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;<span style="color: #0000FF; ">int</span>;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">float</span>&nbsp;*&nbsp;pFloat&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;<span style="color: #0000FF; ">float</span>;<br />&nbsp;&nbsp;&nbsp;&nbsp;BOOST_SCOPE_EXIT(&nbsp;(&amp;pInt)&nbsp;(&amp;pFloat)&nbsp;)<span style="color: #008000; ">//</span><span style="color: #008000; ">以引用的形式进行变量捕获</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delete&nbsp;pInt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pInt&nbsp;=&nbsp;nullptr;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delete&nbsp;pFloat;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pFloat&nbsp;=&nbsp;nullptr;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;&lt;&lt;&nbsp;__FUNCTION__&nbsp;&lt;&lt;&nbsp;std::endl;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;BOOST_SCOPE_EXIT_END;<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;std::<span style="color: #0000FF; ">string</span>&nbsp;str("abc");<br />&nbsp;&nbsp;&nbsp;&nbsp;BOOST_SCOPE_EXIT(&nbsp;str&nbsp;)&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">以值传递的形式进行变量捕获</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str&nbsp;=&nbsp;"123";<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;&lt;&lt;&nbsp;__FUNCTION__&nbsp;&lt;&lt;&nbsp;std::endl;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;BOOST_SCOPE_EXIT_END<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>;<br />}</div><br /><br /><br /><br />
</div><img src ="http://www.cppblog.com/zgysx/aggbug/201826.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zgysx/" target="_blank">永遇乐</a> 2013-07-15 17:30 <a href="http://www.cppblog.com/zgysx/archive/2013/07/15/201826.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>游戏中内存泄漏的查找</title><link>http://www.cppblog.com/zgysx/archive/2013/01/19/197413.html</link><dc:creator>永遇乐</dc:creator><author>永遇乐</author><pubDate>Sat, 19 Jan 2013 08:04:00 GMT</pubDate><guid>http://www.cppblog.com/zgysx/archive/2013/01/19/197413.html</guid><wfw:comment>http://www.cppblog.com/zgysx/comments/197413.html</wfw:comment><comments>http://www.cppblog.com/zgysx/archive/2013/01/19/197413.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/zgysx/comments/commentRss/197413.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zgysx/services/trackbacks/197413.html</trackback:ping><description><![CDATA[<div><p><font class="Apple-style-span" color="#0000ff" size="2">&nbsp; &nbsp; &nbsp;</font>我们的这款游戏从开发到上线至今已有大概4年了，昨天发现代码中有new出来的对象没有delete，程序退出后VS输出栏中居然没有提示，难道程序中没有内存泄漏检察？进一步的求证确定了我的担忧（我是半路进的项目组）。在代码中加上_CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG)  |  _CRTDBG_LEAK_CHECK_DF)后，VS的输出栏赫然显示了大量的内存泄漏。在动手解决内存泄漏之前，先复习一下有关new操作符重载的相关知识：</p> <p>new 操作符按其可见性可分为全局的与局部的(类成员)，我们可以对他们进行重载，下面是VS 2010中new.cpp中new操作符的声明</p><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: #008080; ">1</span>&nbsp;<span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">operator</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">new</span><span style="color: #000000; ">(&nbsp;size_t&nbsp;size&nbsp;);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">1</span><span style="color: #008000; "><br /></span><span style="color: #008080; ">2</span>&nbsp;<span style="color: #008000; "></span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">operator</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">new</span><span style="color: #000000; ">&nbsp;(&nbsp;size_t&nbsp;size,&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;nBlockUse,&nbsp;</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">&nbsp;szFileName,&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;nLine&nbsp;);&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">2</span></div><p><br /></p><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><span style="color: #000000; ">&nbsp;main()<br />{<br />&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">&nbsp;p&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">new</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">调用第1个new</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;p&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">new</span><span style="color: #000000; ">&nbsp;(&nbsp;_NORMAL_BLOCK,&nbsp;__FILE__,&nbsp;__LINE__&nbsp;)&nbsp;</span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">调用第2个new</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">}</span></div> <p>调用new时，传入的参数比new声明时的参数少了一个，即第一个参数，该参数是new的对象的大小，由编译器填写，禁止程序员自己插手。</p> <p>&nbsp;</p> <p>对一个类重载new和delete</p><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><span style="color: #000000; ">&nbsp;Student<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">operator</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">new</span><span style="color: #000000; ">(&nbsp;size_t&nbsp;size&nbsp;)&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">3</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">&nbsp;__FUNCTION__&nbsp;</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">&nbsp;std::endl;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;malloc(&nbsp;</span><span style="color: #0000FF; ">sizeof</span><span style="color: #000000; ">(Student)&nbsp;);<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />};<br /></span></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: #000000; ">Student&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">&nbsp;pS&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">new</span><span style="color: #000000; ">&nbsp;Student();&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">调用Student类内部的new，即第3个new</span></div><p>&nbsp;</p> <p>当我们new一个自定义类时，如果该类重载了new操作符，则优先使用该类内部定义的new，如果这时非要调用全局的new操作符怎么办呢？可以在new前面加两个冒号:</p><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: #000000; ">pS&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;::</span><span style="color: #0000FF; ">new</span><span style="color: #000000; ">&nbsp;Student();&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">调用全局的new，第1个new</span></div><p>&nbsp;</p> <p>下面回到解决内存泄漏的步骤上：</p> <p>1 在程序必定会执行的路径上加上：</p><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: #000000; ">_CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG)&nbsp;</span><span style="color: #000000; ">|</span><span style="color: #000000; ">&nbsp;_CRTDBG_LEAK_CHECK_DF);</span></div> <p>不一定非得是程序的最开始处<br /><br /></p> <p>2 使用上面给出的第2个new操作符，当程序退出时，它会在VS输出栏中注明是哪行代码引起的内存泄漏。即所有的new 都改为</p><div style="display: inline-block; "></div><span class="Apple-style-span" style="font-size: 13px; background-color: #eeeeee; "><span style="color: #0000ff; ">new</span><span style="color: #000000; ">&nbsp;(&nbsp;_NORMAL_BLOCK,&nbsp;__FILE__,&nbsp;__LINE__&nbsp;)</span></span><p>&nbsp;</p> <p>完了。。。。。这样就可以了。<br /></p> <p>但是，我们程序已有的代码都写的是new，而不是new ( _NORMAL_BLOCK, __FILE__, __LINE__ )。</p> <p><br />MFC中的解决方法：</p><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><span style="color: #000000; ">&nbsp;new&nbsp;&nbsp;new&nbsp;(&nbsp;_NORMAL_BLOCK,&nbsp;__FILE__,&nbsp;__LINE__&nbsp;)</span></div> <p>这样好像是可以解决问题，但是我们游戏中用了Gamebryo游戏引擎，这个引擎中很多类内部重载了new操作符，并且还有如下的宏定义：</p><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><span style="color: #000000; ">&nbsp;NiNew&nbsp;new(&nbsp;NI_MEMHINT_NONE,&nbsp;__FILE__,&nbsp;__LINE__&nbsp;,&nbsp;__FUNCTION__&nbsp;)</span></div> <p>并且引擎自带的对象都是通过NiNew来创建的，如&nbsp;<span class="Apple-style-span" style="font-size: 13px; background-color: #eeeeee; ">NiNew&nbsp;NiAlphaProperty();</span></p> <p>如果我们把new 宏定义成了new ( _NORMAL_BLOCK, __FILE__, __LINE__ )，那么碰到NiNew  NiAlphaProperty()后，代码就被展开成为</p> <p><span class="Apple-style-span" style="font-size: 13px; background-color: #eeeeee; "><span style="color: #0000FF; ">new</span><span style="color: #000000; ">&nbsp;(&nbsp;_NORMAL_BLOCK,&nbsp;__FILE__,&nbsp;__LINE__&nbsp;)&nbsp;&nbsp;(&nbsp;NI_MEMHINT_NONE,&nbsp;__FILE__,&nbsp;__LINE__&nbsp;,&nbsp;__FUNCTION__&nbsp;)&nbsp;NiAlphaProperty();&nbsp;</span></span>当编译器尝试着用此代码与NiAlphaProperty类内部定义的new操作符去匹配时就抓瞎了，只能报错。</p> <p>目前就只能自己再定义一个宏:</p><div style="font-size: 13px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 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; ">#define</span><span style="color: #000000; ">&nbsp;New&nbsp;&nbsp;&nbsp;::new&nbsp;(&nbsp;_NORMAL_BLOCK,&nbsp;__FILE__,&nbsp;__LINE__&nbsp;)</span></div> <p>将代码中所有的new替换成New。<br /><br /><strong>另一种内存泄漏检测方法就是借用第3方的库</strong>:<br />Visual Leak Detector 是一个不错的泄漏检测库，下载地址：<br /><a href="http://vld.codeplex.com/releases/view/82311">http://vld.codeplex.com/releases/view/82311</a><br />只需要在自己的程序的main函数所在的文件中#include &lt;vld.h&gt;就可以了，使用起来很方便。</p> <p>(注: _CrtSetBreakAlloc()对大型的C++工程不太实用 )</p></div><img src ="http://www.cppblog.com/zgysx/aggbug/197413.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zgysx/" target="_blank">永遇乐</a> 2013-01-19 16:04 <a href="http://www.cppblog.com/zgysx/archive/2013/01/19/197413.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]UML类图关系大全</title><link>http://www.cppblog.com/zgysx/archive/2009/06/13/87587.html</link><dc:creator>永遇乐</dc:creator><author>永遇乐</author><pubDate>Sat, 13 Jun 2009 08:01:00 GMT</pubDate><guid>http://www.cppblog.com/zgysx/archive/2009/06/13/87587.html</guid><wfw:comment>http://www.cppblog.com/zgysx/comments/87587.html</wfw:comment><comments>http://www.cppblog.com/zgysx/archive/2009/06/13/87587.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/zgysx/comments/commentRss/87587.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zgysx/services/trackbacks/87587.html</trackback:ping><description><![CDATA[<span  style="color: rgb(75, 75, 75); font-family: Verdana; font-size: 13px; line-height: 19px; "><div class="postTitle" style="font-size: 14.7px; font-weight: bold; margin-bottom: 10px; "><a id="AjaxHolder_ctl01_TitleUrl" class="postTitle2" href="http://www.cnblogs.com/riky/archive/2007/04/07/704298.html" style="text-decoration: none; color: rgb(26, 139, 200); ">UML类图关系大全</a></div><span style="line-height: 19px; font-size: 10pt; ">1、关联<br><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/dylgsy/doubleAssoc.JPG" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; "><br><br>双向关联：<br>C1-C2：指双方都知道对方的存在，都可以调用对方的公共属性和方法。<br><br>在GOF的设计模式书上是这样描述的：虽然在分析阶段这种关系是适用的，但我们觉得它对于描述设计模式内的类关系来说显得太抽象了，因为在设计阶段关联关系必须被映射为对象引用或指针。对象引用本身就是有向的，更适合表达我们所讨论的那种关系。所以这种关系在设计的时候比较少用到，关联一般都是有向的。<br><br>使用ROSE 生成的代码是这样的：</span><div style="font-size: 10pt; "><div style="font-size: 10pt; "><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">class&nbsp;C1&nbsp;<br><img id="_10_33_Open_Image" onclick="this.style.display='none'; document.getElementById('_10_33_Open_Text').style.display='none'; document.getElementById('_10_33_Closed_Image').style.display='inline'; document.getElementById('_10_33_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; "><img id="_10_33_Closed_Image" onclick="this.style.display='none'; document.getElementById('_10_33_Closed_Text').style.display='none'; document.getElementById('_10_33_Open_Image').style.display='inline'; document.getElementById('_10_33_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">...{<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">public:<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">&nbsp;&nbsp;&nbsp;&nbsp;C2*&nbsp;theC2;<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; "><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">};<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; "><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">class&nbsp;C2&nbsp;<br><img id="_47_70_Open_Image" onclick="this.style.display='none'; document.getElementById('_47_70_Open_Text').style.display='none'; document.getElementById('_47_70_Closed_Image').style.display='inline'; document.getElementById('_47_70_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; "><img id="_47_70_Closed_Image" onclick="this.style.display='none'; document.getElementById('_47_70_Closed_Text').style.display='none'; document.getElementById('_47_70_Open_Image').style.display='inline'; document.getElementById('_47_70_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">...{<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">public:<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">&nbsp;&nbsp;&nbsp;&nbsp;C1*&nbsp;theC1;<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; "><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">};</div></div><p style="line-height: 19px; margin-top: 0px; margin-right: auto; margin-bottom: 10px; margin-left: auto; text-indent: 0px; font-size: 10pt; ">双向关联在代码的表现为双方都拥有对方的一个指针，当然也可以是引用或者是值。<br><br><br><br><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/dylgsy/uniAssoc.JPG" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; "><br><br>单向关联:<br>C3-&gt;C4：表示相识关系，指C3知道C4，C3可以调用C4的公共属性和方法。没有生命期的依赖。一般是表示为一种引用。<br><br>生成代码如下：</p><div style="font-size: 10pt; "><div style="font-size: 10pt; "><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">class&nbsp;C3&nbsp;<br><img id="_10_33_Open_Image" onclick="this.style.display='none'; document.getElementById('_10_33_Open_Text').style.display='none'; document.getElementById('_10_33_Closed_Image').style.display='inline'; document.getElementById('_10_33_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; "><img id="_10_33_Closed_Image" onclick="this.style.display='none'; document.getElementById('_10_33_Closed_Text').style.display='none'; document.getElementById('_10_33_Open_Image').style.display='inline'; document.getElementById('_10_33_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">...{<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">public:<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">&nbsp;&nbsp;&nbsp;&nbsp;C4*&nbsp;theC4;<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; "><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">};<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; "><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">class&nbsp;C4&nbsp;<br><img id="_47_50_Open_Image" onclick="this.style.display='none'; document.getElementById('_47_50_Open_Text').style.display='none'; document.getElementById('_47_50_Closed_Image').style.display='inline'; document.getElementById('_47_50_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; "><img id="_47_50_Closed_Image" onclick="this.style.display='none'; document.getElementById('_47_50_Closed_Text').style.display='none'; document.getElementById('_47_50_Open_Image').style.display='inline'; document.getElementById('_47_50_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">...{<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; "><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">};</div></div><p style="line-height: 19px; margin-top: 0px; margin-right: auto; margin-bottom: 10px; margin-left: auto; text-indent: 0px; font-size: 10pt; ">单向关联的代码就表现为C3有C4的指针，而C4对C3一无所知。<br><br><br></p><p style="line-height: 19px; margin-top: 0px; margin-right: auto; margin-bottom: 10px; margin-left: auto; text-indent: 0px; font-size: 10pt; "><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/dylgsy/selfAssoc.JPG" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; "><br><br>自身关联（反身关联）：<br>自己引用自己，带着一个自己的引用。<br><br>代码如下：</p><div style="font-size: 10pt; "><div style="font-size: 10pt; "><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">class&nbsp;C14&nbsp;<br><img id="_11_36_Open_Image" onclick="this.style.display='none'; document.getElementById('_11_36_Open_Text').style.display='none'; document.getElementById('_11_36_Closed_Image').style.display='inline'; document.getElementById('_11_36_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; "><img id="_11_36_Closed_Image" onclick="this.style.display='none'; document.getElementById('_11_36_Closed_Text').style.display='none'; document.getElementById('_11_36_Open_Image').style.display='inline'; document.getElementById('_11_36_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">...{<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">public:<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">&nbsp;&nbsp;&nbsp;&nbsp;C14*&nbsp;theC14;<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; "><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">};</div></div><p style="line-height: 19px; margin-top: 0px; margin-right: auto; margin-bottom: 10px; margin-left: auto; text-indent: 0px; font-size: 10pt; ">就是在自己的内部有着一个自身的引用。<br><br>2、聚合/组合<br><br>当类之间有整体-部分关系的时候，我们就可以使用组合或者聚合。<br><br><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/dylgsy/Aggregation.JPG" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; "><br><br>聚合：表示C9聚合C10，但是C10可以离开C9而独立存在（独立存在的意思是在某个应用的问题域中这个类的存在有意义。这句话怎么解，请看下面组合里的解释）。<br><br>代码如下：</p><div style="font-size: 10pt; "><div style="font-size: 10pt; "><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">class&nbsp;C9&nbsp;<br><img id="_10_34_Open_Image" onclick="this.style.display='none'; document.getElementById('_10_34_Open_Text').style.display='none'; document.getElementById('_10_34_Closed_Image').style.display='inline'; document.getElementById('_10_34_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; "><img id="_10_34_Closed_Image" onclick="this.style.display='none'; document.getElementById('_10_34_Closed_Text').style.display='none'; document.getElementById('_10_34_Open_Image').style.display='inline'; document.getElementById('_10_34_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">...{<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">public:<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">&nbsp;&nbsp;&nbsp;&nbsp;C10&nbsp;theC10;<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; "><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">};<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; "><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">class&nbsp;C10&nbsp;<br><img id="_49_52_Open_Image" onclick="this.style.display='none'; document.getElementById('_49_52_Open_Text').style.display='none'; document.getElementById('_49_52_Closed_Image').style.display='inline'; document.getElementById('_49_52_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; "><img id="_49_52_Closed_Image" onclick="this.style.display='none'; document.getElementById('_49_52_Closed_Text').style.display='none'; document.getElementById('_49_52_Open_Image').style.display='inline'; document.getElementById('_49_52_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">...{<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; "><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">};<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; "></div></div><p style="line-height: 19px; margin-top: 0px; margin-right: auto; margin-bottom: 10px; margin-left: auto; text-indent: 0px; font-size: 10pt; ">&nbsp;</p><p style="line-height: 19px; margin-top: 0px; margin-right: auto; margin-bottom: 10px; margin-left: auto; text-indent: 0px; font-size: 10pt; "><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/dylgsy/Composition.JPG" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; "><br><br>组合（也有人称为包容）：一般是实心菱形加实线箭头表示，如上图所示，表示的是C8被C7包容，而且C8不能离开C7而独立存在。但这是视问题域而定的，例如在关心汽车的领域里，轮胎是一定要组合在汽车类中的，因为它离开了汽车就没有意义了。但是在卖轮胎的店铺业务里，就算轮胎离开了汽车，它也是有意义的，这就可以用聚合了。在《敏捷开发》中还说到，A组合B，则A需要知道B的生存周期，即可能A负责生成或者释放B，或者A通过某种途径知道B的生成和释放。<br><br>他们的代码如下：</p><div style="font-size: 10pt; "><div style="font-size: 10pt; "><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">class&nbsp;C7&nbsp;<br><img id="_10_32_Open_Image" onclick="this.style.display='none'; document.getElementById('_10_32_Open_Text').style.display='none'; document.getElementById('_10_32_Closed_Image').style.display='inline'; document.getElementById('_10_32_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; "><img id="_10_32_Closed_Image" onclick="this.style.display='none'; document.getElementById('_10_32_Closed_Text').style.display='none'; document.getElementById('_10_32_Open_Image').style.display='inline'; document.getElementById('_10_32_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">...{<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">public:<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">&nbsp;&nbsp;&nbsp;&nbsp;C8&nbsp;theC8;<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; "><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">};<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; "><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">class&nbsp;C8&nbsp;<br><img id="_46_48_Open_Image" onclick="this.style.display='none'; document.getElementById('_46_48_Open_Text').style.display='none'; document.getElementById('_46_48_Closed_Image').style.display='inline'; document.getElementById('_46_48_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; "><img id="_46_48_Closed_Image" onclick="this.style.display='none'; document.getElementById('_46_48_Closed_Text').style.display='none'; document.getElementById('_46_48_Open_Image').style.display='inline'; document.getElementById('_46_48_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">...{<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">};</div></div><p style="line-height: 19px; margin-top: 0px; margin-right: auto; margin-bottom: 10px; margin-left: auto; text-indent: 0px; font-size: 10pt; ">可以看到，代码和聚合是一样的。具体如何区别，可能就只能用语义来区分了。<br><br>3、依赖<br><br><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/dylgsy/Dependancy.JPG" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; "><br><br>依赖:<br>指C5可能要用到C6的一些方法，也可以这样说，要完成C5里的所有功能，一定要有C6的方法协助才行。C5依赖于C6的定义，一般是在C5类的头文件中包含了C6的头文件。ROSE对依赖关系不产生属性。<br><br>注意，要避免双向依赖。一般来说，不应该存在双向依赖。<br><br>ROSE生成的代码如下：<br></p><div style="font-size: 10pt; "><div style="font-size: 10pt; "><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">//&nbsp;C5.h<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">#include&nbsp;"C6.h"<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; "><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">class&nbsp;C5&nbsp;<br><img id="_35_38_Open_Image" onclick="this.style.display='none'; document.getElementById('_35_38_Open_Text').style.display='none'; document.getElementById('_35_38_Closed_Image').style.display='inline'; document.getElementById('_35_38_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; "><img id="_35_38_Closed_Image" onclick="this.style.display='none'; document.getElementById('_35_38_Closed_Text').style.display='none'; document.getElementById('_35_38_Open_Image').style.display='inline'; document.getElementById('_35_38_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">...{<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; "><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">};<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; "><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">//&nbsp;C6.h<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">#include&nbsp;"C5.h"<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; "><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">class&nbsp;C6<br><img id="_76_79_Open_Image" onclick="this.style.display='none'; document.getElementById('_76_79_Open_Text').style.display='none'; document.getElementById('_76_79_Closed_Image').style.display='inline'; document.getElementById('_76_79_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; "><img id="_76_79_Closed_Image" onclick="this.style.display='none'; document.getElementById('_76_79_Closed_Text').style.display='none'; document.getElementById('_76_79_Open_Image').style.display='inline'; document.getElementById('_76_79_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">...{<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; "><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">};<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; "></div></div><p style="line-height: 19px; margin-top: 0px; margin-right: auto; margin-bottom: 10px; margin-left: auto; text-indent: 0px; font-size: 10pt; ">虽然ROSE不生成属性，但在形式上一般是A中的某个方法把B的对象作为参数使用(假设A依赖于B)。如下：</p><div style="font-size: 10pt; "><div style="font-size: 10pt; "><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">#include&nbsp;"B.h"<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">class&nbsp;A<br><img id="_23_52_Open_Image" onclick="this.style.display='none'; document.getElementById('_23_52_Open_Text').style.display='none'; document.getElementById('_23_52_Closed_Image').style.display='inline'; document.getElementById('_23_52_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; "><img id="_23_52_Closed_Image" onclick="this.style.display='none'; document.getElementById('_23_52_Closed_Text').style.display='none'; document.getElementById('_23_52_Open_Image').style.display='inline'; document.getElementById('_23_52_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">...{<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;void&nbsp;Func(B&nbsp;&amp;b);<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">}</div></div><p style="line-height: 19px; margin-top: 0px; margin-right: auto; margin-bottom: 10px; margin-left: auto; text-indent: 0px; font-size: 10pt; ">那依赖和聚合\组合、关联等有什么不同呢？<br><br>关联是类之间的一种关系，例如老师教学生，老公和老婆，水壶装水等就是一种关系。这种关系是非常明显的，在问题领域中通过分析直接就能得出。<br><br>依赖是一种弱关联，只要一个类用到另一个类，但是和另一个类的关系不是太明显的时候（可以说是&#8220;uses&#8221;了那个类），就可以把这种关系看成是依赖，依赖也可说是一种偶然的关系，而不是必然的关系，就是&#8220;我在某个方法中偶然用到了它，但在现实中我和它并没多大关系&#8221;。例如我和锤子，我和锤子本来是没关系的，但在有一次要钉钉子的时候，我用到了它，这就是一种依赖，依赖锤子完成钉钉子这件事情。</p><p style="line-height: 19px; margin-top: 0px; margin-right: auto; margin-bottom: 10px; margin-left: auto; text-indent: 0px; font-size: 10pt; ">组合是一种整体-部分的关系，在问题域中这种关系很明显，直接分析就可以得出的。例如轮胎是车的一部分，树叶是树的一部分，手脚是身体的一部分这种的关系，非常明显的整体-部分关系。<br><br>上述的几种关系（关联、聚合/组合、依赖）在代码中可能以指针、引用、值等的方式在另一个类中出现，不拘于形式，但在逻辑上他们就有以上的区别。<br><br>这里还要说明一下，所谓的这些关系只是在某个问题域才有效，离开了这个问题域，可能这些关系就不成立了，例如可能在某个问题域中，我是一个木匠，需要拿着锤子去干活，可能整个问题的描述就是我拿着锤子怎么钉桌子，钉椅子，钉柜子；既然整个问题就是描述这个，我和锤子就不仅是偶然的依赖关系了，我和锤子的关系变得非常的紧密，可能就上升为组合关系（让我突然想起武侠小说的剑不离身，剑亡人亡...）。这个例子可能有点荒谬，但也是为了说明一个道理，就是关系和类一样，它们都是在一个问题领域中才成立的，离开了这个问题域，他们可能就不复存在了。<br><br><br>4、泛化（继承）<br><br><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/dylgsy/inheri.jpg" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; "><br><br>泛化关系：如果两个类存在泛化的关系时就使用，例如父和子，动物和老虎，植物和花等。<br>ROSE生成的代码很简单，如下：</p><div style="font-size: 10pt; "><div style="font-size: 10pt; "><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">#include&nbsp;"C11.h"<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; "><br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">class&nbsp;C12&nbsp;:&nbsp;public&nbsp;C11<br><img id="_41_43_Open_Image" onclick="this.style.display='none'; document.getElementById('_41_43_Open_Text').style.display='none'; document.getElementById('_41_43_Closed_Image').style.display='inline'; document.getElementById('_41_43_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; "><img id="_41_43_Closed_Image" onclick="this.style.display='none'; document.getElementById('_41_43_Closed_Text').style.display='none'; document.getElementById('_41_43_Open_Image').style.display='inline'; document.getElementById('_41_43_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">...{<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">};</div></div><p style="line-height: 19px; margin-top: 0px; margin-right: auto; margin-bottom: 10px; margin-left: auto; text-indent: 0px; font-size: 10pt; "><br>5、这里顺便提一下模板<br><br><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/dylgsy/Template.jpg" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; "><br><br>上面的图对应的代码如下：</p><div style="font-size: 10pt; "><div style="font-size: 10pt; "><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">template&lt;int&gt;<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">class&nbsp;C13&nbsp;<br><img id="_25_27_Open_Image" onclick="this.style.display='none'; document.getElementById('_25_27_Open_Text').style.display='none'; document.getElementById('_25_27_Closed_Image').style.display='inline'; document.getElementById('_25_27_Closed_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; "><img id="_25_27_Closed_Image" onclick="this.style.display='none'; document.getElementById('_25_27_Closed_Text').style.display='none'; document.getElementById('_25_27_Open_Image').style.display='inline'; document.getElementById('_25_27_Open_Text').style.display='inline';" alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">...{<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; ">};<br><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; "></div></div><p style="line-height: 19px; margin-top: 0px; margin-right: auto; margin-bottom: 10px; margin-left: auto; text-indent: 0px; font-size: 10pt; ">这里再说一下重复度，其实看完了上面的描述之后，我们应该清楚了各个关系间的关系以及具体对应到代码是怎么样的，所谓的重复度，也只不过是上面的扩展，例如A和B有着&#8220;1对多&#8221;的重复度，那在A中就有一个列表，保存着B对象的N个引用，就是这样而已。<br><br>好了，到这里，已经把上面的类图关系说完了，希望你能有所收获了，我也费了不少工夫啊（画图、生成代码、截图、写到BLOG上，唉，一头大汗）。不过如果能让你彻底理解UML类图的这些关系，也值得了。:)<br><br><br></p></span>
<img src ="http://www.cppblog.com/zgysx/aggbug/87587.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zgysx/" target="_blank">永遇乐</a> 2009-06-13 16:01 <a href="http://www.cppblog.com/zgysx/archive/2009/06/13/87587.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>解析IP</title><link>http://www.cppblog.com/zgysx/archive/2008/08/14/58858.html</link><dc:creator>永遇乐</dc:creator><author>永遇乐</author><pubDate>Thu, 14 Aug 2008 09:52:00 GMT</pubDate><guid>http://www.cppblog.com/zgysx/archive/2008/08/14/58858.html</guid><wfw:comment>http://www.cppblog.com/zgysx/comments/58858.html</wfw:comment><comments>http://www.cppblog.com/zgysx/archive/2008/08/14/58858.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zgysx/comments/commentRss/58858.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zgysx/services/trackbacks/58858.html</trackback:ping><description><![CDATA[<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #008080;">&nbsp;1</span>&nbsp;<span style="color: #008000;">//</span><span style="color: #008000;">析取IP地址，如果说是合法的IP则返回true,否则返回&nbsp;false</span><span style="color: #008000;"><br></span><span style="color: #008080;">&nbsp;2</span>&nbsp;<span style="color: #008000;"></span><span style="color: #0000ff;">bool</span><span style="color: #000000;"> GetProxyIP(&nbsp;std::wstring</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;strIP&nbsp;)<br></span><span style="color: #008080;">&nbsp;3</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">&nbsp;4</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;strIP.clear();<br></span><span style="color: #008080;">&nbsp;5</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;LPCWSTR&nbsp;pszIP&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;GetEditBoxText(&nbsp;IDC_DLG_LOGIN_SETTING_EDIT_ADDRESS&nbsp;);<br></span><span style="color: #008080;">&nbsp;6</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(&nbsp;pszIP&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;NULL&nbsp;</span><span style="color: #000000;">||</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">!</span><span style="color: #000000;">wcscmp(&nbsp;pszIP,&nbsp;TEXT(</span><span style="color: #000000;">""</span><span style="color: #000000;">)&nbsp;)&nbsp;)<br></span><span style="color: #008080;">&nbsp;7</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">false</span><span style="color: #000000;">;<br></span><span style="color: #008080;">&nbsp;8</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;9</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;std::wstring&nbsp;strTemp&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;pszIP;<br></span><span style="color: #008080;">10</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;std::wstring::size_type&nbsp;nPos1,&nbsp;nPos2;<br></span><span style="color: #008080;">11</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;nPos1&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;nPos2&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br></span><span style="color: #008080;">12</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;nIP[</span><span style="color: #000000;">4</span><span style="color: #000000;">]&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;{</span><span style="color: #000000;">0</span><span style="color: #000000;">};<br></span><span style="color: #008080;">13</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;std::wstring::size_type&nbsp;i&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br></span><span style="color: #008080;">14</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">(&nbsp;;&nbsp;(i&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">4</span><span style="color: #000000;">)&nbsp;</span><span style="color: #000000;">&amp;&amp;</span><span style="color: #000000;">&nbsp;(nPos2&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;std::wstring::npos&nbsp;);&nbsp;</span><span style="color: #000000;">++</span><span style="color: #000000;">i&nbsp;)<br></span><span style="color: #008080;">15</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="color: #008080;">16</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(&nbsp;nPos2&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">&nbsp;)<br></span><span style="color: #008080;">17</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nPos1&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;nPos2;<br></span><span style="color: #008080;">18</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;"><br></span><span style="color: #008080;">19</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nPos1&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;nPos2&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">;<br></span><span style="color: #008080;">20</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">21</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nPos2&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;strTemp.find(&nbsp;TEXT(</span><span style="color: #000000;">'</span><span style="color: #000000;">.</span><span style="color: #000000;">'</span><span style="color: #000000;">),&nbsp;nPos1);<br></span><span style="color: #008080;">22</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::wstring::size_type&nbsp;nCount&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;std::wstring::npos;<br></span><span style="color: #008080;">23</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(&nbsp;nPos2&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;std::wstring::npos&nbsp;)<br></span><span style="color: #008080;">24</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nCount&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;nPos2&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;nPos1;<br></span><span style="color: #008080;">25</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">26</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::wstring&nbsp;strSub&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;strTemp.substr(nPos1,&nbsp;nCount);<br></span><span style="color: #008080;">27</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(&nbsp;strSub&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;TEXT(</span><span style="color: #000000;">""</span><span style="color: #000000;">)&nbsp;)<br></span><span style="color: #008080;">28</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">false</span><span style="color: #000000;">;<br></span><span style="color: #008080;">29</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">30</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;nValue&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;_wtoi(&nbsp;strSub.c_str()&nbsp;);<br></span><span style="color: #008080;">31</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(&nbsp;nValue&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">||</span><span style="color: #000000;">&nbsp;nValue&nbsp;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">255</span><span style="color: #000000;">&nbsp;)<br></span><span style="color: #008080;">32</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">false</span><span style="color: #000000;">;<br></span><span style="color: #008080;">33</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nIP[i]&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;nValue;<br></span><span style="color: #008080;">34</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="color: #008080;">35</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">36</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(&nbsp;i&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">4</span><span style="color: #000000;">&nbsp;)<br></span><span style="color: #008080;">37</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">false</span><span style="color: #000000;">;<br></span><span style="color: #008080;">38</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;wchar_t&nbsp;szIP[</span><span style="color: #000000;">100</span><span style="color: #000000;">]&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;{</span><span style="color: #000000;">0</span><span style="color: #000000;">};<br></span><span style="color: #008080;">39</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;wsprintf(&nbsp;szIP,&nbsp;TEXT(</span><span style="color: #000000;">"</span><span style="color: #000000;">%d.%d.%d.%d</span><span style="color: #000000;">"</span><span style="color: #000000;">),&nbsp;nIP[</span><span style="color: #000000;">0</span><span style="color: #000000;">],&nbsp;nIP[</span><span style="color: #000000;">1</span><span style="color: #000000;">],&nbsp;nIP[</span><span style="color: #000000;">2</span><span style="color: #000000;">],&nbsp;nIP[</span><span style="color: #000000;">3</span><span style="color: #000000;">]&nbsp;);<br></span><span style="color: #008080;">40</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;strIP&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;szIP;<br></span><span style="color: #008080;">41</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">true</span><span style="color: #000000;">;<br></span><span style="color: #008080;">42</span>&nbsp;<span style="color: #000000;">}</span></div>
<br><img src ="http://www.cppblog.com/zgysx/aggbug/58858.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zgysx/" target="_blank">永遇乐</a> 2008-08-14 17:52 <a href="http://www.cppblog.com/zgysx/archive/2008/08/14/58858.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于fscanf读取文件的问题</title><link>http://www.cppblog.com/zgysx/archive/2008/07/28/57354.html</link><dc:creator>永遇乐</dc:creator><author>永遇乐</author><pubDate>Mon, 28 Jul 2008 07:29:00 GMT</pubDate><guid>http://www.cppblog.com/zgysx/archive/2008/07/28/57354.html</guid><wfw:comment>http://www.cppblog.com/zgysx/comments/57354.html</wfw:comment><comments>http://www.cppblog.com/zgysx/archive/2008/07/28/57354.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zgysx/comments/commentRss/57354.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zgysx/services/trackbacks/57354.html</trackback:ping><description><![CDATA[<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">比如读取以以下格式存放在文件中的字符串,可采用fscanf<br><br></span><span style="color: #000000;">1000</span><span style="color: #000000;">,小明,团员,湖北武昌XXXX<br></span><span style="color: #000000;">1001</span><span style="color: #000000;">,张华,党员,湖北宜昌XXXX<br><img src="http://www.cppblog.com/Images/dot.gif"><img src="http://www.cppblog.com/Images/dot.gif"><img src="http://www.cppblog.com/Images/dot.gif"><img src="http://www.cppblog.com/Images/dot.gif"><img src="http://www.cppblog.com/Images/dot.gif"><img src="http://www.cppblog.com/Images/dot.gif"><img src="http://www.cppblog.com/Images/dot.gif"><img src="http://www.cppblog.com/Images/dot.gif"><img src="http://www.cppblog.com/Images/dot.gif">.<br><br><br>FILE&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;fp&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;fopen(&nbsp;pszFilePath,&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">r</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br></span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;n&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">;<br></span><span style="color: #0000ff;">while</span><span style="color: #000000;">(&nbsp;n&nbsp;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&amp;&amp;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">!</span><span style="color: #000000;">feof(&nbsp;fp&nbsp;)&nbsp;)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;nID;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">&nbsp;szName[</span><span style="color: #000000;">100</span><span style="color: #000000;">]&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;{</span><span style="color: #000000;">0</span><span style="color: #000000;">};<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">&nbsp;szBelong[</span><span style="color: #000000;">100</span><span style="color: #000000;">]&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;{</span><span style="color: #000000;">0</span><span style="color: #000000;">};<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">&nbsp;szAddress[</span><span style="color: #000000;">300</span><span style="color: #000000;">]&nbsp;&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;{</span><span style="color: #000000;">0</span><span style="color: #000000;">};<br>&nbsp;&nbsp;&nbsp;&nbsp;n&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;fscanf(&nbsp;fp,&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">%d,%[^','],%[^','],%s\r\n</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">nID,&nbsp;szName,&nbsp;szBelong,&nbsp;szAddress);<br></span><span style="color: #008000;">//</span><span style="color: #008000;"><img src="http://www.cppblog.com/Images/dot.gif"><img src="http://www.cppblog.com/Images/dot.gif"><img src="http://www.cppblog.com/Images/dot.gif"><img src="http://www.cppblog.com/Images/dot.gif"><img src="http://www.cppblog.com/Images/dot.gif"><img src="http://www.cppblog.com/Images/dot.gif"><img src="http://www.cppblog.com/Images/dot.gif"><img src="http://www.cppblog.com/Images/dot.gif">.</span><span style="color: #008000;"><br></span><span style="color: #000000;">}</span></div>
<br><br><img src ="http://www.cppblog.com/zgysx/aggbug/57354.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zgysx/" target="_blank">永遇乐</a> 2008-07-28 15:29 <a href="http://www.cppblog.com/zgysx/archive/2008/07/28/57354.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>异常处理</title><link>http://www.cppblog.com/zgysx/archive/2008/07/23/56926.html</link><dc:creator>永遇乐</dc:creator><author>永遇乐</author><pubDate>Wed, 23 Jul 2008 05:07:00 GMT</pubDate><guid>http://www.cppblog.com/zgysx/archive/2008/07/23/56926.html</guid><wfw:comment>http://www.cppblog.com/zgysx/comments/56926.html</wfw:comment><comments>http://www.cppblog.com/zgysx/archive/2008/07/23/56926.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zgysx/comments/commentRss/56926.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zgysx/services/trackbacks/56926.html</trackback:ping><description><![CDATA[<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">string</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br><br>#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">stdio.h</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br>#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">windows.h</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br>#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">dbghelp.h</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br><br>#pragma&nbsp;comment(lib,&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">Dbghelp.lib</span><span style="color: #000000;">"</span><span style="color: #000000;">)<br><br></span><span style="color: #0000ff;">#define</span><span style="color: #000000;">&nbsp;_INNER_TEST&nbsp;1</span><span style="color: #000000;"><br><br></span><span style="color: #0000ff;">#if</span><span style="color: #000000;">&nbsp;_DEBUG&nbsp;&amp;&nbsp;!defined(&nbsp;_INNER_TEST&nbsp;)</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">#define</span><span style="color: #000000;">&nbsp;GS_EXCEPTION_BEGIN()</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">#define</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;GS_EXCEPTION_END()</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">#else</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">#define</span><span style="color: #000000;">&nbsp;EXCEPTION_BEGIN()&nbsp;__try&nbsp;{</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">#define</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;EXCEPTION_END()&nbsp;}&nbsp;__except(&nbsp;MyUnhandledFilter(&nbsp;GetExceptionInformation()&nbsp;)&nbsp;)&nbsp;{}</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">#endif</span><span style="color: #000000;"><br><br><br><br><br>LONG&nbsp;WINAPI&nbsp;MyUnhandledFilter(</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;_EXCEPTION_POINTERS&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;lpExceptionInfo)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;LONG&nbsp;ret&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;EXCEPTION_EXECUTE_HANDLER;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;TCHAR&nbsp;szFileName[</span><span style="color: #000000;">64</span><span style="color: #000000;">];<br>&nbsp;&nbsp;&nbsp;&nbsp;SYSTEMTIME&nbsp;st;<br>&nbsp;&nbsp;&nbsp;&nbsp;::GetLocalTime(</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">st);<br>&nbsp;&nbsp;&nbsp;&nbsp;wsprintf(szFileName,&nbsp;TEXT(</span><span style="color: #000000;">"</span><span style="color: #000000;">%04d-%02d-%02d-%02d-%02d-%02d-%02d-%02d.dmp</span><span style="color: #000000;">"</span><span style="color: #000000;">),&nbsp;st.wYear,&nbsp;st.wMonth,&nbsp;st.wDay,&nbsp;st.wHour,&nbsp;st.wMinute,&nbsp;st.wSecond,&nbsp;st.wMilliseconds,&nbsp;</span><span style="color: #008000;">/*</span><span style="color: #008000;">rand()</span><span style="color: #008000;">*/</span><span style="color: #000000;">100</span><span style="color: #000000;">);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;HANDLE&nbsp;hFile&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;::CreateFile(szFileName,&nbsp;GENERIC_WRITE,&nbsp;FILE_SHARE_WRITE,&nbsp;NULL,&nbsp;CREATE_ALWAYS,&nbsp;FILE_ATTRIBUTE_NORMAL,&nbsp;NULL&nbsp;);<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(hFile&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;INVALID_HANDLE_VALUE)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MINIDUMP_EXCEPTION_INFORMATION&nbsp;ExInfo;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ExInfo.ThreadId&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;::GetCurrentThreadId();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ExInfo.ExceptionPointers&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;lpExceptionInfo;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ExInfo.ClientPointers&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">false</span><span style="color: #000000;">;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BOOL&nbsp;bOK&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;MiniDumpWriteDump(GetCurrentProcess(),&nbsp;GetCurrentProcessId(),&nbsp;hFile,&nbsp;MiniDumpNormal,&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">ExInfo,&nbsp;NULL,&nbsp;NULL&nbsp;);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(bOK)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000;">"</span><span style="color: #000000;">Create&nbsp;Dump&nbsp;File&nbsp;Success!\n</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000;">"</span><span style="color: #000000;">MiniDumpWriteDump&nbsp;Failed:&nbsp;%d\n</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;GetLastError());<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;::CloseHandle(hFile);<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000;">"</span><span style="color: #000000;">Create&nbsp;File&nbsp;%s&nbsp;Failed&nbsp;%d\n</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;szFileName,&nbsp;GetLastError());<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;std::</span><span style="color: #0000ff;">string</span><span style="color: #000000;">&nbsp;strTip;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">switch</span><span style="color: #000000;">(&nbsp;lpExceptionInfo</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">ExceptionRecord</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">ExceptionCode&nbsp;)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">case</span><span style="color: #000000;">&nbsp;STATUS_ACCESS_VIOLATION:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">&nbsp;sz[</span><span style="color: #000000;">200</span><span style="color: #000000;">]&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;{</span><span style="color: #000000;">0</span><span style="color: #000000;">};<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sprintf(&nbsp;sz,&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">内存访问冲突&nbsp;Access&nbsp;violation,&nbsp;Attempt&nbsp;to&nbsp;%s&nbsp;data&nbsp;at&nbsp;address&nbsp;%p</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;&nbsp;lpExceptionInfo</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">ExceptionRecord</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">ExceptionInformation[</span><span style="color: #000000;">0</span><span style="color: #000000;">]&nbsp;</span><span style="color: #000000;">?</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">write</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;:&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">read</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;lpExceptionInfo</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">ExceptionRecord</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">ExceptionInformation[</span><span style="color: #000000;">1</span><span style="color: #000000;">]);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strTip&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;sz;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">break</span><span style="color: #000000;">;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">case</span><span style="color: #000000;">&nbsp;STATUS_BREAKPOINT:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strTip&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">用户断点&nbsp;Breakpoint</span><span style="color: #000000;">"</span><span style="color: #000000;">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">break</span><span style="color: #000000;">;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">case</span><span style="color: #000000;">&nbsp;STATUS_DATATYPE_MISALIGNMENT:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strTip&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">内存地址对齐错误&nbsp;Address&nbsp;misaligned</span><span style="color: #000000;">"</span><span style="color: #000000;">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">break</span><span style="color: #000000;">;<br>#ifdef&nbsp;STATUS_FLOATING_DIVIDE_BY_ZERO<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">case</span><span style="color: #000000;">&nbsp;STATUS_FLOATING_DIVIDE_BY_ZERO:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strTip&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;L</span><span style="color: #000000;">"</span><span style="color: #000000;">浮点数除数为0&nbsp;Floating&nbsp;point&nbsp;divide&nbsp;by&nbsp;0</span><span style="color: #000000;">"</span><span style="color: #000000;">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">break</span><span style="color: #000000;">;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">case</span><span style="color: #000000;">&nbsp;STATUS_FLOATING_OVERFLOW:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strTip&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;L</span><span style="color: #000000;">"</span><span style="color: #000000;">浮点数溢出&nbsp;Floating&nbsp;point&nbsp;overflow</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">break</span><span style="color: #000000;">;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">case</span><span style="color: #000000;">&nbsp;STATUS_FLOATING_UNDERFLOW:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strTip&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;L</span><span style="color: #000000;">"</span><span style="color: #000000;">浮点数溢出&nbsp;Floating&nbsp;point&nbsp;underflow</span><span style="color: #000000;">"</span><span style="color: #000000;">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">break</span><span style="color: #000000;">;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">case</span><span style="color: #000000;">&nbsp;STATUS_FLOATING_RESEVERED_OPERAND:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strTip&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;L</span><span style="color: #000000;">"</span><span style="color: #000000;">保留的浮点数格式&nbsp;Reserved&nbsp;Floating&nbsp;point&nbsp;format</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">break</span><span style="color: #000000;">;<br></span><span style="color: #0000ff;">#endif</span><span style="color: #000000;"><br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">case</span><span style="color: #000000;">&nbsp;STATUS_ILLEGAL_INSTRUCTION:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strTip&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">非法指令&nbsp;Illegal&nbsp;instruction</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">break</span><span style="color: #000000;">;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">case</span><span style="color: #000000;">&nbsp;STATUS_PRIVILEGED_INSTRUCTION:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strTip&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">特权指令&nbsp;Priviledged&nbsp;instruction</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">break</span><span style="color: #000000;">;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">case</span><span style="color: #000000;">&nbsp;STATUS_INTEGER_DIVIDE_BY_ZERO:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strTip&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">0除数错误&nbsp;Integer&nbsp;divide&nbsp;by&nbsp;0</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">break</span><span style="color: #000000;">;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">case</span><span style="color: #000000;">&nbsp;STATUS_INTEGER_OVERFLOW:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strTip&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">整数溢出&nbsp;Integer&nbsp;overflow</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">break</span><span style="color: #000000;">;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">case</span><span style="color: #000000;">&nbsp;STATUS_SINGLE_STEP:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strTip&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">单步执行&nbsp;Single&nbsp;step</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">break</span><span style="color: #000000;">;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">default</span><span style="color: #000000;">:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strTip&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">未定义错误&nbsp;Undefined&nbsp;error.</span><span style="color: #000000;">"</span><span style="color: #000000;">;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;printf(&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">发生错误的位置是&nbsp;%p&nbsp;\n&nbsp;%s\n</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;lpExceptionInfo</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">ExceptionRecord</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">ExceptionAddress,&nbsp;strTip.c_str()&nbsp;);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;ret;<br>}<br><br><br></span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;_tmain(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;argc,&nbsp;_TCHAR</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;argv[])<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">::SetUnhandledExceptionFilter(MyUnhandledFilter);</span><span style="color: #008000;"><br></span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;EXCEPTION_BEGIN()<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;a&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;b&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">2</span><span style="color: #000000;">;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">int&nbsp;c&nbsp;=&nbsp;b/a;</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;p&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">)</span><span style="color: #000000;">1</span><span style="color: #000000;">;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">p&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">2</span><span style="color: #000000;">;<br>&nbsp;&nbsp;&nbsp;&nbsp;strcpy(&nbsp;NULL,&nbsp;NULL&nbsp;);<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;EXCEPTION_END()<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br>}</span></div>
<br><img src ="http://www.cppblog.com/zgysx/aggbug/56926.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zgysx/" target="_blank">永遇乐</a> 2008-07-23 13:07 <a href="http://www.cppblog.com/zgysx/archive/2008/07/23/56926.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]C++反汇编揭秘1 一个简单的C++程序反汇编解析</title><link>http://www.cppblog.com/zgysx/archive/2008/07/17/56382.html</link><dc:creator>永遇乐</dc:creator><author>永遇乐</author><pubDate>Thu, 17 Jul 2008 02:15:00 GMT</pubDate><guid>http://www.cppblog.com/zgysx/archive/2008/07/17/56382.html</guid><wfw:comment>http://www.cppblog.com/zgysx/comments/56382.html</wfw:comment><comments>http://www.cppblog.com/zgysx/archive/2008/07/17/56382.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/zgysx/comments/commentRss/56382.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zgysx/services/trackbacks/56382.html</trackback:ping><description><![CDATA[<p>本系列主要从汇编角度研究C++语言机制和汇编的对应关系。第一篇自然应该从最简单的开始。C++的源代码如下：</p>
<p>
<table style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; BACKGROUND: rgb(219,229,241) 0% 50%; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none; BORDER-COLLAPSE: collapse; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial" cellSpacing=0 cellPadding=0 border=1>
    <tbody>
        <tr>
            <td style="BORDER-RIGHT: black 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: black 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0in; BORDER-LEFT: black 1pt solid; WIDTH: 7.65in; PADDING-TOP: 0in; BORDER-BOTTOM: black 1pt solid" vAlign=top width=734>
            <div style="MARGIN-BOTTOM: 0pt">class my_class</div>
            <div style="MARGIN-BOTTOM: 0pt">{</div>
            <div style="MARGIN-BOTTOM: 0pt">public :</div>
            <div style="MARGIN-BOTTOM: 0pt"><span>&nbsp;&nbsp;&nbsp; my_class()</span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span>&nbsp;&nbsp;&nbsp; {</span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_member = 1;</span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span>&nbsp;&nbsp;&nbsp; }</span></div>
            <div style="MARGIN-BOTTOM: 0pt">&nbsp;</div>
            <div style="MARGIN-BOTTOM: 0pt"><span>&nbsp;&nbsp;&nbsp; void method(int n)</span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span>&nbsp;&nbsp;&nbsp; {</span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_member = n;</span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span>&nbsp;&nbsp;&nbsp; }</span></div>
            <div style="MARGIN-BOTTOM: 0pt">&nbsp;</div>
            <div style="MARGIN-BOTTOM: 0pt"><span>&nbsp;&nbsp;&nbsp; ~my_class()</span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span>&nbsp;&nbsp;&nbsp; {</span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_member = 0;</span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span>&nbsp;&nbsp; &nbsp;}</span></div>
            <div style="MARGIN-BOTTOM: 0pt">&nbsp;</div>
            <div style="MARGIN-BOTTOM: 0pt">private :</div>
            <div style="MARGIN-BOTTOM: 0pt"><span>&nbsp;&nbsp;&nbsp; int m_member;</span></div>
            <div style="MARGIN-BOTTOM: 0pt">};</div>
            <div style="MARGIN-BOTTOM: 0pt">&nbsp;</div>
            <div style="MARGIN-BOTTOM: 0pt">int _tmain(int argc, _TCHAR* argv[])</div>
            <div style="MARGIN-BOTTOM: 0pt">{</div>
            <div style="MARGIN-BOTTOM: 0pt"><span>&nbsp;&nbsp;&nbsp; my_class a_class;</span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span>&nbsp;&nbsp;&nbsp; a_class.method(10);</span></div>
            <div style="MARGIN-BOTTOM: 0pt">&nbsp;</div>
            <div style="MARGIN-BOTTOM: 0pt"><span>&nbsp;&nbsp;&nbsp; return 0;</span></div>
            <div style="MARGIN-BOTTOM: 0pt">}</div>
            </td>
        </tr>
    </tbody>
</table>
</p>
<div>&nbsp;</div>
<div>可以直接Debug的时候看到Assembly代码，不过这样获得的代码注释比较少。比较理想的方法是利用VC编译器的一个选项/FAs来生成对应的汇编代码。/FAs还会在汇编代码中加入注释注明和C++代码的对应关系，十分有助于分析。Build代码便可以在输出目录下发现对应的.ASM文件。本文将逐句分析汇编代码和C++的对应关系。</div>
<div>首先是WinMain：</div>
<p>
<table style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; BACKGROUND: rgb(219,229,241) 0% 50%; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none; BORDER-COLLAPSE: collapse; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial" cellSpacing=0 cellPadding=0 border=1>
    <tbody>
        <tr>
            <td style="BORDER-RIGHT: black 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: black 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0in; BORDER-LEFT: black 1pt solid; WIDTH: 7.65in; PADDING-TOP: 0in; BORDER-BOTTOM: black 1pt solid" vAlign=top width=734>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New">_TEXT<span> SEGMENT</span></font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New">_wmain<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PROC</span></font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push&nbsp;ebp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; </span>保存旧的ebp</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; ebp, esp&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; ebp</span>保存当前栈的位置</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push&nbsp;-1&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; </span>建立SEH(Structured Exception Handler)链</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; -1</span>表示表头,没有Prev</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push&nbsp;__ehhandler$_wmain&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; SEH</span>异常处理程序的地址</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; eax, DWORD PTR fs:0&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; fs:0</span>指向TEB的内容，头4个字节是当前SEH链的地址</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push&nbsp;eax&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; </span>保存起来</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sub&nbsp;&nbsp; esp, d8H&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; </span>分配d8H字节的空间</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push&nbsp;ebx</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push&nbsp;esi</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push&nbsp;edi</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lea&nbsp;&nbsp; edi, DWORD PTR [ebp-e4H]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; e4H = d8H + 4 * 3</span>，跳过中间ebx, esi, edi</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; ecx, 36H&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; 36H*4H=d8H</span>，也就是用36H个ccccccccH填满刚才分配的d8H字节空间</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; eax, ccccccccH</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rep stosd</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; eax, DWORD PTR ___security_cookie&nbsp;&nbsp; </font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xor&nbsp;&nbsp; eax, ebp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push&nbsp;eax&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; ebp ^ __security_cookie</span>压栈保存</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lea&nbsp;&nbsp; eax, DWORD PTR [ebp-0cH]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; ebp-0cH</span>是新的SEH链的结构地址（刚压入栈中的栈地址）</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; DWORD PTR fs:0, eax&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; </span>设置到TEB中作为当前Active的SEH链表末尾</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New">&nbsp;</font></div>
            </td>
        </tr>
    </tbody>
</table>
</p>
<div>&nbsp;</div>
<div>到此为止栈的内容是这样的：</div>
<div>低地址</div>
<p>
<table style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; BACKGROUND: rgb(219,229,241) 0% 50%; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none; BORDER-COLLAPSE: collapse; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial" cellSpacing=0 cellPadding=0 border=1>
    <tbody>
        <tr>
            <td style="BORDER-RIGHT: black 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: black 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0in; BORDER-LEFT: black 1pt solid; WIDTH: 161.6pt; PADDING-TOP: 0in; BORDER-BOTTOM: black 1pt solid" vAlign=top width=215>
            <div style="MARGIN-BOTTOM: 0pt">Security cookie after XOR</div>
            </td>
        </tr>
        <tr>
            <td style="BORDER-RIGHT: 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: medium none; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0in; BORDER-LEFT: 1pt solid; WIDTH: 161.6pt; PADDING-TOP: 0in; BORDER-BOTTOM: 1pt solid" vAlign=top width=215>
            <div style="MARGIN-BOTTOM: 0pt">Edi</div>
            </td>
        </tr>
        <tr>
            <td style="BORDER-RIGHT: 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: medium none; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0in; BORDER-LEFT: 1pt solid; WIDTH: 161.6pt; PADDING-TOP: 0in; BORDER-BOTTOM: 1pt solid" vAlign=top width=215>
            <div style="MARGIN-BOTTOM: 0pt">Esi</div>
            </td>
        </tr>
        <tr>
            <td style="BORDER-RIGHT: 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: medium none; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0in; BORDER-LEFT: 1pt solid; WIDTH: 161.6pt; PADDING-TOP: 0in; BORDER-BOTTOM: 1pt solid" vAlign=top width=215>
            <div style="MARGIN-BOTTOM: 0pt">Ebx</div>
            </td>
        </tr>
        <tr>
            <td style="BORDER-RIGHT: 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: medium none; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0in; BORDER-LEFT: 1pt solid; WIDTH: 161.6pt; PADDING-TOP: 0in; BORDER-BOTTOM: 1pt solid" vAlign=top width=215>
            <div style="MARGIN-BOTTOM: 0pt">Local stack: d8H</div>
            </td>
        </tr>
        <tr>
            <td style="BORDER-RIGHT: 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: medium none; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0in; BORDER-LEFT: 1pt solid; WIDTH: 161.6pt; PADDING-TOP: 0in; BORDER-BOTTOM: 1pt solid" vAlign=top width=215>
            <div style="MARGIN-BOTTOM: 0pt">Old fs:0</div>
            </td>
        </tr>
        <tr>
            <td style="BORDER-RIGHT: 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: medium none; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0in; BORDER-LEFT: 1pt solid; WIDTH: 161.6pt; PADDING-TOP: 0in; BORDER-BOTTOM: 1pt solid" vAlign=top width=215>
            <div style="MARGIN-BOTTOM: 0pt">__ehhandler$_wmain</div>
            </td>
        </tr>
        <tr>
            <td style="BORDER-RIGHT: 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: medium none; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0in; BORDER-LEFT: 1pt solid; WIDTH: 161.6pt; PADDING-TOP: 0in; BORDER-BOTTOM: 1pt solid" vAlign=top width=215>
            <div style="MARGIN-BOTTOM: 0pt">ffffffffH</div>
            </td>
        </tr>
        <tr>
            <td style="BORDER-RIGHT: 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: medium none; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0in; BORDER-LEFT: 1pt solid; WIDTH: 161.6pt; PADDING-TOP: 0in; BORDER-BOTTOM: 1pt solid" vAlign=top width=215>
            <div style="MARGIN-BOTTOM: 0pt">Old ebp</div>
            </td>
        </tr>
    </tbody>
</table>
</p>
<div>&nbsp;高地址</div>
<div>main接着后面调用my_class的构造函数</div>
<p>
<table style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; BACKGROUND: rgb(219,229,241) 0% 50%; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none; BORDER-COLLAPSE: collapse; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial" cellSpacing=0 cellPadding=0 border=1>
    <tbody>
        <tr>
            <td style="BORDER-RIGHT: black 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: black 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0in; BORDER-LEFT: black 1pt solid; WIDTH: 7.65in; PADDING-TOP: 0in; BORDER-BOTTOM: black 1pt solid" vAlign=top width=734>
            <div style="MARGIN-BOTTOM: 0pt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face="Courier New">lea&nbsp;&nbsp; ecx, DWORD PTR [ebp-14H]</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;call&nbsp;??0my_class@@QAE@XZ&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; </span>调用my_class::my_class, ??my_class@@QAE@XZ是经过Name Mangling后的名字</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp; DWORD PTR [ebp-4], 0&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; </span>进入__try块，在Main中有一个隐式的__try/__except块</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New">&nbsp;</font></div>
            </td>
        </tr>
    </tbody>
</table>
</p>
<div>&nbsp;</div>
<div>接着调用my_class::method</div>
<p>
<table style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; BACKGROUND: rgb(219,229,241) 0% 50%; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none; BORDER-COLLAPSE: collapse; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial" cellSpacing=0 cellPadding=0 border=1>
    <tbody>
        <tr>
            <td style="BORDER-RIGHT: black 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: black 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0in; BORDER-LEFT: black 1pt solid; WIDTH: 7.65in; PADDING-TOP: 0in; BORDER-BOTTOM: black 1pt solid" vAlign=top width=734>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push&nbsp;10&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; </span>参数入栈</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lea&nbsp;&nbsp; ecx, DWORD PTR [ebp-14H]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; </span>遵循thiscall调用协定，ecx存放的是this指针</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; call&nbsp;?method@my_class@@QAEXH@Z&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; </span>调用子程序my_class:method(10)</font></div>
            </td>
        </tr>
    </tbody>
</table>
</p>
<div>&nbsp;</div>
<div>之后是析构：</div>
<p>
<table style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; BACKGROUND: rgb(219,229,241) 0% 50%; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none; BORDER-COLLAPSE: collapse; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial" cellSpacing=0 cellPadding=0 border=1>
    <tbody>
        <tr>
            <td style="BORDER-RIGHT: black 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: black 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0in; BORDER-LEFT: black 1pt solid; WIDTH: 7.65in; PADDING-TOP: 0in; BORDER-BOTTOM: black 1pt solid" vAlign=top width=734>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; DWORD PTR [ebp-e0H], 0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; </span>用来放置返回值</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; DWORD PTR [ebp-4], -1&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; </span>标记TRY的正常结束</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lea&nbsp;&nbsp; ecx, DWORD PTR [ebp-14H]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; a_class</span>的地址作为this存入ECX</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; call&nbsp;??1my_class@@QAE@XZ&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; my_class::~my_class</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; eax, DWORD PTR [ebp-e0H]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; </span>返回值按照约定放入eax中</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New">&nbsp;</font></div>
            </td>
        </tr>
    </tbody>
</table>
</p>
<div>&nbsp;</div>
<div>Main函数退出代码如下：</div>
<p>
<table style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; BACKGROUND: rgb(219,229,241) 0% 50%; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none; BORDER-COLLAPSE: collapse; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial" cellSpacing=0 cellPadding=0 border=1>
    <tbody>
        <tr>
            <td style="BORDER-RIGHT: black 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: black 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0in; BORDER-LEFT: black 1pt solid; WIDTH: 7.65in; PADDING-TOP: 0in; BORDER-BOTTOM: black 1pt solid" vAlign=top width=734>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push&nbsp;edx</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; ecx, ebp</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push&nbsp;eax</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lea&nbsp;&nbsp; edx, DWORD PTR $LN7@wmain</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; call&nbsp;@_RTC_CheckStackVars@8&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; </span>检查栈</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pop&nbsp;&nbsp; eax</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pop&nbsp;&nbsp; edx</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; ecx, DWORD PTR [ebp-0cH]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; </span>取出之前保存的旧的fs:0，并恢复</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; DWORD PTR fs:0, ecx</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pop&nbsp;&nbsp; ecx</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pop&nbsp;&nbsp; edi</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pop&nbsp;&nbsp; esi</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pop&nbsp;&nbsp; ebx</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; add&nbsp;&nbsp; esp, e4H&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; </span>退掉分配的d8H + 建立SEH链所需的0cH字节</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmp&nbsp;&nbsp; ebp, esp</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; call&nbsp;__RTC_CheckEsp&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; </span>检查esp值，这个时候esp应该和ebp匹配，否则说明出现了栈不平衡的情况，这种情况下调用子程序报错</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; esp, ebp&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; </span>恢复ebp到esp</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pop&nbsp;&nbsp; ebp&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; </span>恢复原来的ebp值</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ret&nbsp;&nbsp; 0</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New">_wmain<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ENDP</span></font></div>
            </td>
        </tr>
    </tbody>
</table>
</p>
<div>&nbsp;</div>
<div>专门用于SEH的子程序。__unwindfunclet$_wmain$0当异常发生的时候被调，负责进行栈展开，主要是调用析构函数。__ehhandler$_wmain则是在exception被抛出的时候调用。</div>
<p>
<table style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; BACKGROUND: rgb(219,229,241) 0% 50%; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none; BORDER-COLLAPSE: collapse; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial" cellSpacing=0 cellPadding=0 border=1>
    <tbody>
        <tr>
            <td style="BORDER-RIGHT: black 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: black 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0in; BORDER-LEFT: black 1pt solid; WIDTH: 7.65in; PADDING-TOP: 0in; BORDER-BOTTOM: black 1pt solid" vAlign=top width=734>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New">Text$x<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SEGMENT</span></font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New">__unwindfunclet$_wmain$0:<span>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; </span>当SEH发生的时候会调用该函数，析购a_class</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lea&nbsp;&nbsp; ecx, DWORD PTR [ebp-14H]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; ecx = [ebp &#8211; 14H]</span>，也就是a_class的地址</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jmp&nbsp;&nbsp; ??1my_class@@QAE@XZ&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; </span>调用my_class::~my_class</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New">__ehhandler$_wmain:</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; edx, DWORD PTR [esp+8]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; esp = </span>当前的fs:0, [esp + 8] = 之前的SEH结构，也就是main中建立的</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lea&nbsp;&nbsp; eax, DWORD PTR [edx+0cH]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; edx + 0Ch = </span>当前的ebp，也就是main的ebp，此时不能直接使用ebp因为可能会从任意函数调过来，此时ebp是该函数的ebp，而不是main的ebp</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; ecx, DWORD PTR [edx-e0H]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; </span>之前存下去的__security_cookie ^ ebp</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xor&nbsp;&nbsp; ecx, eax&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; </span>再次和ebp相异或</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; call&nbsp;@__security_check_cookie@4&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; </span>此时ecx应该等于__security_cookie，否则说明栈的内容被恶意改动（或者编程错误）</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; eax, OFFSET __ehfuncinfo$_wmain</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jmp&nbsp;&nbsp; ___CxxFrameHandler3</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New">text$x<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ENDS</span></font></div>
            <div style="MARGIN-BOTTOM: 0pt">&nbsp;</div>
            </td>
        </tr>
    </tbody>
</table>
</p>
<div>&nbsp;</div>
<div>My_class::my_class构造函数如下。构造函数本质上就是一个全局函数，名字是经过打乱的(Name Mangling)，这样可以和同一Class和其他Class的同名方法区别开来。不同编译器有不同规则，因此不必过于深究。</div>
<p>
<table style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; BACKGROUND: rgb(219,229,241) 0% 50%; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none; BORDER-COLLAPSE: collapse; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial" cellSpacing=0 cellPadding=0 border=1>
    <tbody>
        <tr>
            <td style="BORDER-RIGHT: black 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: black 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0in; BORDER-LEFT: black 1pt solid; WIDTH: 7.65in; PADDING-TOP: 0in; BORDER-BOTTOM: black 1pt solid" vAlign=top width=734>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New">_TEXT</font><span><font face="Courier New"> SEGMENT<br>??0my_class@@QAE@XZ PROC</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push&nbsp;ebp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; </span>保存旧的ebp</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; ebp, esp&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; ebp</span>保存当前栈的位置</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sub&nbsp;&nbsp; esp, ccH&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; </span>给栈分配ccH个字节</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push&nbsp;ebx&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; </span>保存常用寄存器</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push&nbsp;esi</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push&nbsp;edi</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push&nbsp;ecx</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lea&nbsp;&nbsp; edi, DWORD PTR [ebp-ccH]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; </span>从分配的位置开始</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; ecx, 33H&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; </span>写33H个ccccccccH</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; eax, ccccccccH&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; </span>也就是33H*4H=ccH，正好是分配的大小</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rep stosd&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; </span>从而把整个栈上当前分配的空间用ccH填满</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pop&nbsp;&nbsp; ecx</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; DWORD PTR [ebp-8], ecx&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; </span>按照约定，一般用ECX保存this指针</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; </span>把this存入到ebp-8，并不是很必要，因为这是Debug版本</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New">&nbsp;</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New">; 10<span>&nbsp;&nbsp; :&nbsp;&nbsp;&nbsp;&nbsp; {</span></font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New">; 11<span>&nbsp;&nbsp; :&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_member = 1;</span></font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New">&nbsp;</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; eax, DWORD PTR [ebp-8]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; eax</span>中存放this</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; DWORD PTR [eax], 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; this</span>的头四个byte是m_member的内容</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New">&nbsp;</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New">; 12<span>&nbsp;&nbsp; :&nbsp;&nbsp;&nbsp;&nbsp; }</span></font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New">&nbsp;</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; eax, DWORD PTR [ebp-8]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; </span>多余的一句话，可以优化掉</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pop&nbsp;&nbsp; edi</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pop&nbsp;&nbsp; esi</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pop&nbsp;&nbsp; ebx</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; esp, ebp&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; </span>恢复esp，因此就算是中间栈运算出错，最后也不会导致灾难性的结果，只要ebp还是正确的</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pop&nbsp;&nbsp; ebp</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ret&nbsp;&nbsp; 0</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New">??0my_class@@QAE@XZ ENDP</font></div>
            </td>
        </tr>
    </tbody>
</table>
</p>
<div>&nbsp;</div>
<div>My_class::method的实现如下：</div>
<p>
<table style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; BACKGROUND: rgb(219,229,241) 0% 50%; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none; BORDER-COLLAPSE: collapse; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial" cellSpacing=0 cellPadding=0 border=1>
    <tbody>
        <tr>
            <td style="BORDER-RIGHT: black 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: black 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0in; BORDER-LEFT: black 1pt solid; WIDTH: 7.65in; PADDING-TOP: 0in; BORDER-BOTTOM: black 1pt solid" vAlign=top width=734>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New">_TEXT<span> SEGMENT</span></font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New">?method@my_class@@QAEXH@Z PROC<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; my_class::method</span></font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New">&nbsp;</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New">; 15<span>&nbsp;&nbsp; :&nbsp;&nbsp;&nbsp;&nbsp; {</span></font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New">&nbsp;</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push&nbsp;ebp</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; ebp, esp</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sub&nbsp;&nbsp; esp, ccH</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push&nbsp;ebx</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push&nbsp;esi</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push&nbsp;edi</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push&nbsp;ecx</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lea&nbsp;&nbsp; edi, DWORD PTR [ebp-ccH]</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; ecx, 33H</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; eax, ccccccccH</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rep stosd</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pop&nbsp;&nbsp; ecx</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; DWORD PTR [ebp-8], ecx</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New">&nbsp;</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New">; 16<span>&nbsp;&nbsp; :&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_member = n;</span></font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New">&nbsp;</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; eax, DWORD PTR [ebp-8]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; eax</span>中存放this</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; ecx, DWORD PTR [ebp+8]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; ebp -&gt; ebp</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; ebp + 4 -&gt; IP </font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; ebp + 8 -&gt; n</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; </span>把n存入ecx中</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; DWORD PTR [eax], ecx&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; this</span>头四个字节是m_member, 因此这句话就是m_member = n</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New">&nbsp;</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New">; 17<span>&nbsp;&nbsp; :&nbsp;&nbsp;&nbsp;&nbsp; }</span></font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New">&nbsp;</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pop&nbsp;&nbsp; edi</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pop&nbsp;&nbsp; esi</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pop&nbsp;&nbsp; ebx</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; esp, ebp</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pop&nbsp;&nbsp; ebp</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ret&nbsp;&nbsp; 4&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; </span>等价于</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; ret </span>恢复EIP，返回调用地址</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; add esp, 4 -&gt; </span>把n从栈上Pop掉</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New">?method@my_class@@QAEXH@Z ENDP</font></div>
            </td>
        </tr>
    </tbody>
</table>
</p>
<div>&nbsp;</div>
<div>最后的析构函数，和前面的代码并无区别。</div>
<p>
<table style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; BACKGROUND: rgb(219,229,241) 0% 50%; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none; BORDER-COLLAPSE: collapse; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial" cellSpacing=0 cellPadding=0 border=1>
    <tbody>
        <tr>
            <td style="BORDER-RIGHT: black 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: black 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0in; BORDER-LEFT: black 1pt solid; WIDTH: 7.65in; PADDING-TOP: 0in; BORDER-BOTTOM: black 1pt solid" vAlign=top width=734>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New">_TEXT<span> SEGMENT</span></font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New">??1my_class@@QAE@XZ PROC<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; my_class::~my_class</span></font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New">&nbsp;</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New">; 20<span>&nbsp;&nbsp; :&nbsp;&nbsp;&nbsp;&nbsp; {</span></font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New">&nbsp;</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push&nbsp;ebp</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; ebp, esp</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sub&nbsp;&nbsp; esp, 204&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push&nbsp;ebx</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push&nbsp;esi</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push&nbsp;edi</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push&nbsp;ecx</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lea&nbsp;&nbsp; edi, DWORD PTR [ebp-204]</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; ecx, 33H&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; eax, ccccccccH&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rep stosd</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pop&nbsp;&nbsp; ecx</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; DWORD PTR _this$[ebp], ecx</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New">&nbsp;</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New">; 21<span>&nbsp;&nbsp; :&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_member = 0;</span></font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New">&nbsp;</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; eax, DWORD PTR [ebp-8]</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; DWORD PTR [eax], 0</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New">&nbsp;</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New">; 22<span>&nbsp;&nbsp; :&nbsp;&nbsp;&nbsp;&nbsp; }</span></font></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New">&nbsp;</font></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pop&nbsp;&nbsp; edi</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pop&nbsp;&nbsp; esi</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pop&nbsp;&nbsp; ebx</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; esp, ebp</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pop&nbsp;&nbsp; ebp</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><span><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ret&nbsp;&nbsp; 0</font></span></div>
            <div style="MARGIN-BOTTOM: 0pt"><font face="Courier New">??1my_class@@QAE@XZ ENDP<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; my_class::~my_class</span></font></div>
            </td>
        </tr>
    </tbody>
</table>
</p>
<img src ="http://www.cppblog.com/zgysx/aggbug/56382.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zgysx/" target="_blank">永遇乐</a> 2008-07-17 10:15 <a href="http://www.cppblog.com/zgysx/archive/2008/07/17/56382.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>编写可变参数函数</title><link>http://www.cppblog.com/zgysx/archive/2008/07/08/55609.html</link><dc:creator>永遇乐</dc:creator><author>永遇乐</author><pubDate>Tue, 08 Jul 2008 03:35:00 GMT</pubDate><guid>http://www.cppblog.com/zgysx/archive/2008/07/08/55609.html</guid><wfw:comment>http://www.cppblog.com/zgysx/comments/55609.html</wfw:comment><comments>http://www.cppblog.com/zgysx/archive/2008/07/08/55609.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zgysx/comments/commentRss/55609.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zgysx/services/trackbacks/55609.html</trackback:ping><description><![CDATA[<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">#include&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">stdafx.h</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">stdio.h</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">stdarg.h</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">varargs.h</span><span style="COLOR: #000000">&gt;</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: #0000ff">void</span><span style="COLOR: #000000">&nbsp;Format(wchar_t&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;psz,&nbsp;<img src="http://www.cppblog.com/Images/dot.gif">&nbsp;)<br><img id=Codehighlighter1_132_299_Open_Image onclick="this.style.display='none'; Codehighlighter1_132_299_Open_Text.style.display='none'; Codehighlighter1_132_299_Closed_Image.style.display='inline'; Codehighlighter1_132_299_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_132_299_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_132_299_Closed_Text.style.display='none'; Codehighlighter1_132_299_Open_Image.style.display='inline'; Codehighlighter1_132_299_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_132_299_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_132_299_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;va_list&nbsp;ap;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;wchar_t&nbsp;message[</span><span style="COLOR: #000000">1024</span><span style="COLOR: #000000">] = {0};&nbsp;</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;va_start(ap,psz);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;vswprintf(message,psz,ap);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;va_end(ap);<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;wprintf(L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%s\n</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;message);<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">int</span><span style="COLOR: #000000">&nbsp;_tmain(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;argc,&nbsp;_TCHAR</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;argv[])<br><img id=Codehighlighter1_340_413_Open_Image onclick="this.style.display='none'; Codehighlighter1_340_413_Open_Text.style.display='none'; Codehighlighter1_340_413_Closed_Image.style.display='inline'; Codehighlighter1_340_413_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_340_413_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_340_413_Closed_Text.style.display='none'; Codehighlighter1_340_413_Open_Image.style.display='inline'; Codehighlighter1_340_413_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_340_413_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_340_413_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;wchar_t&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;p&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">abc</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;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;a&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">10</span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;Format(L</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%s%d</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;p,&nbsp;a);<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: #000000">0</span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span></div>
<br>输出为:abc10
<img src ="http://www.cppblog.com/zgysx/aggbug/55609.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zgysx/" target="_blank">永遇乐</a> 2008-07-08 11:35 <a href="http://www.cppblog.com/zgysx/archive/2008/07/08/55609.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>有关图像方面的就业方向</title><link>http://www.cppblog.com/zgysx/archive/2008/03/12/44278.html</link><dc:creator>永遇乐</dc:creator><author>永遇乐</author><pubDate>Wed, 12 Mar 2008 07:36:00 GMT</pubDate><guid>http://www.cppblog.com/zgysx/archive/2008/03/12/44278.html</guid><wfw:comment>http://www.cppblog.com/zgysx/comments/44278.html</wfw:comment><comments>http://www.cppblog.com/zgysx/archive/2008/03/12/44278.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zgysx/comments/commentRss/44278.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zgysx/services/trackbacks/44278.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 就我看来，个人觉得图像处理的就业还是不错的。首先可以把图像看成二维、三维或者更高维的信号，从这个意义上来说，图像处理是整个信号处理里面就业形势最好的，因为你不仅要掌握（一维）信号处理的基本知识，也要掌握图像处理（二维或者高维信号处理）的知识。其次，图像处理是计算机视觉和视频处理的基础，掌握好了图像处理的基本知识，就业时就可以向这些方向发展。目前的模式识别，大部分也都是图像模式识别。在实际应用场合，采集的信息很多都是图像信息，比如指纹、条码、人脸、虹膜、车辆等等。说到应用场合，千万不能忘了医学图像这一块，如果有医学图像处理的背景，去一些医疗器械公司或者医疗软件公司也是不错的选择。图像处理对编程的要求比较高，如果编程很厉害，当然就业也多了一个选择方向，并不一定要局限在图像方向。</p>
<p>下面谈谈我所知道的一些公司信息，不全，仅仅是我所了解到的或者我所感兴趣的，实际远远不止这么多。</p>
<p>搜索方向<br>基于内容的图像或视频搜索是很多搜索公司研究的热点。要想进入这个领域，必须有很强的编程能力，很好的图像处理和模式识别的背景。要求高待遇自然就不错，目前这方面的代表公司有微软、google、yahoo和百度，个个鼎鼎大名。</p>
<p>医学图像方向<br>目前在医疗器械方向主要是几个大企业在竞争，来头都不小，其中包括Simens、GE、飞利浦和柯达，主要生产CT和MRI等医疗器材。由于医疗器械的主要功能是成像，必然涉及到对图像的处理，做图像处理的很有机会进入这些公司。它们在国内都设有研发中心，simens的在上海和深圳，GE和柯达都在上海，飞利浦的在沈阳。由于医疗市场是一个没有完全开发的市场，而一套医疗设备的价格是非常昂贵的，所以在这些地方的待遇都还可以，前景也看好。国内也有一些这样的企业比如深圳安科和迈瑞</p>
<p>计算机视觉和模式识别方向<br>我没去调研过有哪些公司在做，但肯定不少，比如指纹识别、人脸识别、虹膜识别。还有一个很大的方向是车牌识别，这个我倒是知道有一个公司高德威智能交通似乎做的很不错的样子。目前视频监控是一个热点问题，做跟踪和识别的可以在这个方向找到一席之地。<br>上海法视特位于上海张江高科技园区，在视觉和识别方面做的不错。北京的我也知道两个公司：大恒和凌云，都是以图像作为研发的主体。</p>
<p>视频方向<br>一般的高校或者研究所侧重在标准的制定和修改以及技术创新方面，而公司则侧重在编码解码的硬件实现方面。一般这些公司要求是熟悉或者精通MPEG、H.264或者AVS，选择了这个方向，只要做的还不错，基本就不愁饭碗。由于这不是我所感兴趣的方向，所以这方面的公司的信息我没有收集，但平常在各个bbs或者各种招聘网站经常看到。<br>我所知道的两个公司：诺基亚和pixelworks</p>
<p>其他<br>其实一般来说，只要涉及到成像或者图像的基本都要图像处理方面的人。比方说一个成像设备，在输出图像之前需要对原始图像进行增强或者去噪处理，存储时需要对图像进行压缩，成像之后需要对图像内容进行自动分析，这些内容都是图像处理的范畴。下面列举一些与图像有关或者招聘时明确说明需要图像处理方面人才的公司：<br>上海豪威集成电路有限公司（<a href="http://www.ovt.com.cn/" target=_blank>www.ovt.com.cn</a>）<br>中芯微<br>摩托罗拉上海研究院<br>威盛（VIA）<br>松下<br>索尼<br>清华同方<br>三星<br>所有与图像（静止或者运动图像）有关的公司都是一种选择。比如数码相机、显微镜成像、超声成像、工业机器人控制、显示器、电视、遥感等等，都可以作为求职方向。</p>
<p>要求：<br>1、外语。如果进外企，外语的重要性不言而喻。一般外企的第一轮面试都是英语口语面试。<br>2、编程。这方面尤以C＋＋为重，很多公司的笔试都是考c＋＋知识。<br>3、专业水平。如果要找专业相关的工作，研究生期间的研究经历和发表的论文就显的比较重要。<br>4、知识面的宽度。我觉得在研究生期间，除了做好自己的研究方向之外，扩宽一下知识面也有很大的帮助，当然这个知识面指的是图像处理、计算机视觉和模式识别，知识面越宽，就业时的选择就会越多。</p>
<p>图像处理方向毕业的就业面非常广，而且待遇在应届生应该是中上等。其实还是一句话，能力决定一切。只要研究生三年没有白</p>
<img src ="http://www.cppblog.com/zgysx/aggbug/44278.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zgysx/" target="_blank">永遇乐</a> 2008-03-12 15:36 <a href="http://www.cppblog.com/zgysx/archive/2008/03/12/44278.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>重载(overload)，覆盖(override),隐藏(hide)的区别</title><link>http://www.cppblog.com/zgysx/archive/2007/03/12/19662.html</link><dc:creator>永遇乐</dc:creator><author>永遇乐</author><pubDate>Mon, 12 Mar 2007 13:47:00 GMT</pubDate><guid>http://www.cppblog.com/zgysx/archive/2007/03/12/19662.html</guid><wfw:comment>http://www.cppblog.com/zgysx/comments/19662.html</wfw:comment><comments>http://www.cppblog.com/zgysx/archive/2007/03/12/19662.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.cppblog.com/zgysx/comments/commentRss/19662.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zgysx/services/trackbacks/19662.html</trackback:ping><description><![CDATA[写正题之前，先给出几个关键字的中英文对照，重载(overload)，覆盖(override),隐藏(hide)。在早期的C++书籍中，可能翻译的人不熟悉专业用语（也不能怪他们，他们不是搞计算机编程的，他们是英语专业的），常常把重载(overload)和覆盖(override)搞错！
<p>　　我们先来看一些代码及其编译结果。</p><p>　　实例一:<br />　　#include "stdafx.h"<br />　　#include &lt;iostream.h&gt;</p><p>　　class CB<br />　　{<br />　　public:<br /> 　　　　<font color="#ff0000">void f(int)<br /></font> 　　　　{<br /> 　　　　　　 cout &lt;&lt; "CB::f(int)" &lt;&lt; endl;<br />　　　　 }</p><p>　　};</p><p><br />　　class CD : public CB<br />　　{<br />　　public:<br />　　　　 <font color="#ff0000">void f(int,int)<br /></font> 　　　　{<br />  　　　　　　cout &lt;&lt; "CD::f(int,int)" &lt;&lt; endl;<br /> 　　　　}</p><p> 　　　　void test()<br /> 　　　　{<br />  　　　　　f(1);<br /> 　　　　}<br />　　};</p><p>　int main(int argc, char* argv[])<br />　{<br />　　　 return 0;<br />　}<br />编译了一下<br />error C2660: 'f' : function does not take 1 parameters</p><p><br />结论：在类CD这个域中，没有f(int)这样的函数，基类中的void f(int)被<font color="#ff0000">隐藏</font></p><p>　　如果把派生CD中成员函数void f(int,int)的声明改成和基类中一样，即f(int)，基类中的void f(int)还是一样被覆盖，此时编译不会出错，在函数中test调用的是CD中的f(int)　</p><p>　　所以，在<font color="#ff0000">基类中</font>的某些函数，如果<font color="#ff0000">没有</font><font color="#ff0000">virtral</font>关键字，函数名是<font color="#ff0000">f(</font>参数是什么我们不管)，那么如果在派生类CD中<font color="#ff0000">也声明了某个f</font>成员函数，那么在类CD域中，<font color="#ff0000">基类中所有的那些f都被隐藏。</font><br />　　如果你比较心急，想知道什么是隐藏，看文章最后的简单说明，不过我建议你还是一步一步看下去。</p><p>　　我们刚才说的是没有virtual的情况，如果有virtual的情况呢？？<br />　　实例二：</p><p>#include "stdafx.h"<br />#include &lt;iostream.h&gt;</p><p>class CB<br />{<br />public:<br /> 　　<font color="#ff0000">virtual void f(int)<br /></font> 　　{<br />  　　　　cout &lt;&lt; "CB::f(int)" &lt;&lt; endl;<br /> 　　}</p><p>};</p><p><br />class CD : public CB<br />{<br />public:<br />　　 <font color="#ff0000">void f(int)<br /></font> 　　{<br />  　　　　cout &lt;&lt; "CD::f(int)" &lt;&lt; endl;<br />　　 }</p><p>};</p><p>int main(int argc, char* argv[])<br />{<br /> 　return 0;<br />}</p><p>　　这么写当然是没问题了，在这里我不多费口舌了，这是很简单的，多态，虚函数，然后什么指向基类的指针指向派生类对象阿，通过引用调用虚函数阿什么的，属性多的很咯，什么？？你不明白？？随便找本C++的书，对会讲多态和虚函数机制的哦！！<br />　　这种情况我们叫<font color="#ff0000">覆盖(override)！</font>覆盖指的是派生类的虚拟函数覆盖了基类的同名且参数相同的函数！<br />　　在这里，我要强调的是，这种覆盖，要满足两个条件<br />　<font size="4">(a)</font><font color="#ff0000">有virtual关键字</font>，在基类中函数声明的时候加上就可以了<br />　<font size="4">(b)</font>基类CB中的函数和派生类CD中的函数<font color="#ff0000">要一模一样</font>，什么叫一模一样，<font color="#ff0000">函数名，参数，返回类型三个条件</font>。<br />　　有人可能会对(b)中的说法质疑，说返回类型也要一样？？<br />　　是，覆盖的话必须一样，我试了试，如果在基类中,把f的声明改成virtual int f(int)，编译出错了<br />　　error C2555: 'CD::f' : overriding virtual function differs from 'CB::f' only by return type or calling convention<br />　　所以，覆盖的话，必须要满足上述的(a)(b)条件</p><p>　　那么如果基类CB中的函数f有关键字virtual　，但是参数和派生类CD中的函数f参数不一样呢，<br />实例三:<br />  #include "stdafx.h"<br />#include &lt;iostream.h&gt;</p><p>class CB<br />{<br />　public:<br /> 　　 virtual  void f(int)<br />　　 {<br /> 　　　　 cout &lt;&lt; "CB::f(int)" &lt;&lt; endl;<br />　　 }</p><p>}<br />;</p><p><br />class CD : public CB<br />{<br />public:<br /> 　　 void f(int，int)<br /> 　　{<br /> 　　　 cout &lt;&lt; "CD::f(int，int)" &lt;&lt; endl;<br /> 　　}</p><p> 　　void test()<br /> 　　{<br /> 　　　　 f(1);<br /> 　　}<br />}<br />;</p><p>int main(int argc, char* argv[])<br />{<br /> return 0;<br />}</p><p>编译出错了，<br /> error C2660: 'f' : function does not take 1 parameters<br />　　咦？？好面熟的错？？对，和实例一中的情况一样哦，结论也是基类中的函数被隐藏了。</p><p>　　通过上面三个例子，得出一个简单的结论<br />如果<font color="#ff0000">基类中的函数和派生类中的两个名字一样的函数f</font><br />满足下面的两个条件<br /><font size="4">(a)在基类中函数声明的时候有virtual关键字<br />(b)基类CB中的函数和派生类CD中的函数一模一样，函数名，参数，返回类型都一样。<br />那么这就是叫做<font color="#ff0000">覆盖(override)，</font>这也就是虚函数，多态的性质</font></p><p><font size="4">那么其他的情况呢？？只要名字一样，不满足上面覆盖的条件，就是<font color="#ff0000">隐藏</font>了。</font></p><p><font size="4">下面我要讲最关键的地方了</font>，好多人认为，基类CB中的f(int)会继承下来和CD中的f(int,int)在派生类CD中构成重载，就像实例一中想像的那样。<br />　　对吗？我们先看重载的定义<br />　　<font color="#ff0000">重载(overload):<br /></font>　　必须在一个域中,函数名称相同但是函数参数不同,重载的作用就是同一个函数有不同的行为,因此不是在一个域中的函数是无法构成重载的,这个是重载的重要特征<br />　　<font color="#ff0000" size="4">必须在一个域中</font>，而继承明显是在两个类中了哦，所以上面的想法是不成立的，我们测试的结构也是这样，派生类中的f(int,int)把基类中的f(int)隐藏了<br />　　所以，<font color="#ff0000">相同的函数名的函数，在基类和派生类中的关系只能是覆盖或者隐藏。</font></p><p>　　在文章中，我把重载和覆盖的定义都给了出来了，但是一直没有给隐藏的定义，在最后，我把他给出来，这段话是网上google来的，比较长，你可以简单的理解成，在派生类域中，看不到基类中的那个同名函数了，或者说，是并没有继承下来给你用，呵呵，如实例一　那样。<br />　　</p><p><font color="#ff0000">隐藏(hide):<br /></font>指的是派生类的成员函数隐藏了基类函数的成员函数.隐藏一词可以这么理解:在调用一个类的成员函数的时候,编译器会沿着类的继承链逐级的向上查找函数的定义,如果找到了那么就停止查找了,所以如果一个派生类和一个基类都有同一个<font style="BACKGROUND-COLOR: #ffffff" color="#ff0000">同名</font>(暂且不论参数是否相同)的函数,而编译器最终选择了在派生类中的函数,那么我们就说这个派生类的成员函数"隐藏"了基类的成员函数,也就是说它阻止了编译器继续向上查找函数的定义.</p><img src ="http://www.cppblog.com/zgysx/aggbug/19662.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zgysx/" target="_blank">永遇乐</a> 2007-03-12 21:47 <a href="http://www.cppblog.com/zgysx/archive/2007/03/12/19662.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>gdb常用命令</title><link>http://www.cppblog.com/zgysx/archive/2007/03/09/19491.html</link><dc:creator>永遇乐</dc:creator><author>永遇乐</author><pubDate>Fri, 09 Mar 2007 05:42:00 GMT</pubDate><guid>http://www.cppblog.com/zgysx/archive/2007/03/09/19491.html</guid><wfw:comment>http://www.cppblog.com/zgysx/comments/19491.html</wfw:comment><comments>http://www.cppblog.com/zgysx/archive/2007/03/09/19491.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zgysx/comments/commentRss/19491.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zgysx/services/trackbacks/19491.html</trackback:ping><description><![CDATA[
		<p>
				<font size="6">GNU的调试器称为gdb,是一个交互式的程序，工作在字符模式。其常用命令如下：</font>
		</p>
		<p>
				<font size="6">break NUM 在指定的行上设置断点  break 1</font>
		</p>
		<p>
				<font size="6">bt 显示函数的调用顺序</font>
		</p>
		<p>
				<font size="6">clear 删除断点 clear test.c:10 </font>
		</p>
		<p>
				<font size="6">display expr 每次程序停止后显示表达式的值</font>
		</p>
		<p>
				<font size="6">printf expr显示表达式的值。与display expr是有区别的</font>
		</p>
		<p>
				<font size="6">file filename装载文件进行调试</font>
		</p>
		<p>
				<font size="6">info break;显示断点清单</font>
		</p>
		<p>
				<font size="6">info files 显示被调试文件的信息</font>
		</p>
		<p>
				<font size="6">info func显示所有函数名称</font>
		</p>
		<p>
				<font size="6">info local显示当前函数中的局部变量信息</font>
		</p>
		<p>
				<font size="6">info var 显示所有的全局和静态变量名称。</font>
		</p>
		<p>
				<font size="6">info prog 显示被调试程序的执行状态。</font>
		</p>
		<p>
				<font size="6">kill 终止正在被调试的程序</font>
		</p>
		<p>
				<font size="6">list 显示源代码</font>
		</p>
		<p>
				<font size="6">next 单步调试</font>
		</p>
		<p>
				<font size="6">where 显示程序出错的地方。</font>
		</p>
<img src ="http://www.cppblog.com/zgysx/aggbug/19491.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zgysx/" target="_blank">永遇乐</a> 2007-03-09 13:42 <a href="http://www.cppblog.com/zgysx/archive/2007/03/09/19491.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]URL编码</title><link>http://www.cppblog.com/zgysx/archive/2007/01/04/17217.html</link><dc:creator>永遇乐</dc:creator><author>永遇乐</author><pubDate>Thu, 04 Jan 2007 05:46:00 GMT</pubDate><guid>http://www.cppblog.com/zgysx/archive/2007/01/04/17217.html</guid><wfw:comment>http://www.cppblog.com/zgysx/comments/17217.html</wfw:comment><comments>http://www.cppblog.com/zgysx/archive/2007/01/04/17217.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/zgysx/comments/commentRss/17217.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zgysx/services/trackbacks/17217.html</trackback:ping><description><![CDATA[
		<p align="center">
				<strong>URL编码</strong>
				<br />作者： Chandrasekhar Vuppalapati <br />翻译：eastvc</p>
		<p>
				<a href="http://www.vckbase.com/code/downcode.asp?id=3000">下载源代码</a>
				<br />
				<br />本文的目的是设计一个完成URL编码的C++类。在我曾经的项目中，我需要从VC++ 6.0应用程序中POST数据，而这些数据需要进行URL编码。我在MSDN中查找能根据提供的字符串生成URL编码的相关类或API，但我没有找到，因此我必须设计一个自己的URLEncode C++类。</p>
		<p>URLEncoder.exe是一个使用URLEncode类的MFC对话框程序。</p>
		<p>
				<font color="blue">
						<strong>如何处理</strong>
				</font>
		</p>
		<p>一些特殊字符在Internet上传送是件棘手的事情, 经URL编码特殊处理，可以使所有字符安全地从Internet传送。</p>
		<p>例如，回车的ASCII值是13，在发送FORM数据时候这就认为是一行数据的结束。</p>
		<p>通常，所有应用程序采用HTTP或HTTPS协议在客户端和服务器端传送数据。服务器端从客户端接收数据有两种基本方法：</p>
		<p>1、数据可以从HTTP头传送（COOKIES或作为FORM数据发送）<br />2、可以包含在URL中的查询部分</p>
		<p>当数据包含在URL，它必须遵循URL语法进行编码。在WEB服务器端，数据自动解码。考虑一下下面的URL，哪个数据是作为查询参数。</p>
		<p>例如：http://WebSite/ResourceName?Data=Data</p>
		<p>WebSite是URL名称<br />ResourceName可以是ASP或Servlet名称<br />Data是需要发送的数据。如果MIME类型是Content-Type: application/x-www-form-urlencoded，则要求进行编码。</p>
		<p>
				<font color="blue">
						<strong>RFC 1738</strong>
				</font>
		</p>
		<p>RFC 1738指明了统一资源定位(URLs)中的字符应该是US-ASCII字符集的子集。这是受HTML的限制，另一方面，允许在文档中使用所有ISO- 8859-1(ISO-Latin)字符集。这将意味着在HTML FORM里POST的数据（或作为查询字串的一部分），所有HTML编码必须被编码。</p>
		<p>ISO-8859-1 (ISO-Latin)字符集</p>
		<p>在下表中，包含了完整的ISO-8859-1 (ISO-Latin)字符集，表格提供了每个字符范围（10进制），描述，实际值，十六进制值，HTML结果。某个范围中的字符是否安全。<br /></p>
		<table cellspacing="2" cellpadding="2" border="2">
				<tbody>
						<tr bgcolor="#ffff99">
								<td valign="top">
										<b>Character range(decimal)</b>
								</td>
								<td valign="top">
										<b>Type</b>
								</td>
								<td valign="top">
										<b>Values</b>
								</td>
								<td valign="top">
										<b>Safe/Unsafe</b>
								</td>
						</tr>
						<tr>
								<td valign="top">0-31</td>
								<td valign="top">ASCII Control Characters</td>
								<td valign="top">These characters are not printable</td>
								<td valign="top">Unsafe</td>
						</tr>
						<tr>
								<td valign="top">32-47</td>
								<td valign="top">Reserved Characters</td>
								<td valign="top">'' ''!?#$%&amp;''()*+,-./</td>
								<td valign="top">Unsafe</td>
						</tr>
						<tr>
								<td valign="top">48-57</td>
								<td valign="top">ASCII Characters and Numbers</td>
								<td valign="top">0-9</td>
								<td valign="top">Safe</td>
						</tr>
						<tr>
								<td valign="top">58-64</td>
								<td valign="top">Reserved Characters</td>
								<td valign="top">:;&lt;=&gt;?@</td>
								<td valign="top">Unsafe</td>
						</tr>
						<tr>
								<td valign="top">65-90</td>
								<td valign="top">ASCII Characters</td>
								<td valign="top">A-Z</td>
								<td valign="top">Safe</td>
						</tr>
						<tr>
								<td valign="top">91-96</td>
								<td valign="top">Reserved Characters</td>
								<td valign="top">[\]^_`</td>
								<td valign="top">Unsafe</td>
						</tr>
						<tr>
								<td valign="top">97-122</td>
								<td valign="top">ASCII Characters</td>
								<td valign="top">a-z</td>
								<td valign="top">Safe</td>
						</tr>
						<tr>
								<td valign="top">123-126</td>
								<td valign="top">Reserved Characters</td>
								<td valign="top">{|}~</td>
								<td valign="top">Unsafe</td>
						</tr>
						<tr>
								<td valign="top">127</td>
								<td valign="top">Control Characters</td>
								<td valign="top">'' '' </td>
								<td valign="top">Unsafe</td>
						</tr>
						<tr>
								<td valign="top">128-255</td>
								<td valign="top">Non-ASCII Characters</td>
								<td valign="top">'' '' </td>
								<td valign="top">Unsafe</td>
						</tr>
				</tbody>
		</table>
		<p>所有不安全的ASCII字符都需要编码，例如，范围(32-47, 58-64, 91-96, 123-126)。<br />下表描述了这些字符为什么不安全。 
</p>
		<table cellspacing="2" cellpadding="2" width="808" border="2">
				<tbody>
						<tr bgcolor="#ffff99">
								<td valign="top" width="72">
										<b>Character</b>
								</td>
								<td valign="top" width="579">
										<b>Unsafe Reason</b>
								</td>
								<td valign="top" width="127">
										<b>Character Encode</b>
								</td>
						</tr>
						<tr>
								<td valign="top">"&lt;"</td>
								<td valign="top">Delimiters around URLs in free text</td>
								<td valign="top">%3C</td>
						</tr>
						<tr>
								<td valign="top">&gt;</td>
								<td valign="top">Delimiters around URLs in free text</td>
								<td valign="top">%3E</td>
						</tr>
						<tr>
								<td valign="top">.</td>
								<td valign="top">Delimits URLs in some systems</td>
								<td valign="top">%22</td>
						</tr>
						<tr>
								<td valign="top">#</td>
								<td valign="top">It is used in the World Wide Web and in other systems to delimit a URL from a fragment/anchor identifier that might follow it. </td>
								<td valign="top">%23</td>
						</tr>
						<tr>
								<td valign="top">{</td>
								<td valign="top">Gateways and other transport agents are known to sometimes modify such characters </td>
								<td valign="top">%7B</td>
						</tr>
						<tr>
								<td valign="top">}</td>
								<td valign="top">Gateways and other transport agents are known to sometimes modify such characters</td>
								<td valign="top">%7D</td>
						</tr>
						<tr>
								<td valign="top">|</td>
								<td valign="top">Gateways and other transport agents are known to sometimes modify such characters</td>
								<td valign="top">%7C</td>
						</tr>
						<tr>
								<td valign="top">\</td>
								<td valign="top">Gateways and other transport agents are known to sometimes modify such characters</td>
								<td valign="top">%5C</td>
						</tr>
						<tr>
								<td valign="top">^</td>
								<td valign="top">Gateways and other transport agents are known to sometimes modify such characters</td>
								<td valign="top">%5E</td>
						</tr>
						<tr>
								<td valign="top">~</td>
								<td valign="top">Gateways and other transport agents are known to sometimes modify such characters</td>
								<td valign="top">%7E</td>
						</tr>
						<tr>
								<td valign="top">[</td>
								<td valign="top">Gateways and other transport agents are known to sometimes modify such characters</td>
								<td valign="top">%5B</td>
						</tr>
						<tr>
								<td valign="top">]</td>
								<td valign="top">Gateways and other transport agents are known to sometimes modify such characters</td>
								<td valign="top">%5D</td>
						</tr>
						<tr>
								<td valign="top">`</td>
								<td valign="top">Gateways and other transport agents are known to sometimes modify such characters</td>
								<td valign="top">%60</td>
						</tr>
						<tr>
								<td valign="top">+</td>
								<td valign="top">Indicates a space (spaces cannot be used in a URL)</td>
								<td valign="top">%20</td>
						</tr>
						<tr>
								<td valign="top">/</td>
								<td valign="top">Separates directories and subdirectories</td>
								<td valign="top">%2F</td>
						</tr>
						<tr>
								<td valign="top">?</td>
								<td valign="top">Separates the actual URL and the parameters</td>
								<td valign="top">%3F</td>
						</tr>
						<tr>
								<td valign="top">&amp;</td>
								<td valign="top">Separator between parameters specified in the URL</td>
								<td valign="top">%26</td>
						</tr>
				</tbody>
		</table>
		<p>
				<strong>
						<font color="blue">如何实现</font>
				</strong>
		</p>
		<p>字符的URL编码是将字符转换到8位16进制并在前面加上''%''前缀。例如，US-ASCII字符集中空格是10进制<br />的32或16进制的20，因此，URL编码是%20。</p>
		<p>URLEncode: URLEncode是一个C++类，来实现字符串的URL编码。CURLEncode类包含如下函数：<br />isUnsafeString <br />decToHex <br />convert <br />URLEncode </p>
		<p>URLEncode()函数完成编码过程，URLEncode检查每个字符，看是否安全。如果不安全将用%16进制值进行转换并添加<br />到原始字符串中。</p>
		<p>
				<strong>
						<font color="blue">代码片断</font>
				</strong>:</p>
		<pre>class CURLEncode
{
private:
  static CString csUnsafeString;
  CString (char num, int radix);
  bool isUnsafe(char compareChar);
  CString convert(char val);

public:
  CURLEncode() { };
  virtual ~CURLEncode() { };
  CString (CString vData);
};

bool CURLEncode::isUnsafe(char compareChar)
{
  bool bcharfound = false;
  char tmpsafeChar;
  int m_strLen = 0;

  m_strLen = csUnsafeString.GetLength();
  for(int ichar_pos = 0; ichar_pos &lt; m_strLen ;ichar_pos++)
  {
    tmpsafeChar = csUnsafeString.GetAt(ichar_pos);
    if(tmpsafeChar == compareChar)
    {
      bcharfound = true;
      break;
    }
  }
  int char_ascii_value = 0;
  //char_ascii_value = __toascii(compareChar);
  char_ascii_value = (int) compareChar;

  if(bcharfound == false &amp;&amp;  char_ascii_value &gt; 32 &amp;&amp;
                             char_ascii_value &lt; 123)
  {
    return false;
  }
  // found no unsafe chars, return false
  else
  {
    return true;
  }

  return true;
}

CString CURLEncode::decToHex(char num, int radix)
{
  int temp=0;
  CString csTmp;
  int num_char;

num_char = (int) num;
  if (num_char &lt; 0)
    num_char = 256 + num_char;

  while (num_char &gt;= radix)
    {
    temp = num_char % radix;
    num_char = (int)floor(num_char / radix);
    csTmp = hexVals[temp];
    }

  csTmp += hexVals[num_char];

  if(csTmp.GetLength() &lt; 2)
  {
    csTmp += ''0'';
  }

  CString strdecToHex(csTmp);
  // Reverse the String
  strdecToHex.MakeReverse();

  return strdecToHex;
}

CString CURLEncode::convert(char val)
{
  CString csRet;
  csRet += "%";
  csRet += decToHex(val, 16);
  return  csRet;
}
</pre>
		<br />
		<strong>
				<font color="blue">参考：</font>
		</strong>
		<br />
		<br />URL编码: <a href="http://www.blooberry.com/indexdot/html/topics/urlencoding.htm" target="newframe">http://www.blooberry.com/indexdot/html/topics/urlencoding.htm</a>.<br /><br />RFC 1866: The HTML 2.0 规范 (纯文本). 附录包含了字符表: <a href="http://www.rfc-editor.org/rfc/rfc1866.txt" target="newframe">http://www.rfc-editor.org/rfc/rfc1866.txt</a>.<br /><br />Web HTML 2.0 版本(RFC 1866) : <a href="http://www.w3.org/MarkUp/html-spec/html-spec_13.html" target="newframe">http://www.w3.org/MarkUp/html-spec/html-spec_13.html</a>.<br /><br />The HTML 3.2 (Wilbur) 建议: <a href="http://www.w3.org/MarkUp/Wilbur/" target="newframe">http://www.w3.org/MarkUp/Wilbur/</a>.<br /><br />The HTML 4.0 建议: <a href="http://www.w3.org/TR/REC-html40/" target="newframe">http://www.w3.org/TR/REC-html40/</a>.<br /><br />W3C HTML 国际化区域: <a href="http://www.w3.org/International/O-HTML.html" target="newframe">http://www.w3.org/International/O-HTML.html</a>.<img src ="http://www.cppblog.com/zgysx/aggbug/17217.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zgysx/" target="_blank">永遇乐</a> 2007-01-04 13:46 <a href="http://www.cppblog.com/zgysx/archive/2007/01/04/17217.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]用完成端口开发大响应规模的Winsock应用程序</title><link>http://www.cppblog.com/zgysx/archive/2007/01/04/17216.html</link><dc:creator>永遇乐</dc:creator><author>永遇乐</author><pubDate>Thu, 04 Jan 2007 05:42:00 GMT</pubDate><guid>http://www.cppblog.com/zgysx/archive/2007/01/04/17216.html</guid><wfw:comment>http://www.cppblog.com/zgysx/comments/17216.html</wfw:comment><comments>http://www.cppblog.com/zgysx/archive/2007/01/04/17216.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zgysx/comments/commentRss/17216.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zgysx/services/trackbacks/17216.html</trackback:ping><description><![CDATA[
		<p align="center">
				<strong>用完成端口开发大响应规模的Winsock应用程序</strong>
				<br />
		</p>
		<p>原文出处：<a href="http://msdn.microsoft.com/msdnmag/issues/1000/Winsock/" target="_blank">http://msdn.microsoft.com/msdnmag/issues/1000/Winsock/</a><br /><br />通常要开发网络应用程序并不是一件轻松的事情，不过，实际上只要掌握几个关键的原则也就可以了——创建和连接一个套接字，尝试进行连接，然后收发数据。真正难的是要写出一个可以接纳少则一个，多则数千个连接的网络应用程序。本文将讨论如何通过Winsock2在Windows NT 和 Windows 2000上开发高扩展能力的Winsock应用程序。文章主要的焦点在客户机/服务器模型的服务器这一方，当然，其中的许多要点对模型的双方都适用。 </p>
		<p>
				<font color="#009999">
						<strong>API与响应规模</strong>
				</font>
		</p>
		<p>通过Win32的重叠I/O机制，应用程序可以提请一项I/O操作，重叠的操作请求在后台完成，而同一时间提请操作的线程去做其他的事情。等重叠操作完成后线程收到有关的通知。这种机制对那些耗时的操作而言特别有用。不过，像Windows 3.1上的WSAAsyncSelect()及Unix下的select()那样的函数虽然易于使用，但是它们不能满足响应规模的需要。而完成端口机制是针对操作系统内部进行了优化，在Windows NT 和 Windows 2000上，使用了完成端口的重叠I/O机制才能够真正扩大系统的响应规模。</p>
		<p>
				<font color="#009999">
						<strong>完成端口</strong>
				</font>
		</p>
		<p>一个完成端口其实就是一个通知队列，由操作系统把已经完成的重叠I/O请求的通知放入其中。当某项I/O操作一旦完成，某个可以对该操作结果进行处理的工作者线程就会收到一则通知。而套接字在被创建后，可以在任何时候与某个完成端口进行关联。</p>
		<p>通常情况下，我们会在应用程序中创建一定数量的工作者线程来处理这些通知。线程数量取决于应用程序的特定需要。理想的情况是，线程数量等于处理器的数量，不过这也要求任何线程都不应该执行诸如同步读写、等待事件通知等阻塞型的操作，以免线程阻塞。每个线程都将分到一定的CPU时间，在此期间该线程可以运行，然后另一个线程将分到一个时间片并开始执行。如果某个线程执行了阻塞型的操作，操作系统将剥夺其未使用的剩余时间片并让其它线程开始执行。也就是说，前一个线程没有充分使用其时间片，当发生这样的情况时，应用程序应该准备其它线程来充分利用这些时间片。</p>
		<p>完成端口的使用分为两步。首先创建完成端口，如以下代码所示：<br /></p>
		<pre>HANDLE    hIocp;
hIocp = CreateIoCompletionPort(
    INVALID_HANDLE_VALUE,
    NULL,
    (ULONG_PTR)0,
    0);
if (hIocp == NULL) {
    // Error
}
</pre>完成端口创建后，要把将使用该完成端口的套接字与之关联起来。方法是再次调用CreateIoCompletionPort ()函数，第一个参数FileHandle设为套接字的句柄，第二个参数ExistingCompletionPort 设为刚刚创建的那个完成端口的句柄。<br />以下代码创建了一个套接字，并把它和前面创建的完成端口关联起来： <pre>SOCKET    s;

s = socket(AF_INET, SOCK_STREAM, 0);
if (s == INVALID_SOCKET) {
    // Error
if (CreateIoCompletionPort((HANDLE)s,
                           hIocp,
                           (ULONG_PTR)0,
                           0) == NULL)
{
// Error
}
...
}
</pre><br />这时就完成了套接字与完成端口的关联操作。在这个套接字上进行的任何重叠操作都将通过完成端口发出完成通知。注意，CreateIoCompletionPort()函数中的第三个参数用来设置一个与该套接字相关的“完成键(completion key)”(译者注：完成键可以是任何数据类型)。每当完成通知到来时，应用程序可以读取相应的完成键，因此，完成键可用来给套接字传递一些背景信息。 
<p>在创建了完成端口、将一个或多个套接字与之相关联之后，我们就要创建若干个线程来处理完成通知。这些线程不断循环调用GetQueuedCompletionStatus ()函数并返回完成通知。</p><p>下面，我们先来看看应用程序如何跟踪这些重叠操作。当应用程序调用一个重叠操作函数时，要把指向一个overlapped结构的指针包括在其参数中。当操作完成后，我们可以通过GetQueuedCompletionStatus()函数中拿回这个指针。不过，单是根据这个指针所指向的overlapped 结构，应用程序并不能分辨究竟完成的是哪个操作。要实现对操作的跟踪，你可以自己定义一个OVERLAPPED结构，在其中加入所需的跟踪信息。</p><p>无论何时调用重叠操作函数时，总是会通过其lpOverlapped参数传递一个OVERLAPPEDPLUS结构(例如WSASend、 WSARecv等函数)。这就允许你为每一个重叠调用操作设置某些操作状态信息，当操作结束后，你可以通过 GetQueuedCompletionStatus()函数获得你自定义结构的指针。注意OVERLAPPED字段不要求一定是这个扩展后的结构的第一个字段。当得到了指向OVERLAPPED结构的指针以后，可以用CONTAINING_RECORD宏取出其中指向扩展结构的指针。</p><p>OVERLAPPED 结构的定义如下：</p><pre>typedef struct _OVERLAPPEDPLUS {
    OVERLAPPED        ol;
    SOCKET            s, sclient;
    int               OpCode;
    WSABUF            wbuf;
    DWORD             dwBytes, dwFlags;
    // 其它有用的信息
} OVERLAPPEDPLUS;

#define OP_READ     0
#define OP_WRITE    1
#define OP_ACCEPT   2

</pre>下面让我们来看看工作者线程的情况。<br /><br />工作线程WorkerThread代码： <pre>DWORD WINAPI WorkerThread(LPVOID lpParam)
{    
    ULONG_PTR       *PerHandleKey;
    OVERLAPPED      *Overlap;
    OVERLAPPEDPLUS  *OverlapPlus,
                    *newolp;
    DWORD           dwBytesXfered;

    while (1)
    {
        ret = GetQueuedCompletionStatus(
            hIocp,
            &amp;dwBytesXfered,
            (PULONG_PTR)&amp;PerHandleKey,
            &amp;Overlap,
            INFINITE);
        if (ret == 0)
        {
            // Operation failed
            continue;
        }
        OverlapPlus = CONTAINING_RECORD(Overlap, OVERLAPPEDPLUS, ol);
    
    switch (OverlapPlus-&gt;OpCode)
    {
    case OP_ACCEPT:
        // Client socket is contained in OverlapPlus.sclient
        // Add client to completion port
            CreateIoCompletionPort(
                (HANDLE)OverlapPlus-&gt;sclient,
                hIocp,
                (ULONG_PTR)0,
                0);

        //  Need a new OVERLAPPEDPLUS structure
        //  for the newly accepted socket. Perhaps
        //  keep a look aside list of free structures.
        newolp = AllocateOverlappedPlus();
        if (!newolp)
        {
            // Error
        }
        newolp-&gt;s = OverlapPlus-&gt;sclient;
        newolp-&gt;OpCode = OP_READ;

        // This function prepares the data to be sent
        PrepareSendBuffer(&amp;newolp-&gt;wbuf);
  
        ret = WSASend(
                newolp-&gt;s,
                &amp;newolp-&gt;wbuf,
                1,
                &amp;newolp-&gt;dwBytes,
                0,
                &amp;newolp.ol,
                NULL);
        
        if (ret == SOCKET_ERROR)
        {
            if (WSAGetLastError() != WSA_IO_PENDING)
            {
            // Error
            }
        }

        // Put structure in look aside list for later use
        FreeOverlappedPlus(OverlapPlus);

        // Signal accept thread to issue another AcceptEx
        SetEvent(hAcceptThread);
        break;

    case OP_READ:
        // Process the data read    
        // ...

        // Repost the read if necessary, reusing the same
        // receive buffer as before
        memset(&amp;OverlapPlus-&gt;ol, 0, sizeof(OVERLAPPED));
        ret = WSARecv(
              OverlapPlus-&gt;s,
              &amp;OverlapPlus-&gt;wbuf,
              1,
              &amp;OverlapPlus-&gt;dwBytes,
              &amp;OverlapPlus-&gt;dwFlags,
              &amp;OverlapPlus-&gt;ol,
              NULL);

        if (ret == SOCKET_ERROR)
        {
            if (WSAGetLastError() != WSA_IO_PENDING)
            {
                // Error
            }
        }
        break;

    case OP_WRITE:
        // Process the data sent, etc.
        break;
    } // switch
    } // while
}  // WorkerThread

</pre>其中每句柄键(PerHandleKey)变量的内容，是在把完成端口与套接字进行关联时所设置的完成键参数；Overlap参数返回的是一个指向发出重叠操作时所使用的那个OVERLAPPEDPLUS结构的指针。 
<p>要记住，如果重叠操作调用失败时(也就是说，返回值是SOCKET_ERROR，并且错误原因不是WSA_IO_PENDING)，那么完成端口将不会收到任何完成通知。如果重叠操作调用成功，或者发生原因是WSA_IO_PENDING的错误时，完成端口将总是能够收到完成通知。<br /><br /><strong><font color="#009999">Windows NT和Windows 2000的套接字架构</font></strong><br /><br />对于开发大响应规模的Winsock应用程序而言，对Windows NT和Windows 2000的套接字架构有基本的了解是很有帮助的。下图是Windows 2000中的Winsock架构：<br /><img height="231" src="http://www.vckbase.com/document/journal/vckbase50/images/winsockfig03.gif" width="200" /></p><p>与其它类型操作系统不同，Windows NT和Windows 2000的传输协议没有一种风格像套接字那样的、可以和应用程序直接交谈的界面，而是采用了一种更为底层的API，叫做传输驱动程序界面(Transport Driver Interface,TDI)。Winsock的核心模式驱动程序负责连接和缓冲区管理，以便向应用程序提供套接字仿真(在AFD.SYS文件中实现)，同时负责与底层传输驱动程序对话。</p><p><strong><font color="#009999">谁来负责管理缓冲区？</font></strong><br /><br />正如上面所说的，应用程序通过Winsock来和传输协议驱动程序交谈，而AFD.SYS负责为应用程序进行缓冲区管理。也就是说，当应用程序调用 send()或WSASend()函数来发送数据时，AFD.SYS将把数据拷贝进它自己的内部缓冲区(取决于SO_SNDBUF设定值)，然后send ()或WSASend()函数立即返回。也可以这么说，AFD.SYS在后台负责把数据发送出去。不过，如果应用程序要求发出的数据超过了 SO_SNDBUF设定的缓冲区大小，那么WSASend()函数会阻塞，直至所有数据发送完毕。</p><p>从远程客户端接收数据的情况也类似。只要不用从应用程序那里接收大量的数据，而且没有超出SO_RCVBUF设定的值，AFD.SYS将把数据先拷贝到其内部缓冲区中。当应用程序调用recv()或WSARecv()函数时，数据将从内部缓冲拷贝到应用程序提供的缓冲区。</p><p>多数情况下，这样的架构运行良好，特别在是应用程序采用传统的套接字下非重叠的send()和receive()模式编写的时候。不过程序员要小心的是，尽管可以通过setsockopt()这个API来把SO_SNDBUF和SO_RCVBUF选项值设成0(关闭内部缓冲区)，但是程序员必须十分清楚把 AFD.SYS的内部缓冲区关掉会造成什么后果，避免收发数据时有关的缓冲区拷贝可能引起的系统崩溃。</p><p>举例来说，一个应用程序通过设定SO_SNDBUF为0把缓冲区关闭，然后发出一个阻塞send()调用。在这样的情况下，系统内核会把应用程序的缓冲区锁定，直到接收方确认收到了整个缓冲区后send()调用才返回。似乎这是一种判定你的数据是否已经为对方全部收到的简洁的方法，实际上却并非如此。想想看，即使远端TCP 通知数据已经收到，其实也根本不代表数据已经成功送给客户端应用程序，比如对方可能发生资源不足的情况，导致AFD.SYS不能把数据拷贝给应用程序。另一个更要紧的问题是，在每个线程中每次只能进行一次发送调用，效率极其低下。</p><p>把SO_RCVBUF设为0，关闭AFD.SYS的接收缓冲区也不能让性能得到提升，这只会迫使接收到的数据在比Winsock更低的层次进行缓冲，当你发出receive调用时，同样要进行缓冲区拷贝，因此你本来想避免缓冲区拷贝的阴谋不会得逞。</p><p>现在我们应该清楚了，关闭缓冲区对于多数应用程序而言并不是什么好主意。只要要应用程序注意随时在某个连接上保持几个WSARecvs重叠调用，那么通常没有必要关闭接收缓冲区。如果AFD.SYS总是有由应用程序提供的缓冲区可用，那么它将没有必要使用内部缓冲区。</p><p>高性能的服务器应用程序可以关闭发送缓冲区，同时不会损失性能。不过，这样的应用程序必须十分小心，保证它总是发出多个重叠发送调用，而不是等待某个重叠发送结束了才发出下一个。如果应用程序是按一个发完再发下一个的顺序来操作，那浪费掉两次发送中间的空档时间，总之是要保证传输驱动程序在发送完一个缓冲区后，立刻可以转向另一个缓冲区。</p><p><font color="#009999"><strong>资源的限制条件</strong></font></p><p>在设计任何服务器应用程序时，其强健性是主要的目标。也就是说，</p><p>你的应用程序要能够应对任何突发的问题，例如并发客户请求数达到峰值、可用内存临时出现不足、以及其它短时间的现象。这就要求程序的设计者注意Windows NT和2000系统下的资源限制条件的问题，从容地处理突发性事件。</p><p>你可以直接控制的、最基本的资源就是网络带宽。通常，使用用户数据报协议(UDP)的应用程序都可能会比较注意带宽方面的限制，以最大限度地减少包的丢失。然而，在使用TCP连接时，服务器必须十分小心地控制好，防止网络带宽过载超过一定的时间，否则将需要重发大量的包或造成大量连接中断。关于带宽管理的方法应根据不同的应用程序而定，这超出了本文讨论的范围。</p><p>虚拟内存的使用也必须很小心地管理。通过谨慎地申请和释放内存，或者应用lookaside lists(一种高速缓存)技术来重新使用已分配的内存，将有助于控制服务器应用程序的内存开销(原文为“让服务器应用程序留下的脚印小一点”)，避免操作系统频繁地将应用程序申请的物理内存交换到虚拟内存中(原文为“让操作系统能够总是把更多的应用程序地址空间更多地保留在内存中”)。你也可以通过 SetWorkingSetSize()这个Win32 API让操作系统分配给你的应用程序更多的物理内存。</p><p>在使用Winsock时还可能碰到另外两个非直接的资源不足情况。一个是被锁定的内存页面的极限。如果你把AFD.SYS的缓冲关闭，当应用程序收发数据时，应用程序缓冲区的所有页面将被锁定到物理内存中。这是因为内核驱动程序需要访问这些内存，在此期间这些页面不能交换出去。如果操作系统需要给其它应用程序分配一些可分页的物理内存，而又没有足够的内存时就会发生问题。我们的目标是要防止写出一个病态的、锁定所有物理内存、让系统崩溃的程序。也就是说，你的程序锁定内存时，不要超出系统规定的内存分页极限。</p><p>在Windows NT和2000系统上，所有应用程序总共可以锁定的内存大约是物理内存的1/8(不过这只是一个大概的估计，不是你计算内存的依据)。如果你的应用程序不注意这一点，当你的发出太多的重叠收发调用，而且I/O没来得及完成时，就可能偶尔发生ERROR_INSUFFICIENT_RESOURCES的错误。在这种情况下你要避免过度锁定内存。同时要注意，系统会锁定包含你的缓冲区所在的整个内存页面，因此缓冲区靠近页边界时是有代价的(译者理解，缓冲区如果正好超过页面边界，那怕是1个字节，超出的这个字节所在的页面也会被锁定)。</p><p>另外一个限制是你的程序可能会遇到系统未分页池资源不足的情况。所谓未分页池是一块永远不被交换出去的内存区域，这块内存用来存储一些供各种内核组件访问的数据，其中有的内核组件是不能访问那些被交换出去的页面空间的。Windows NT和2000的驱动程序能够从这个特定的未分页池分配内存。</p><p>当应用程序创建一个套接字(或者是类似的打开某个文件)时，内核会从未分页池中分配一定数量的内存，而且在绑定、连接套接字时，内核又会从未分页池中再分配一些内存。当你注意观察这种行为时你将发现，如果你发出某些I/O请求时(例如收发数据)，你会从未分页池里再分配多一些内存(比如要追踪某个待决的 I/O操作，你可能需要给这个操作添加一个自定义结构，如前文所提及的)。最后这就可能会造成一定的问题，操作系统会限制未分页内存的用量。</p><p>在Windows NT和2000这两种操作系统上，给每个连接分配的未分页内存的具体数量是不同的，未来版本的Windows很可能也不同。为了使应用程序的生命期更长，你就不应该计算对未分页池内存的具体需求量。</p><p>你的程序必须防止消耗到未分页池的极限。当系统中未分页池剩余空间太小时，某些与你的应用程序毫无关系的内核驱动就会发疯，甚至造成系统崩溃，特别是当系统中有第三方设备或驱动程序时，更容易发生这样的惨剧(而且无法预测)。同时你还要记住，同一台电脑上还可能运行有其它同样消耗未分页池的其它应用程序，因此在设计你的应用程序时，对资源量的预估要特别保守和谨慎。</p><p>处理资源不足的问题是十分复杂的，因为发生上述情况时你不会收到特别的错误代码，通常你只能收到一般性的WSAENOBUFS或者ERROR_INSUFFICIENT_RESOURCES 错误。要处理这些错误，首先，把你的应用程序工作配置调整到合理的最大值(译者注：所谓工作配置，是指应用程序各部分运行中所需的内存用量，请参考 <a href="http://msdn.microsoft.com/msdnmag/issues/1000/Bugslayer/Bugslayer1000.asp" target="_blank">http://msdn.microsoft.com/msdnmag/issues/1000/Bugslayer/Bugslayer1000.asp</a> ，关于内存优化，译者另有译文)，如果错误继续出现，那么注意检查是否是网络带宽不足的问题。之后，请确认你没有同时发出太多的收发调用。最后，如果还是收到资源不足的错误，那就很可能是遇到了未分页内存池不足的问题了。要释放未分页内存池空间，请关闭应用程序中相当部分的连接，等待系统自行渡过和修正这个瞬时的错误。<br /><br /><strong><font color="#009999">接受连接请求</font></strong><br /><br />服务器要做的最普通的事情之一就是接受来自客户端的连接请求。在套接字上使用重叠I/O接受连接的惟一API就是AcceptEx()函数。有趣的是，通常的同步接受函数accept()的返回值是一个新的套接字，而AcceptEx()函数则需要另外一个套接字作为它的参数之一。这是因为 AcceptEx()是一个重叠操作，所以你需要事先创建一个套接字(但不要绑定或连接它)，并把这个套接字通过参数传给AcceptEx()。以下是一小段典型的使用AcceptEx()的伪代码： </p><pre>do {
    -等待上一个 AcceptEx 完成
    -创建一个新套接字并与完成端口进行关联
    -设置背景结构等等
    -发出一个 AcceptEx 请求
}while(TRUE);</pre>作为一个高响应能力的服务器，它必须发出足够的AcceptEx调用，守候着，一旦出现客户端连接请求就立刻响应。至于发出多少个AcceptEx才够，就取决于你的服务器程序所期待的通信交通类型。比如，如果进入连接率高的情况(因为连接持续时间较短，或者出现交通高峰)，那么所需要守候的 AcceptEx当然要比那些偶尔进入的客户端连接的情况要多。聪明的做法是，由应用程序来分析交通状况，并调整AcceptEx守候的数量，而不是固定在某个数量上。 
<p>对于Windows2000，Winsock提供了一些机制，帮助你判定AcceptEx的数量是否足够。这就是，在创建监听套接字时创建一个事件，通过WSAEventSelect()这个API并注册FD_ACCEPT事件通知来把套接字和这个事件关联起来。一旦系统收到一个连接请求，如果系统中没有AcceptEx()正在等待接受连接，那么上面的事件将收到一个信号。通过这个事件，你就可以判断你有没有发出足够的 AcceptEx()，或者检测出一个非正常的客户请求(下文述)。这种机制对Windows NT 4.0不适用。</p><p>使用AcceptEx()的一大好处是，你可以通过一次调用就完成接受客户端连接请求和接受数据(通过传送lpOutputBuffer参数)两件事情。也就是说，如果客户端在发出连接的同时传输数据，你的AcceptEx()调用在连接创建并接收了客户端数据后就可以立刻返回。这样可能是很有用的，但是也可能会引发问题，因为AcceptEx()必须等全部客户端数据都收到了才返回。具体来说，如果你在发出AcceptEx()调用的同时传递了lpOutputBuffer参数，那么AcceptEx()不再是一项原子型的操作，而是分成了两步：接受客户连接，等待接收数据。当缺少一种机制来通知你的应用程序所发生的这种情况：“连接已经建立了，正在等待客户端数据”，这将意味着有可能出现客户端只发出连接请求，但是不发送数据。如果你的服务器收到太多这种类型的连接时，它将拒绝连接更多的合法客户端请求。这就是黑客进行“拒绝服务”攻击的常见手法。</p><p>要预防此类攻击，接受连接的线程应该不时地通过调用getsockopt()函数(选项参数为 SO_CONNECT_TIME)来检查AcceptEx()里守候的套接字。getsockopt()函数的选项值将被设置为套接字被连接的时间，或者设置为-1(代表套接字尚未建立连接)。这时，WSAEventSelect()的特性就可以很好地利用来做这种检查。如果发现连接已经建立，但是很久都没有收到数据的情况，那么就应该终止连接，方法就是关闭作为参数提供给AcceptEx()的那个套接字。注意，在多数非紧急情况下，如果套接字已经传递给AcceptEx()并开始守候，但还未建立连接，那么你的应用程序不应该关闭它们。这是因为即使关闭了这些套接字，出于提高系统性能的考虑，在连接进入之前，或者监听套接字自身被关闭之前，相应的内核模式的数据结构也不会被干净地清除。</p><p>发出AcceptEx()调用的线程，似乎与那个进行完成端口关联操作、处理其它I/O完成通知的线程是同一个，但是，别忘记线程里应该尽力避免执行阻塞型的操作。Winsock2分层结构的一个副作用是调用socket()或WSASocket() API的上层架构可能很重要(译者不太明白原文意思，抱歉)。每个AcceptEx()调用都需要创建一个新套接字，所以最好有一个独立的线程专门调用AcceptEx()，而不参与其它I/O处理。你也可以利用这个线程来执行其它任务，比如事件记录。</p><p>有关AcceptEx()的最后一个注意事项：要实现这些API，并不需要其它提供商提供的Winsock2实现。这一点对微软特有的其它API也同样适用，比如TransmitFile()和GetAcceptExSockAddrs()，以及其它可能会被加入到新版Windows的API. 在Windows NT和2000上，这些API是在微软的底层提供者DLL(mswsock.dll)中实现的，可通过与mswsock.lib编译连接进行调用，或者通过WSAIoctl() (选项参数为SIO_GET_EXTENSION_FUNCTION_POINTER)动态获得函数的指针。</p><p>如果在没有事先获得函数指针的情况下直接调用函数(也就是说，编译时静态连接mswsock.lib，在程序中直接调用函数)，那么性能将很受影响。因为 AcceptEx()被置于Winsock2架构之外，每次调用时它都被迫通过WSAIoctl()取得函数指针。要避免这种性能损失，需要使用这些 API的应用程序应该通过调用WSAIoctl()直接从底层的提供者那里取得函数的指针。<br /><br />参见下图套接字架构： <br /><img height="231" src="http://www.vckbase.com/document/journal/vckbase50/images/winsockfig03.gif" width="200" /><br /><br /><br /><strong><font color="#009999">TransmitFile 和 TransmitPackets </font></strong><br /><br />Winsock 提供两个专门为文件和内存数据传输进行了优化的函数。其中TransmitFile()这个API函数在Windows NT 4.0 和 Windows 2000上都可以使用，而TransmitPackets()则将在未来版本的Windows中实现。</p><p>TransmitFile ()用来把文件内容通过Winsock进行传输。通常发送文件的做法是，先调用CreateFile()打开一个文件，然后不断循环调用ReadFile () 和WSASend ()直至数据发送完毕。但是这种方法很没有效率，因为每次调用ReadFile() 和 WSASend ()都会涉及一次从用户模式到内核模式的转换。如果换成TransmitFile()，那么只需要给它一个已打开文件的句柄和要发送的字节数，而所涉及的模式转换操作将只在调用CreateFile()打开文件时发生一次，然后TransmitFile()时再发生一次。这样效率就高多了。</p><p>TransmitPackets()比TransmitFile()更进一步，它允许用户只调用一次就可以发送指定的多个文件和内存缓冲区。函数原型如下：<br /></p><pre>BOOL TransmitPackets(
  SOCKET hSocket,                             
  LPTRANSMIT_PACKET_ELEMENT lpPacketArray,
  DWORD nElementCount,                
  DWORD nSendSize,                
  LPOVERLAPPED lpOverlapped,                  
  DWORD dwFlags                               
); </pre>其中，lpPacketArray是一个结构的数组，其中的每个元素既可以是一个文件句柄或者内存缓冲区，该结构定义如下：<br /><pre>typedef struct _TRANSMIT_PACKETS_ELEMENT { 
    DWORD dwElFlags; 
    DWORD cLength; 
    union {
        struct {
            LARGE_INTEGER     nFileOffset;
            HANDLE            hFile;
            };
            PVOID             pBuffer;
    };
} TRANSMIT_FILE_BUFFERS;
</pre>其中各字段是自描述型的(self explanatory)。<br />dwElFlags字段：指定当前元素是一个文件句柄还是内存缓冲区(分别通过常量TF_ELEMENT_FILE 和TF_ELEMENT_MEMORY指定)；<br />cLength字段：指定将从数据源发送的字节数(如果是文件，这个字段值为0表示发送整个文件)；<br />结构中的无名联合体：包含文件句柄的内存缓冲区(以及可能的偏移量)。 
<p>使用这两个API的另一个好处，是可以通过指定TF_REUSE_SOCKET和TF_DISCONNECT标志来重用套接字句柄。每当API完成数据的传输工作后，就会在传输层级别断开连接，这样这个套接字就又可以重新提供给AcceptEx()使用。采用这种优化的方法编程，将减轻那个专门做接受操作的线程创建套接字的压力(前文述及)。</p><p>这两个API也都有一个共同的弱点：Windows NT Workstation 或 Windows 2000 专业版中，函数每次只能处理两个调用请求，只有在Windows NT、Windows 2000服务器版、Windows 2000高级服务器版或 Windows 2000 Data Center中才获得完全支持。</p><p><font color="#009999"><strong>放在一起看看</strong></font></p><p>以上各节中，我们讨论了开发高性能的、大响应规模的应用程序所需的函数、方法和可能遇到的资源瓶颈问题。这些对你意味着什么呢？其实，这取决于你如何构造你的服务器和客户端。当你能够在服务器和客户端设计上进行更好地控制时，那么你越能够避开瓶颈问题。</p><p>来看一个示范的环境。我们要设计一个服务器来响应客户端的连接、发送请求、接收数据以及断开连接。那么，服务器将需要创建一个监听套接字，把它与某个完成端口进行关联，为每颗CPU创建一个工作线程。再创建一个线程专门用来发出AcceptEx()。我们知道客户端会在发出连接请求后立刻传送数据，所以如果我们准备好接收缓冲区会使事情变得更为容易。当然，不要忘记不时地轮询AcceptEx()调用中使用的套接字(使用SO_CONNECT_TIME选项参数)来确保没有恶意超时的连接。</p><p>该设计中有一个重要的问题要考虑，我们应该允许多少个AcceptEx()进行守候。这是因为，每发出一个AcceptEx()时我们都同时需要为它提供一个接收缓冲区，那么内存中将会出现很多被锁定的页面(前文说过了，每个重叠操作都会消耗一小部分未分页内存池，同时还会锁定所有涉及的缓冲区)。这个问题很难回答，没有一个确切的答案。最好的方法是把这个值做成可以调整的，通过反复做性能测试，你就可以得出在典型应用环境中最佳的值。</p><p>好了，当你测算清楚后，下面就是发送数据的问题了，考虑的重点是你希望服务器同时处理多少个并发的连接。通常情况下，服务器应该限制并发连接的数量以及等候处理的发送调用。因为并发连接数量越多，所消耗的未分页内存池也越多；等候处理的发送调用越多，被锁定的内存页面也越多(小心别超过了极限)。这同样也需要反复测试才知道答案。</p><p>对于上述环境，通常不需要关闭单个套接字的缓冲区，因为只在AcceptEx()中有一次接收数据的操作，而要保证给每个到来的连接提供接收缓冲区并不是太难的事情。但是，如果客户机与服务器交互的方式变一变，客户机在发送了一次数据之后，还需要发送更多的数据，在这种情况下关闭接收缓冲就不太妙了，除非你想办法保证在每个连接上都发出了重叠接收调用来接收更多的数据。</p><p><font color="#009999"><strong>结论</strong></font></p><p>开发大响应规模的Winsock服务器并不是很可怕，其实也就是设置一个监听套接字、接受连接请求和进行重叠收发调用。通过设置合理的进行守候的重叠调用的数量，防止出现未分页内存池被耗尽，这才是最主要的挑战。按照我们前面讨论的一些原则，你就可以开发出大响应规模的服务器应用程序。</p><img src ="http://www.cppblog.com/zgysx/aggbug/17216.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zgysx/" target="_blank">永遇乐</a> 2007-01-04 13:42 <a href="http://www.cppblog.com/zgysx/archive/2007/01/04/17216.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>让List Control有Check Box 和 让List Box有Check Box</title><link>http://www.cppblog.com/zgysx/archive/2006/12/30/17030.html</link><dc:creator>永遇乐</dc:creator><author>永遇乐</author><pubDate>Sat, 30 Dec 2006 05:30:00 GMT</pubDate><guid>http://www.cppblog.com/zgysx/archive/2006/12/30/17030.html</guid><wfw:comment>http://www.cppblog.com/zgysx/comments/17030.html</wfw:comment><comments>http://www.cppblog.com/zgysx/archive/2006/12/30/17030.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/zgysx/comments/commentRss/17030.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zgysx/services/trackbacks/17030.html</trackback:ping><description><![CDATA[
		<p>
				<font color="#008000">
						<strong>1.让List Control有Check Box</strong>
				</font>
				<br />用SetExtendedStyle方法可以设置，看代码：<br />（CListCtrl m_ListCtrl;）</p>
		<p>DWORD dwStyle = m_ListCtrl.GetStyle();<br />dwStyle |= LVS_EX_CHECKBOXES;<br />m_ListCtrl.SetExtendedStyle(dwStyle);</p>
		<p>
				<font color="#008000">
						<strong>2.让List Box有Check Box</strong>
				</font>
				<br />首先，声明Control变量的时候用CCheckListBox代替CListBox。<br />然后，将List Box的Has Strings属性改为True；把Ower Draw属性改为Fixed。</p>
<img src ="http://www.cppblog.com/zgysx/aggbug/17030.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zgysx/" target="_blank">永遇乐</a> 2006-12-30 13:30 <a href="http://www.cppblog.com/zgysx/archive/2006/12/30/17030.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]电子书下载网址大全</title><link>http://www.cppblog.com/zgysx/archive/2006/12/29/16990.html</link><dc:creator>永遇乐</dc:creator><author>永遇乐</author><pubDate>Fri, 29 Dec 2006 09:22:00 GMT</pubDate><guid>http://www.cppblog.com/zgysx/archive/2006/12/29/16990.html</guid><wfw:comment>http://www.cppblog.com/zgysx/comments/16990.html</wfw:comment><comments>http://www.cppblog.com/zgysx/archive/2006/12/29/16990.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/zgysx/comments/commentRss/16990.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zgysx/services/trackbacks/16990.html</trackback:ping><description><![CDATA[http://asp2.6to23.com/blueshand/default.asp <br />http://www.mycnknow.com/srindex.htm <br />http://pcbook.godcn.net/ <br />http://www.helpwork.net/ <br />http://www.chinathink.net/edown/default.asp <br />http://www.ebook007.com/ <br />http://www.bbook.net/gb/books/booksdefault.asp <br />http://www.hlepwork.net/ <br />http://www.mycnknow.com/srindex.htm <br />http://www.pcbookcn.com/ <br />http://www.ebooksou.com/ <br />http://bingle.pku.edu.cn/ <br />ftp://dlking:good_guy@coolwoo.dlking.com/ <br />http://www.xiaomai.org/ <br />http://www.pcbookcn.com/ <br />http://www.epubcn.com/ <br />http://www.id163.com/ <br />http://www.vvsoft.net/vvbksd/index.asp <br />http://free.21cn.com/lobby/zls/indexxux.htm <br />http://www.marcocantu.com/ <br />http://www.taishen.net/ebook/ <br />http://wlbookwl.myrice.com/c2book.htm <br />http://www.readease.com/ <br />http://wenxue.lycos.com.cn/ <br />http://www.taishen.net/ebook/ <br />http://www.helpwork.com/ <br />http://extend.hk.hi.cn/~kehubu/VBbooks.htm <br />http://ojava.uhome.net/ <br />http://www.mycnknow.com/ <br />http://www.pcbookcn.com/ <br />http://www.epubcn.com/ <br />http://free.21cn.com/lobby/zls/indexxux.htm <br />http://www.ebook007.com/ <br />http://www.ebooksou.com/ <br />http://www.hao123.com/book.htm <br />ftp://166.111.164.147/ <br />http://www.helpwork.com/ <br />http://www.epubcn.com/ <br />http://www.yuyux.com/ <br />http://www.oklink.net/ <br />http://home.eshunet.com/ <br />http://www.ebook007.com/ <br />http://www.shuku.net:8080/ <br />http://www.eshunet.com/ <br />http://www.epubcn.com/ <br />http://www.jetdown.com/ <br />http://www.winmag.com.cn/forum/ <br />http://pcbook.godcn.net/帝华咨讯网 <br />http://www.vckbase.com/VC知识库 <br />http://www.helpwork.net/博士网 <br />http://www.dev-club.com/ <br />http://www.aspxcn.com/.NET中华网 <br />http://www.51itworld.com/无忧IT世界 <br />http://www.netsquare.com/netbook/电脑书籍 <br />http://www.5566.org/prog-.htm【程 ?序】 <br />http://www.tinydust.com/微尘程序员网站 <br />http://www.comjoe.com/中国程序员网 <br />http://www.ccidnet.com/赛迪网 <br />http://www.programmersheaven.com/Programmers Heaven <br />http://www.huachu.com.cn/华储网 <br />http://yuyu.6to23.com/非常书城 <br />http://www.china-pub.com/也可以买书 <br />http://pcbook.51soft.com/无忧书库,网页字体效果极棒！ <br />http://www.dingbing.com/book/ <br />http://www.eshunet.come/书时空 <br />http://zjfeng.topcool.net/song.htm电脑书籍 <br />http://www.eng.stu.edu.cn/ebook/电脑书籍 <br />http://www.godcn.net/school/ <br />http://gshulkin.hypermart.net/books/FreeVBBook.html <br />http://www.monumental.com/boat/computerbooks.html <br />http://www.rokinc.cjb.net/电脑书籍 <br />http://www.pcbookcn.com/中华电脑书库 <br />http://www.cnforyou.com/上海网上书店 <br />http://ebook.0451.net/html/js139/11/book1.htmWINDOWS 95/98操作系统编程实例详解 <br />http://www.umlchina.com/ <br />202.192.154.5/ebook/index.asp <br />China: ://www.ibm.com/developerWorks/cn/download/mirror/bruceeckel/ <br />China: <a href="http://biubiu.at.china.com/download/book/eckel" target="_blank"><font color="#000000">http://biubiu.at.china.com/download/book/eckel </font></a><br />China: <a href="http://javachina.yeah.net/design" target="_blank"><font color="#000000">http://javachina.yeah.net/design </font></a><br />China: <a href="http://louisxiv.home.chinaren.com/" target="_blank"><font color="#000000">http://louisxiv.home.chinaren.com/ </font></a><br />China: <a href="http://proxy.iini.com/eckel/" target="_blank"><font color="#000000">http://proxy.iini.com/eckel/ </font></a><br />China: <a href="http://www.jiangnan.edu.cn/" target="_blank"><font color="#000000">http://www.jiangnan.edu.cn/ </font></a><br />China: <a href="http://www.lelf.net/lelf/download/tij/" target="_blank"><font color="#000000">http://www.lelf.net/lelf/download/tij/ </font></a><br />ftp.gargoylewiz.dynip.com <br />ftp.gargoylewiz.dynip.com <br />ftp.gargoylewiz.dynip.com <br />ftp://128.32.208.109/.NWNK-FxP/_vti_pvt/_vti_pub <br />ftp://141.133.239.239/.%20scanned%2...oaded/by%20blue <br />ftp://166.111.132.3 /<br />ftp://166.111.160.4 /<br />ftp://166.111.164.147/ <br />ftp://166.111.174.33 /<br />ftp://203.198.80.44/test/ilifebacku...%20by%20p/Bookz <br />ftp://209.196.62.156/_vti_pvt/.pmbd <br />ftp://209.204.119.253/temp/damoak/ <br />ftp://216.0.51.50/~tmp/.%20for/%7...;%20TutorialZ=- <br />ftp://216.149.46.228/scan/by/damoak/ <br />ftp://216.167.56.173/tmp/damoak/cisco/ <br />ftp://216.233.144.210/~/~tagged%20by%20fietsbeller/ <br />ftp://61.156.23.10/2/.EM/m2w/study/ <br />ftp://cicd.hfut.edu.cn/ <br />ftp://dl3.51soft.com:8384/c_c021.zip《C++高级参考手册》 <br />ftp://ftp.bj.software.chinese.com/s...m/book/1a35.zip <br />ftp://ftp.bupt.edu.cn/pub1/e-book/computer/ <br />ftp://ftp.pim.tsinghua.edu.cn /<br />ftp://ftp.sjtu.edu.cn/document <br />ftp://ftp.tsinghua.edu.cn/pub/ <br />ftp://ftp.tup.tsinghua.edu.cn/C++/ 钱能《c++程序设计教程》那本书的书后习题源码 <br />ftp://ftp.xjtu.edu.cn/pub/document <br />ftp://ftp.xjtu.edu.cn/pub/document <br />ftp://keygen:exam@24.92.14.2:21 /<br />ftp://maestro.den.disa.mil /<br />ftp://win2k:abc123@63.236.67.26/ <br />ftp://win2k:win2000@63.236.67.49/ <br />ftp://wlbookwl:2531382@ftp.diy.myri...book/dosint.zip <br />ftp://wlbookwl:2531382@ftp.diy.myri...k/qianC/001.zip 《钱能C++程序设计》(1) <br />ftp://wlbookwl:2531382@ftp.diy.myri...k/qianC/002.zip 《钱能C++程序设计》(2) <br />target=_blank&gt;<a href="ftp://wlbookwl:2531382@ftp.diy.myri...%e8%9b%8f%e6%9d%93%e5%89%96%e7%ac%9b%e6%a9%b9%e5%82%85%e8%82%8c/?/a%3E" target="_blank"><font color="#000000">ftp://wlbookwl:2531382@ftp.diy.myri...蛏杓剖笛橹傅肌/?/a&gt; </font></a><br />http://202.101.232.120/book/default.asp <br />http://202.103.176.81/erun/sealife/ （主力站点） <br />http://202.96.70.228/cakk/delphi/Wi...喑碳际跄谀?rar <br />http://202.96.70.229/cakk/delphi/delphibbs/dfw.chm <br />http://202.96.70.229/cakk/delphi/do...02000%203rd.chm <br />http://202.96.70.229/cakk/delphi/doc/vc++技术内幕IV(潘爱民).rar <br />http://books.gnaritas.net/Books/Exams/ <br />http://books.zone.ru/ <br />http://cheminf.nankai.edu.cn/DynaDocBooks/ <br />http://computerbooks.address.com/ <br />http://cpp.chinaccd.net/ebook <br />http://cpp.chinaccd.net/ebook/c++byAnwser.rar <br />http://cpp.chinaccd.net/ebook/Effective_C++2e.pdf <br />http://cpp.chinaccd.net/ebook/More%...ctive%20C++.pdf <br />http://cpp.chinaccd.net/ebook/The%2...%20Language.rar <br />http://cpp.chinaccd.net/ebook/Thinkinc++.rar <br />http://delphideveloper.myrice.com/ <br />http://dir.sohu.com/computer/freeservice/computerbooks/ <br />http://download.wz.zj.cn/downhits.a...ebook/mfc2e.zip <br />http://download.wz.zj.cn/downhits.a...ebook/zd001.zip <br />http://download.wz.zj.cn/downhits.a...acker-class.chm <br />http://dzhang.yeah.net/ <br />http://ebook.it-pc.com/ ****时空咨询 <br />http://edu.netbig.com/rank/data/t3/...000402/6403.htm <br />http://frank.533.net/aspbook.html <br />http://ftp.cnuol.com/e_book/±à&amp;sup3;&amp;Igrave;/vc/ <br />http://ftp.cnuol.com/e_book/Unix_Linux/ <br />http://ftp.cnuol.com/e_book/windows/ <br />http://ftp.lib.pku.edu.cn:81/ <br />http://ftp.pcworld.com/pub/internet/ <br />http://ftp.xanet.edu.cn/pub/ <br />http://go7.163.com/~huibian/index.html ? ? ? ?汇编学堂 <br />http://gshulkin.hypermart.net/books/FreeVBBook.html <br />http://home.cyberarmy.com/micromaniz/ <br />http://home.kzinfo.net/getc/ ?内有?..可惜是PDF格式的 <br />http://home.online.tj.cn/~cavendish <br />http://home.wtwh.com.cn/download/ebookshelf.html <br />http://it.263.net/b/book/ <br />http://jjhou.csdn.net/ <br />http://lib.wuhee.edu.cn/book/computer.asp <br />http://linuxgazette.hopestar.org/ <br />http://members.spree.com/education/jackyhft/ <br />http://members.xoom.com/dgss_02 <br />http://oklink.soyou.com/dnsj/index5.htm <br />http://pcbook.51soft.com/ <br />http://pcbook.godcn.net/program/asm/ibmpc.zip IBM PC汇编语言程序设计 <br />http://pcbook.godcon.net/ 《MFC深入浅出》 <br />http://pcbooks.myrice.com/ <br />http://pclub.technoart.net/books/cpplang/ <br />http://rokinc.narod.ru/ <br />http://space.ustc.edu.cn/C++Builder/book/book.php <br />http://teach.wol.com.cn/down/asm/asm.zip 汇编源代码大全 <br />http://tmxcf.topcool.net/bkxzbook1.htm <br />http://toye.yeah.net/ ? ? ? ?密码破解 <br />http://vg.dyndns.org/ebook/ <br />http://web.gmg.ch/zoomout/windows2000/ <br />http://wenxue.lycos.com.cn/level/5011.html <br />http://wlbookwl.myrice.com/ Turboc2 win98ddkinc winsoftice-9x masm32v6.exe <br />http://wlbookwl.myrice.com/book.htm <br />http://www.bookbig.com/culture12.html <br />http://www.books24x7.com/ <br />http://www.bruceeckel.com/DownloadSites/ <br />http://www.certificationcorner.com/2000.htm <br />http://www.chian-pub.com/ <br />http://www.china-pub.com/computers/...ook_XiaZhai.htm <br />http://www.csdn.net/expert/jjhou/wi...opers-guide.pdf <br /><br /><br />http://www.ebooksou.com/ <br />http://www.eng.stu.edu.cn/ebook/ <br />http://www.eshunet.com/list0/08dn.asp <br />http://www.freedrive.com/ASP/PostFo...sp?fsc=15456975 <br />http://www.gbfocus.com/ <br />http://www.godcn.net/school/ ****帝华 <br />http://www.helpwork.net/ %%##???博士网 <br />http://www.helpwork.net/book/html/user/index.asp <br />http://www.helpwork.net/downdata/bo...++2/invcpp5.chm <br />http://www.hktk.com/soft/program/book/index.html <br />http://www.hyedu.com/ <br />http://www.jjhou.com/ <br />http://www.kubao.com/ <br />http://www.laohu.net/ <br />http://www.linuxdoc.org/LDP/lpg/node1.html <br />http://www.mayia.com/downshu/book/c_c015.zip <br />http://www.mayia.com/downshu/bookcity/index.asp <br />http://www.mcsdunion.com/ <br />http://www.mcsebraindumps.com/ <br />http://www.mcsetutor.com/freestuff.html <br />http://www.mikezqz.myetang.com/computeronline.htm <br />http://www.monumental.com/boat/computerbooks.html <br />http://www.net-sky.com/Computers_an...rnet/Education/ <br />http://www.nopayweb.com/ <br />http://www.pcbookcn.com/ <br />http://www.pchome.net/~/LJ/book/book3.htm <br />http://www.qdit.com.cn/software/programm/ <br />http://www.realvb.bizland.com/ <br />http://www.rokinc.cjb.net/ <br />http://www.startvweb.com/Computers_and_Internet <br />http://www.vr3d.com/personal.HTM <br />http://www.vvsoft.net/vvbkss/vvbkss.asp <br />http://www.winsite.com/hot/winnt.html <br />http://www.wuyou.org/wlbookwl/windowshxbc.zip 《windows核心编程》 <br />http://www.wuyou.org/wlbookwl/windowsp5.zip 《Windows程序设计第五版》 <br />http://www8.pconline.com.cn/ <br />http://yangnan.126.com/ ****白菜乐园 <br />http://zhanet.myrice.com/ *****化境 <br />http://zhwm.myrice.com/pcbook/index.htm <br />http://zjfeng.csw.cnshare.net/ <br />http://zjfeng.csw.cnshare.net/ <br />http://zjfeng.csw.cnshare.net/ <br />http://zjfeng.topcool.net/index.html <br />ftp://delphi:delphi@ftp.xxtax.gov.cn/ <br />ms html workshop <br />nihao.dlut.edu.cn/web/book <br />www.3322.net/~shii/TNT/crk_a.htm <br />http://www.helpwork.net/ <br />http://www.tech521.com/ <br />http://www.mycnknow.com/ <br />http://www.readease.com/ <br />http://wenxue.lycos.com.cn/ <br />http://www.taishen.net/ebook/ <br />http://www.helpwork.com/ <br />http://extend.hk.hi.cn/~kehubu/VBbooks.htm <br />http://ojava.uhome.net/ <br />http://www.mycnknow.com/ <br />www.guxiang.com/epubcn <br />http://www.pcbookcn.com/ <br />http://www.epubcn.com/ <br />http://free.21cn.com/lobby/zls/indexxux.htm <br />http://wlbookwl.myrice.com/c2book.htm <br />http://www.yuyux.com/ <br />http://www.ebooksou.com/ <br />http://www.ez-search.com/ <br />http://home.eshunet.com/ <br />http://www.3stonebook.com/ <br />http://www.mypcera.com/book <br />http://www.hao123.com/book.htm <br />ftp://166.111.164.147/ <br />http://www.rokinc.cjb.net/ <br />http://books.zone.ru/ <br />http://members.spree.com/education/jackyhft/ <br />http://www.realvb.bizland.com/ <br />http://lib.wuhee.edu.cn/book/computer.asp <br />http://zhanet.myrice.com/ *****化境 <br />http://it.263.net/b/book/ <br />ftp://win2k:abc123@63.236.67.26/ <br />ftp://216.233.144.210/~/~tagged%20by%20fietsbeller/ <br />http://zjfeng.csw.cnshare.net/ <br />http://vg.dyndns.org/ebook/ <br />http://www.pchome.net/~/LJ/book/book3.htm <br />http://www.mcsebraindumps.com/ <br />http://www.mcsdunion.com/ <br />http://www.kubao.com/ <br />ftp.gargoylewiz.dynip.com <br />http://delphideveloper.myrice.com/ <br />http://www.freedrive.com/ASP/PostFo...sp?fsc=14365878 <br />ftp://maestro.den.disa.mil /<br />http://rokinc.narod.ru/ <br />http://home.cyberarmy.com/micromaniz/ <br />http://www.helpwork.com/ <br />http://www.chinathink.net/edown/default.asp <br />http://www.bbook.net/gb/books/booksdefault.asp <br />http://www.hlepwork.net/ <br />http://www.mycnknow.com/srindex.htm <br />http://www.pcbookcn.com/ <br />http://www.ebooksou.com/ <br />http://bingle.pku.edu.cn/ <br />ftp://dlking:good_guy@coolwoo.dlking.com/ <br />http://www.xiaomai.org/ <br />http://www.pcbookcn.com/ <br />http://www.epubcn.com/ <br />http://www.id163.com/ <br />http://www.vvsoft.net/vvbksd/index.asp <br />http://free.21cn.com/lobby/zls/indexxux.htm <br />http://www.marcocantu.com/ <br />http://www.taishen.net/ebook/ <br /><br /><br />Flash制作高级教程版) <br />ftp://ebook:taishen@202.103.69.76/0293.zip <br /><br />所有诗词总汇-包括年代、作者查询 <br />是一个极全的诗词软件。 <br />http://www.cessd.com.cn/soft1/shici.zip <br /><br />中国鹰派网络安全教程 <br />http://www.zzpaper.com/renren/cn8341-5.rar <br /><br />ASP系列讲座 <br />这是最好的ASP教程，共分9个系列，分别从简到难的介绍ASP的方方面面，带有大量源码作为参考！强烈推荐！！ <br />http://lib.yctc.edu.cn/soft/020301/2128.zip <br /><br />超级菜鸟黑客速成图文教程 <br />http://www.softsdown.net/down/ncchacker.zip <br /><br />Windows XP "手把手" 教程专业版 <br />国外的学习软件实在做的非常出色，不但在技术表现出色（动画结合智能程序），而且设计的非常周到，可以让你来模拟操作XP，虽然是英文版，但还是非常值得推荐。这款软件共有两个版本，一个是针对家庭版（home）的xp教程，一个是针对专业版的教程（其实这个已经包括了家庭版），所以我选择了专业版提供下载，非常值得推荐，尤其是正在使用或打算使用xp的网友。 <br />http://hnftp.soft163.com/xpclass.zip <br /><br />《SQL Server 2000 编程员指南》PDF格式， <br />ftp://dl3.51soft.com:8384/sql004.zip <br /><br />数据结构算法与应用-C 语言描述 <br />本书是关于计算机科学与工程领域的基础性研究科目之一??数据结构与算法的专著。 本书在简要回顾了基本的C++ 程序设计概念的基础上，全面系统地介绍了队列、堆栈、树、图等基本数据结构，以及贪婪算法、分而治之算法、分枝定界算法等多种算法设计方法，为数据结构与算法的继续学习和研究奠定了一个坚实的基础。更为可贵的是，本书不仅仅介绍了理论知识，还提供了50多个应用实例及600多道练习题。本书内容广博权威，结构清晰合理，是一本全新的有关数据结构与算法的教材，对于计算机科学与工程领域的从业人员也是一本很好的参考书。 <br />http://www.dbgnu.com/ebook/85.zip <br /><br />WINDOWS网络编程技术 <br />本书专门讨论Windows网络编程技术，覆盖Windows 95/98/NT 4/2000/CE平台。内容包括NetBIOS和Windows重定向器方法、Winsock方法、客户端远程访问服务器方法。本书论述深入浅出、用大量实例详解了微软网络API函数的应用。配套光盘包含了所有实例代码，方便读者使用。本书适合中、高级程序设计人员以及网络设计与管理人员参考 <br />http://www.dbgnu.com/ebook/60.zip <br /><br />数据通讯与网络教程 <br />本书系统地介绍了数据通信和计算机网络领域的基本内容。在第1版的基础上，修改和增加了新的内容，包括无线和卫星通信、有线电视电缆调制解调器、压缩技术、密码技术、防病毒、100 Mbps以太网、NetWare 4.0、边界网关协议、域名系统、IPv6、异步传送模式、使用客户/服务器模式来实现文件传送协议及开发Web网页等。在内容和结构安排上，注意理论与实际应用的结合，每章后面既有复习题，又有练习题。本书适合作为计算机科学专业本科生的教材，也可供教师和从事该领域设计或应用的研究人员用做参考书 <br />http://www.dbgnu.com/ebook/28.zip <br /><br />中文LOTUS NOTES R5 web高级编程 <br />http://www.kaihong-clothes.com/ebook/150.zip <br /><br />C++ Builder 5编程实例与技巧 <br />前言 2000年上半年，Inprise公司(原Borland公司)推出了C++Builder的最新版本：C++Builder 5。C++Builder 5继承了以前版本的优点，并在此基础上增添了许多新的功能，比如在ADO、数据模块设计、IBX、MIDAS、CORBA、程序调试、VCL、窗体框架和桌面定义等方面都增强了许多，可以极大地提高软件系统的设计、管理和开发的速度。此外，由于C++Builder在学习过程中很容易上手，而且功能也非常强大，尤其在界面设计、Windows编程、数据库编程和网络编程等方面更具独到之处，是其他一些软件开发工具无法比拟的。本书分六个部分，共25章，主要介绍了C++Builder集成开发环境、C++语言关键技术、组件、通用编程技术、动态链接库、多线程、多媒体编程、数据库编程、网络编程和 Windows API编程等。参加本书编写工作的主要有：朱时银、马承志、杨飞和王华等。此外，梁志刚、张延鑫、秦宇海、陈学林、柳海军、叶爱亮、石玉华、倪凤月、詹武平、武少青和郑再军等广泛地进行了资料收集、例程验证，并做了细致的校对。在本书的编写过程中，曹凌云、祁立学、黄家贵、王成、赵雷鸣、刘存根、马兴义和李刚等也提供了许多帮助。尤其感谢张世芳每天打来的电话。机械工业出版社华章公司在本书的出版过程中给予了大力的支持与帮助，在此一并表示衷心的感谢。由于作者水平有限，书中难免存在错误和疏漏之处，恳请读者批评、指正。 编著者 2000年7月 <br /><br /><br />导读本书特色本书具有下面的一些特色： (1) 例程精练、实用、完整，易于查找本书的例程丰富，短小精练。在每章的前面部分，以一定的篇幅对基本理论、知识要点等进行论述；然后以经典的例程加以说明；最后对例程进行分析和总结。书中的例程完整，并全部按照章号进行了编号。在随书的光盘中有这些例程的源代码和编译、链接后的可执行文件。读者可以使用随书光盘中的“复制”程序(可执行文件为D5Samples.exe)将例程复制到硬盘的指定位置，也可以通过资源管理器进行复制。另外，对于每个例程都指定了若干个关键字，可以根据关键字查找相关知识点的例程。 (2) 编程技巧丰富作者将自己在开发程序过程中总结、收集的经验和教训、一些读者在编程过程中遇到的问题等融合在本书中，并且将这些编程技巧尽量独立，便于读者快速查找。 (3) 内容广泛，兼容性强本书几乎涉及了C++Builder编程的所有领域，不仅适用于C++Builder 5，而且也适用于C++Builder 4和C++Builder 3等以前的版本。 (4) 体现了面向对象的技术和软件工程化的思想本书从总体上体现了面向对象程序设计的方法，同时将软件工程化的思想融于其中。内容编排本书主要分为下面的六个部分：第一部分 C++Builder编程基础 C++ Builder编程基础包括：C++Builder集成开发环境的介绍和C++语言的关键技术。第二部分 C++Builder编程通用技术 C++ Builder编程核心技能包括：窗体和组件、菜单、工具栏和状态栏、键盘和鼠标、文件、目录和驱动器以及打印等。第三部分 C++Builder高级编程技术 C++Builder 高级编程技术包括：数据共享、操作注册表、帮助系统的制作、安装与卸载、多线程应用程序、动态链接库和图形与多媒体等技术。第四部分数据库编程数据库编程部分包括：关系数据库、数据库组件、InterBase服务器、OLE DB/ADO和Web与数据库等。第五部分组件对象模型(COM) 组件对象模型(COM)包括：COM和OLE自动化等内容。第六部分分布式程序设计分布式程序设计包括：DCOM、MIDAS、ActiveFORM、CORBA与分布式应用程序，以及其他的一些编程方法与技巧。阅读建议对于C++Builder的初学者，可以按顺序进行阅读。如果读者对C++语言有一定的了解，也可以直接从第二部分开始，待使用C++Builder编程有了一定的经验后，再回过头来看看第一部分的内容。对于C++Builder的中级用户，可以按章节顺序阅读、上机，也可以直接挑选感兴趣的章节学习。值得注意的是，第一部分的内容对使用C++语言进行软件开发非常有用，一定要掌握好。对于C++Builder的高级用户，可以直接挑选感兴趣的章节阅读。 <br />http://www.kaihong-clothes.com/ebook/154.zip <br /><br />《xml高级编程》 <br />好东西，《xml高级编程》可以节约95块大洋！ <br />http://www.dbgnu.com/bcb/ebook/176.zip <br /><br />新编Win32 API大全 <br />ftp://challenger:heijin@211.97.180.8/Win32API.chm <br /><br />南开大学``计算机网络``课程笔记 <br />http://211.81.22.13/download/jisuanjiwangluo.zip <br /><br />自学TCP/IP <br />http://210.40.4.9/s/doc/network/tcpip.zip <br /><br />自学Netware <br />http://210.40.4.9/s/doc/network/NETWARE.zip <br /><br />局域网与Novell安装和指令 <br />http://210.40.4.9/s/doc/network/netnovell.zip <br /><br />计算机网络（适用于系统程序员） <br />http://210.40.4.9/s/doc/network/network.zip <br /><br />UNIX V4.0使用大全。 <br />http://210.40.4.9/s/doc/system/UNIX4.zip <br /><br />Netware4.X网络规划和维护 <br />http://210.40.4.9/s/doc/network/NETWARE4.zip <br /><br />Novell4.XX实用手册 <br />http://210.40.4.9/s/doc/network/NOVELL4.zip <br /><br />大富翁论坛 离线数据库 CHM 版 2001.1123（180M） <br />大富翁论坛是一个专门讨论Delphi的技术论坛，上面高手如云，是国内人气最盛、质量最高的Delphi讨论站。本文件根据该论坛的离线数据包生成，支持全文检索，话题ID检索，并实现了自动换行。由于某些话题正文中的HTML Tag会干扰CHM的生成，所有正文的HTML Tag 已全部转成明文。其中话题ID：316846、362735、412795由于某种原因（不清楚）会使HTML Help Workshop产生非法操作错误，已在生成时自动忽略。 <br />http://210.40.4.9/s/doc/delphi/dfw.chm <br /><br />爆笑网文千篇 <br />http://www.cessd.com.cn/soft1/baoxiao.zip <br /><br />Visual C++ 6.0 21天自学教程 <br />ftp://211.90.241.28/learn/zvc6_book.zip <br />微软认证考试全攻略教程 <br />ftp://download.zj165.com/learn/mcse-gb.exe <br /><br />电脑报》2001年合订本电子版 <br />ftp://download.zj165.com/learn/dnb2001.rar <br /><br />VB6循序渐进教程 <br />学习Visual Basic 6的好教材，适用于从初学者到程序员的各个层次。读取工具可从本站下载。 <br />ftp://download.zj165.com/learn/MVB6.WDL <br /><br />C++ Builder 教学源代码大集合 <br />十七类共一百二十个优秀 C++ Builder 教学源代码大集合!!! 让你二十天内玩转C++ Builder 。 <br />http://210.40.4.9/s/prog/c/cbssetup.exe <br /><br />javascript 使用祥解》 <br />http://read.cnread.net/dnwl/cxsj/java/download/jscr.zip <br /><br />《Microsoft Visual J++ 6.0 Now 即学即用》 <br />http://read.cnread.net/dnwl/cxsj/java/download/jxjy.wdl <br /><br />《JAVA 语言与其程序设计范》 <br />http://read.cnread.net/dnwl/cxsj/java/download/yyyq.zip <br /><br />中华诗词六万 60000（简体XP版） 4.7.22 <br />ftp://zhtx:letmein@zhtx.net:2500/poems60k.zip <br /><br /><br />WinXP控制台主要命令的解释 <br />ftp://61.159.224.20/software/windowsxp.dos.zip <br /><br />Photoshop 6.0中文教材（cool） <br />http://www.flash8.net/file/soft/f/Photoshop6jc.zip <br />浪漫文集 <br />浪漫，存在于生活中的点点滴滴，把这点点滴滴的浪漫汇集起来，细细品味这一份份温馨的回忆，喔……原来生活是充满浪漫的。 <br />http://210.40.4.9/s/other/interest/romance.zip <br /><br />Linux参考大全 <br />《Linux 参考大全》 Internet应用，Unix功能，系统管理以及编程。本书第一部分介绍Linux的安装、启动，以及Linux所包含的大量可下载的窗口管理器、工作平台的基本操作和概念。第二部分为用户在Linux上工作，教授了一套基本的Linux操作技术。第三部分详细地讨论了Linux系统在Internet 上的许多应用，介绍了如何通过Linux自动安装、使用Internet浏览器、服务器，以及诸多的Internet应用程序和Internet工具，还讨论了使用所述工具、应用程序进行网络应用。第四和第五部分介绍了Linux作为一种Unix操作系统的特点，讨论了Unix过滤器、Shell编程、标准编辑器及其使用技巧。第六部分介绍了系统、网络和X Windows管理，以及Linux编程…… <br />http://210.40.4.9/s/doc/linux/LINUX.zip <br /><br />电脑报2001年合订版 电子版-----超级推荐 <br />解压密码：<a href="http://www.liuxm.com/" target="_blank"><font color="#000000">http://www.liuxm.com/ </font></a><br />完整的光碟压缩，除去不必要的音乐和软件，整套2001年电脑报的精彩文章，你还不赶快收入？DOWN.... <br />http://www.liuxm.com/download/doc/mzsx/dnb2001.zip <br /><br />软件破解入门教程与解密常用手册 <br />作为一个电脑爱好者，相信手头一定有不少酷软，但往往这些软件有各种限制，所以你是不是常常为了一个小小的注册码，而经常头痛呢？是不是为了找到一个软件的注册码而费尽心机呢？但大家是否想过自己来破解软件得出注册码？ <br /><br />? ?你也许会说太难了，网上找一个注册码得了，如果你是用自己的技术把软件注册了，一定会有另一番美妙感受。况且一些软件不一定在刚想用的时后，网上就能找到注册码的。 <br /><br />? ?其实破解的乐趣远不在此。 <br /><br />? ?当你去破一个软件时，那种对知识的渴望，对技术的追求，将使迫使你勤奋的学习，来不断的完善自己的知识。特别是对电脑的了解，会有一个质的飞跃。 <br /><br /><br />＊ 推荐使用网络蚂蚁下载本站软件，如果您发现链接错误或其它问题，请到本站“软件咨询点播区”查找或留言，我们会尽快给你答复。 <br />＊ 欢迎广大作者给我们提供软件以及使用说明。【告诉好友】 【评论投票】3354 <br /><br />http://www.liuxm.com/download/doc/mzsx/cracker.chm <br /><br />全方位的BIOS优化手册 <br />http://www.xfsjsoft.com/down/wysc/awen/bios.rar <br /><br />中外诗歌经典12000 1.0 <br />中外诗歌经典（程序版本1.0.2002，诗歌数据库版本1.0.12000）是搜集古今中外著名诗词、诗歌的程序。其中搜集中外作家四百六十余人，搜集诗歌一万二前首（未注册版本只能显示四千首）。其中中国部分包括了中国著名诗词作家的广为流传、脍炙人口的代表作品。外国部分包括了部分诺贝尔文学奖获得者以及一些著名诗人的作品。作品全部经过认真校对。拥有完整的诗人作家简介和诗歌格式说明。完善的诗歌查找功能。对喜好诗歌提供收藏夹功能，方便阅读。 ? <br />ftp://3395686417/newsoft1/poetryleewheel.exe <br /><br />古龙小说全集,CHM文件格式，很方便阅读哦！！ <br />http://61.166.122.174/soft/bookdown/wxxs/glxss_all.chm <br /><br />《中国古典名著百部》72M <br />《中国古典名著百部》－中国古典名著百部，精选了我国历代具有代表性的哲学、历史、小说、文学理论、戏曲、散文诗词、地学、物理学名著50种，共计100部。所选作品价值大、流传广、成就高，或代表一个流派，或开创一时之风，或成就一家之言，深刻影响着当时和我们现在的社会生活，是世界文明的辉煌篇章，具有很高的阅读、欣赏及收藏价值。?请用 WinRar中文版 2.8 解压缩 中文 Acrobat 观看。 <br /><br />http://210.40.4.9/s/edu/human/china.rar <br /><br />《大唐双龙传电子版》（全） <br />http://210.40.4.9/s/other/special/%...C1ú&amp;acute;&amp;laquo;.zip <br /><br />中国青年 杂志2001年合订本 <br />中国青年杂志近年来越办越好，深受广大中青年朋友的推崇，其中有许多文章提出了青年们值得深思的问题,是工作和生活的指南，是开阔视野充实人生观的好帮手。现把2001年全部杂志内容打包成E书，提供给大家阅读。希望大家能够喜欢。 <br />http://210.40.4.9/s/other/special/spark.chm <br /><br />电子书籍[寻秦记].解压密码：myis.yeah.net <br />http://scangel.cpgl.net/zty/homepage/download/book.rar <br /><br />金庸全集（PDF版)版本45M <br />“飞雪连天射白鹿，笑书神侠倚碧鸳”所引出的14部金庸小说曾经风靡全球，小说一经问世，就如石破天惊，震烁文坛，成为中国文学史上的一大奇观，其读者更是遍布世界，人们百读不厌。随着电脑的普及和人们阅读习惯的改变，电子图书热潮正在国内图书界和软件业掀起。近日，青苹果数据中心推出获得著作权许可的《金庸武侠小说全集》电子版。 <br />http://61.166.122.174/soft/down/story/jinyong.zip <br /><br /><br />破解精华教程 1400篇大作！解压密码为: myis.yeah.net <br />http://www.tacwire.com/myis3/t/1204/c3.rar <br /><br />《中国计算机教育报》2001年上半年合订本 <br />ftp://www.activeedu.net:22/0000/090...001-1-noimg.rar <br /><br />最全的一套ASP教程 <br />http://www.caiqing.net/openfile.asp?id=383 <br /><br />《计算机应用文摘》2001年上半年合订本 <br />计算机应用文摘》是一本在国内颇具影响力的普及型IT刊物，风格鲜明、综合性强。全刊138页，8个彩页，分新闻与综述、硬件大看台、软件风景线、网络新时代四个版块。本刊内容选择贴近读者，实用性很强，难度设置合理，采用专题式操作，每期推出几个专题，为用户就某一问题提供全面的知识和解决方案，特别适合初、中级电脑用户阅读。由于各种原因，许多朋友需要电子版的《计算机应用文摘》，但是苦于上网不方便和钞票的原因不能时刻在网上浏览杂志的各篇文章，这不能不说是一种遗憾。西部电子weste.net的icech利用业余之便，免费为大家下载《计算机应用文摘》杂志，并且打包成文件，提供给大家阅读。希望大家能够喜欢。 <br />ftp://dl3.51soft.com:8384/jsjyywz001.zip <br /><br /><br />《大众软件》2001年合订本（上） <br />《大众软件》杂志是我们软件爱好者最喜爱的杂志之一，内容丰富、形式灵活，有极高的收藏和保存价值。由于各种原因，许多朋友需要电子版的《大众软件》，但是苦于上网不方便和钞票的原因不能时刻在网上浏览杂志的各篇文章，这不能不说是一种遗憾。西部电子weste.net的icech利用业余之便，免费为大家下载《大众软件》杂志，并且打包成文件，提供给大家阅读。希望大家能够喜欢。 <br />ftp://dl3.51soft.com:8384/dzrj001.zip <br />《大众软件》2001年合订本（下） <br />http://www.nease.net/~icech/ebook/popsoft2001_2.rar <br /><br /><br />各种E书的下载链接（转贴来的，未经验证（下不了可别怪我哟），与大家分享） <br />《黑客攻防指南》是由黑白网络发布的期刊，共有以下几个栏目：黑客入门，系统漏洞，基础知识，网管天地，病毒信息，业内新闻，工具介绍，特别奉献，主要是一些黑客与网络安全及病毒相关的技术文章等 <br />http://www.heibai.net/download/show.php?id=2837&amp;down=1 <br />看雪学院的破解论坛精华4,爱好破解的朋友不可错过哦. <br />http://www.heibai.net/download/show.php?id=2284&amp;down=1 <br /><br />《黑客攻防指南》是由黑白网络发布的期刊,由星坤策划，傲者少言设计制作，每月的第一个周日发布。内容主要是一些黑客与网络安全及病毒相关的技术文章等，每期杂志共有大小文章教程100篇。主要栏目有：rn黑客入门，主要介绍一些入侵方式方法，知道了黑客是如何进入您的机器的，才能更好的防御。 rn系统漏洞，是各种操作系统、软件的新漏洞以及比较经典的漏洞资料，以及相关补救措施。 rn技术文摘，包括的面比较广泛，但还是以网络安全为主题的各种技术文章，是您提高各种技术的最佳学习途径。 rn病毒信息，这个栏目提供各种病毒预告，各种恶性病毒代码，方便大家学习防御。 rn业内新闻，顾名思义，就是黑客与网络安全界的一些新鲜事啦。rn工具介绍，恐怕是菜鸟们的最爱啦，让您在最短的时间内，体验到入侵或抵挡黑客进攻的快感，为了方便大家学习，我们尽量找些带图片讲解的文章。rn特别奉献，我们会不固定的给大家一个惊喜，或许会提供些基础知识给大家，或许是一些有漏洞的外国机器IP，或许是黑白会员软件的密码，也许是我们搜集到的代理地址等，还有，每个月黑白网络更新的所有软件列表也会在特别奉献中，这样您只要一个月看一次电子杂志，就可以得到最新的软件，看到最新的黑客文章。rn 我们每天有专人，在网上各大安全论坛，黑客、红客、专业网络安全公司的网站为您收集最新最好用的文章，还有广大网友的投稿，更有我们扫描的正式出版物的文章，并有专人制作排版，绝对是黑客及网络爱好者珍藏的好东东啊。 <br />http://www.heibai.net/download/show.php?id=2216&amp;down=1 <br /><br />第一时间给自己的NT/2000服务器打补丁 ,PDF格式 <br />http://www.heibai.net/download/show.php?id=2081&amp;down=1 <br /><br />修改IIS的BANNER实现操作系统版本的隐藏 ,PDF格式 <br />http://www.heibai.net/download/show.php?id=2080&amp;down=1 <br /><br />一次入侵教程FLASH版本，吐血推荐 <br />http://www.heibai.net/download/show.php?id=2027&amp;down=1 <br /><br />MySQL中文手册,HTML格式带图片教程。 <br />http://www.heibai.net/download/show.php?id=1902&amp;down=1 <br /><br />《黑客速成》以多媒体为传播手段，生动翔实的介绍了黑客工具的具体用方法和一些基本的网络常识，其中有很多演示，可以让使用者迅速掌握技术技巧，它可以使你轻轻松松进入黑客大门，是从图片教程到多媒体教程的一次质的飞跃 <br />http://www.heibai.net/download/show.php?id=1482&amp;down=1 <br /><br />Linux internet应用 <br />http://www.heibai.net/download/show.php?id=515&amp;down=1 <br /><br />linux 提示与技巧 里面有好多的提示和技巧，不可不看的！ <br />http://www.heibai.net/download/show.php?id=514&amp;down=1 <br /><br />Linux 系统管理员手册（中文版） <br />http://www.heibai.net/download/show.php?id=513&amp;down=1 <br /><br />《黑客的攻击手段及用户对策》 PDG格式超星阅读器阅读 <br />http://www.heibai.net/download/show.php?id=279&amp;down=1 <br /><br />《天网防火墙个人版2.0教程》 HTML格式 <br />http://www.heibai.net/download/show.php?id=276&amp;down=1 <br /><br />《104种清除木马方法》 CHM 帮助文件格式。 <br />http://www.heibai.net/download/show.php?id=274&amp;down=1 <br /><br />Linux 参考大全 WDL格式中文教程 需用华康图书阅读器 DynaDoc阅读本书分六大部分26章，介绍了四个主要的Linux主题：Internet应用，Unix功能，系统管理以及编程。本书第一部分介绍Linux的安装、启动，以及Linux所包含的大量可下载的窗口管理器、工作平台的基本操作和概念。第二部分为用户在Linux上工作，教授了一套基本的Linux操作技术。第三部分详细地讨论了Linux系统在Internet上的许多应用，介绍了如何通过Linux自动安装、使用Internet浏览器、服务器，以及诸多的Internet应用程序和Internet工具，还讨论了使用所述工具、应用程序进行网络应用。第四和第五部分介绍了Linux作为一种Unix 操作系统的特点，讨论了Unix过滤器、Shell编程、标准编辑器及其使用技巧。第六部分介绍了系统、网络和XWindows管理，以及Linux编程。这一部分前段特别强调了特殊系统管理工具的使用，包括如何通过Linux平台应用这些工具设置网络，配置文件、管理器、应用程序等。后段第23章以后讨论了Linux编程。rn <br />http://www.heibai.net/download/show.php?id=273&amp;down=1 <br /><br />骇世黑客。网络时代，黑客惊世骇俗的智力和行为引发了世界经济、军事、科技、个人生活各方面的震荡，本书为您提供一幅洞悉黑客神秘的智力杀拼的全景图像。 <br />http://www.heibai.net/download/show.php?id=268&amp;down=1 <br /><br />《因特网的防火墙》中文教程，需要SSReader超星图书阅读器阅读 <br />http://www.heibai.net/download/show.php?id=263&amp;down=1 <br /><br />21世纪网络工程师设计宝典丛书 网络核心技术内幕??网络攻击秘航笈 ，中文教程、PDF文件 <br />http://www.heibai.net/download/show.php?id=255&amp;down=1 <br /><br />21世纪计算机网络技术系列书---面向21世纪网络安全与防护，中文教程、PDF文件。 <br />http://www.heibai.net/download/show.php?id=254&amp;down=1 <br /><br />Adobe Acrobat Reader V5.0.1 简体中文版 是一个查看、阅读和打印PDF文件的最佳工具.（*.pdf 文件）需要此程序打开。 <br />http://www.heibai.net/download/show.php?id=253&amp;down=1 <br /><br />学习HTML语言 <br />http://www.hoodle.net/dzbook/down/16/HTML-GB.zip <br />5日精通CSS样式表 <br />http://www.hoodle.net/dzbook/down/16/5css-gb.exe <br /><br />网页制作技巧与常见问题 <br />http://www.hoodle.net/dzbook/down/16/001pageskill.zip <br /><br />Web服务器OmniHTTPd安装手册 <br />http://www.hoodle.net/dzbook/down/16/omnihttpd.zip <br /><br />网页制作特效 <br />http://www.hoodle.net/dzbook/down/16/webeffect.exe <br /><br /><br />网站设计的思考 <br />http://www.hoodle.net/dzbook/down/16/013thinkdesign.zip <br /><br />ASP技巧文集 <br />http://www.hoodle.net/dzbook/down/1/jiqia.zip <br /><br />FIREWORK之中文帮助 <br />http://www.hoodle.net/dzbook/down/1/Fw4HelpCn.zip <br /><br />dreamweaver之中文帮助 <br />http://www.hoodle.net/dzbook/down/1/Dw4HelpCn.zip <br /><br />网络编程之ASP <br />http://www.hoodle.net/dzbook/down/1/asp.exe <br /><br />ASP基础教程 <br />http://www.hoodle.net/dzbook/down/1/ASP-GB.zip <br /><br />flash技巧汇粹 <br />http://www.hoodle.net/dzbook/down/8/flashjq-gb.zip <br /><br />网络编程之javascript <br />http://www.hoodle.net/dzbook/down/12/javascriptjc.exe <br /><br />Java程序设计技巧1001例 <br />http://www.hoodle.net/dzbook/down/12/04021.zip <br /><br />javascript教程 <br />http://www.hoodle.net/dzbook/down/12/005javascript.zip <br /><br />JAVA的思考 <br />http://www.hoodle.net/dzbook/down/12/thinkinjava.zip <br /><br />XML基础教程 <br />http://www.hoodle.net/dzbook/down/5/xml_basic.zip <br /><br />ASP开发者必备的参考资料 <br />这是nbhero我在写程序的时候经常要用到的一些资料，包含了： <br />vbscript 5 的语法帮助文件； <br />vbscript 5.5 的语法帮助文件； <br />javascript 5 的语法帮助文件； <br />ADO 2.1的帮助文件； <br />DHTML的对象的属性/方法/事件等的帮助文件； <br />基于微软JET引擎的SQL语句的帮助文件； <br />这些帮助文件无论对初学者还是高手都有帮助，当作词典来用也不错。 <br />http://61.132.182.156:81/soft/book/aspbook.rar <br />《大众软件》2002年上半年合订本，共12期，没买书的朋友有福了。 <br />ftp://202.102.234.15:27/edu/ebook/pop2002a_weste.exe <br /><br />电脑教育报2002上半年合订本，绝对是收藏上品！不过遗憾的是文件有点太大，有66M，不是宽带的朋友需要些时间了，但是还是非常值得下载的！ <br />解压密码：<a href="http://www.169s.com/" target="_blank"><font color="#000000">http://www.169s.com/ </font></a><br />ftp://202.102.234.15:27/edu/ebook/cce2002-a.rar <br /><br />电脑报2001年合订本（上下） <br />http://www.hldqptt.net.cn/downloads/diannaobao2001.exe <br /><br />WORD2000教程 <br />http://www.hldqptt.net.cn/downloads/word2k.zip <br /><br />FRONTPAGE2000教程 <br />http://www.hldqptt.net.cn/downloads/frontpage.zip <br /><br />INTERNET入门教程 <br />http://www.hldqptt.net.cn/downloads/internet.zip <br /><br />OUTLOOK2000教程 <br />http://www.hldqptt.net.cn/downloads/ol2k.zip <br /><br />硬件基本知识教程 <br />http://www.hldqptt.net.cn/downloads/hard.zip <br /><br />Oicq教程 <br />http://www.hldqptt.net.cn/downloads/oicq.zip <br /><br />Windows2000教程 <br />http://www.hldqptt.net.cn/downloads/win2000.zip <br /><br />网络连接基础教程 <br />http://www.hldqptt.net.cn/downloads...ianjiejichu.zip <br /><br />Red Hat Linux 5.1安装指南 <br />http://www.hldqptt.net.cn/downloads/ <br /><br />HTML4.0手册 <br />http://www.hldqptt.net.cn/downloads/html40.zip <br /><br />注册表使用手册，分为系统安全、系统优化、网络、系统DIY(杂项)等几个专题栏目。 <br />http://ftp.pconline.com.cn/pub/down...00203/reg23.zip <br /><br />Flash MX 5日通 <br />很难相信自从2000年7月 Flash 5的正式发布到现在几乎快两年了，对于下一代的Flash面市我们等的太久。然而，让我首先告诉你的是对与新版本的flash你不会感到失望，无论是用户界面（UI)，还是使用工具。这不是上个世纪的已经过去的那个flash。就象我 一样，也许你不是一个伟大的程序开发人员，但是，新版的flash 内建的动作脚本（Action Script）足可以使你热情满怀，信心十足，动作脚本开发环境的改进和功能的增强绝不是轻量级的。看看FlashMX到底有什么新的和改进的特征 <br />http://zhongwx.533.net/911/FlashMX5day.rar <br /><br />win2000教程（完全） <br />http://www.hongen.com/pc/newer/os/win2000/w1.htm <br /><br />电脑硬件维修手册 <br />http://images.21cn.com/download/fil...o/20716/1-1.exe <br /><br />由祺天大圣精心制作的电子杂志，每周一发送，网虫的必备上网手册。收集了每周网络精华文章、软件、小东东。现已出至第44期。 <br />http://www.xzdd.com/babyshen/magazine/2002/2002-1.rar <br /><br />三部关于服务器的E书 <br />第一部 <br />Apache服务器配置全攻略 <br /><br />第二部 <br />Web服务器大扫除 <br /><br />第三部 <br />Windows2000 DNS 技术指南 <br />http://202.98.111.124:5928/bu/123/ebook.rar <br /><br />java全部教程共九章你也可在线学习可不要错过啊！ <br />http://www.china3y.com/soft/Java.exe <br /><br />网络公司创建指南 <br />http://ebook.best.163.com/netcom.zip <br /><br />大众软件2002（1－10期） <br />http://61.179.118.98/soft/2002/2002061210.rar <br /><br />搜索引擎策略 <br />http://ebook.best.163.com/search.zip <br /><br />PHP教程 <br />http://ebook.best.163.com/php.zip <br />网络管理员培训资料 <br />http://ebook.best.163.com/webmaster.zip <br /><br />一步一步学Flash <br />http://ebook.best.163.com/stepflash.zip <br /><br />HTML简明导引 <br />http://ebook.best.163.com/html-cn.zip <br /><br />网页设计调色板 <br />http://ebook.best.163.com/color.zip <br /><br />77种网络新经济 <br />http://ebook.best.163.com/77.exe <br /><br />大众软件2002（1－10期） <br />http://61.179.118.98/soft/2002/2002061210.rar <br /><br />SQL Server 2000菜鸟进阶,从安装到使用,让你入门 <br />http://www.zgcszsc.com/downs/software/study/sqlbook.exe <br /><br />XML初学进阶 <br />分为十章详细介绍XML标准的语法和应用。第一章，我们简单介绍一下什么是XML，并将回顾 <br />XML的发展史。从第二章到第四章，我们分别从XML语法、DTD和样式单三方面详细介绍XML的三 <br />个基本要件。在第五、第六章中，我们从与XML相关的协议和软件工具两个角度来分析XML的使 <br />用现状。第七、八、九章，我们将讨论一些与XML相关的更深层次的内容，包括XML链接、XML <br />DOM以及XML与数据库的连接。最后，在第十章，希望诸多网友和我们一起，仁者见仁，智者 <br />见智，共同为XML未来的应用和发展方向作一个前景规划！ <br />http://211.96.2.136/asp300/soft/other/xmlcxjj.zip <br /><br />全书共十章，一个附录，223页,全面介绍ASP+的基础语言，是学习的基础。 <br />http://211.96.2.136/asp300/soft/other/vb-vbnet.zip <br /><br />Win2000服务器设置全攻略-教程 <br />http://download.allin.net.cn/down/1930.zip <br /><br />局域网概念和组成 <br />http://www.51/&lt;a%20href=/" target="_blank"&gt;<a href="http://www.51www.net/download/lan2.zip" target="_blank"><font color="#000000">http://www.51www.net/download/lan2.zip </font></a><br /><br />《JSP教程》 <br />http://www.51/&lt;a%20href=/" target="_blank"&gt;<a href="http://www.51www.net/download/JSPbook.zip" target="_blank"><font color="#000000">http://www.51www.net/download/JSPbook.zip </font></a><br /><br />《循序渐进学习XML》 <br />http://www.51/&lt;a%20href=/" target="_blank"&gt;<a href="http://www.51www.net/download/xml.zip" target="_blank"><font color="#000000">http://www.51www.net/download/xml.zip </font></a><br /><br />DivX 全中文制作最强攻略 Ver 1.1（强烈推荐） <br />11500字，配图65张，PDF格式。 <br />http://downcenter.mycol.com/divx20020215/DivXall.pdf <br /><br />AutoCAD 2000 三维造型高级培训教程 <br />http://hnftp.soft163.com/autocad2000_3d_advance.zip <br /><br />AutoCAD 2000中文版技术大全 <br />http://hnftp.soft163.com/AutoCad2000dq.zip <br /><br />单机架站全攻略 <br />现在的宽带越来越普及了，想不想让你一台普通的电脑成为一台有自己的网页，自己的FTP服务，自己论坛服务，自己的邮件服务的全功能服务器呢，单机架站全攻略可以手把手教你 <br />ftp://61.159.224.3/softw/allserver.chm <br /><br />POWERBUILD6.5编程宝典 <br />http://www.xjshz.com.cn/acdown/down/pb6.5.zip <br /><br />电脑报 2001 年合订版电子版 <br />http://www.6266.net/yaka/2998.zip <br /><br />WINDOWS_2000注册表管理PDF格式 <br />本书揭示了Windows 2000注册表的强大功能。它提供了450余个问题的解决方案，涉及系统管理、硬件系统、网络协议、打印管理、远程访问、系统安全、IIS、COM＋、 SQL Server、多媒体、MTS和Internet Explorer等众多方面。本书是Windows 2000系统管理员必备的参考书。它是系统管理员用来直接解决最困难、最复杂问题的最新参考资料。 <br />ftp://www.mesky.net/books/pdf_windows_2000reg.rar <br /><br />MYSQL网络数据库指南PDF格式 <br />MySQL 是完全网络化的跨平台关系型数据库系统，同时是具有客户机/服务器体系结构的分布式数据库管理系统。它具有功能强、使用简便、管理方便、运行速度快、安全可靠性强等优点，用户可利用许多语言编写访问MySQL 数据库的程序，另外，MySQL在UNIX等操作系统上是免费的，在Windows操作系统上，可免费使用其客户机程序和客户机程序库。本书通过两个实例，详细介绍了MySQL的基本概念、基本技巧、编程方法、管理特点，以及第三方工具（如PHP和Perl）的使用方法。本书还提供了大量与MySQL有关的因特网站点，以及获得MySQL的技术支持方法。 本书适合数据库、网络开发与管理等人员参考 <br />ftp://www.mesky.net/books/pdf_mysql_databass.rar <br /><br />网络管理员培训资料 <br />非常不错的网络管理员培训资料，如果你要成为一位成功的网络管理员就应该看看！ <br /><br />培训资料里面的文件是PowerPoint文件，只要完全安装了Office就可以看了！ <br />ftp://fwduser:aladown@211.154.52.165/webmaster.rar <br /><br />Windows 2000 Server资源大全1-6卷（pdf格式） <br />解开压缩包后，当阅读时会提示输入密码，密码就是空格！解压密码：<a href="http://www.soft163.com/" target="_blank"><font color="#000000">http://www.soft163.com/ </font></a><br />http://hnftp.soft163.com/Win2K_Serv.rar <br /><br />《孙子兵法》是中国古代一部著名兵法，相传为先秦时的大军事家孙武所著。这部兵法，已被世界各国公认为是最富哲理性和发生着深远影响的兵法。凡读过这部兵法的人，不仅会感觉到其有一种独抵华屋之下、一览群小的气度，而且还会倾心仰慕它所蕴含的深邃而奥秘的思辨内容，博大而精深的军事学说内涵，清新而鲜明的实践风格，以及辞如珠玉的文学性语言。其问世虽已有两千五百年之久，但它因为所包容的一些哲学思维，以及在这些哲学文化意识指导下所阐述的战争规律和原则，至今仍然闪烁着熠熠光辉，被称为令人叹为观止的罕世之作。 <br />http://www.wlgame.com/cne3online/down/else/szbf.zip ?<img src ="http://www.cppblog.com/zgysx/aggbug/16990.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zgysx/" target="_blank">永遇乐</a> 2006-12-29 17:22 <a href="http://www.cppblog.com/zgysx/archive/2006/12/29/16990.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]VC 界面开发 常见的问题</title><link>http://www.cppblog.com/zgysx/archive/2006/12/28/16952.html</link><dc:creator>永遇乐</dc:creator><author>永遇乐</author><pubDate>Thu, 28 Dec 2006 09:54:00 GMT</pubDate><guid>http://www.cppblog.com/zgysx/archive/2006/12/28/16952.html</guid><wfw:comment>http://www.cppblog.com/zgysx/comments/16952.html</wfw:comment><comments>http://www.cppblog.com/zgysx/archive/2006/12/28/16952.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zgysx/comments/commentRss/16952.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zgysx/services/trackbacks/16952.html</trackback:ping><description><![CDATA[
		<h2>
				<a id="viewpost1_TitleUrl" href="/mzty/archive/2006/11/14/15149.html">
						<font size="3">VC 常见的问题</font>
				</a>
				<font size="3">
						<br />
						<br />
						<font color="#000000">（3） 如何在程序中获得其他程序的 图标?<br />两种方法:<br />(1) SDK函数 SHGetFileInfo 或使用 ExtractIcon获得图标资源的 handle,<br />(2) SDK函数 SHGetFileInfo 获得有关文件的很多信息,如大小图标,属性, 类型等.</font>
				</font>
		</h2>
		<h2>
				<font size="3">
						<font color="#808080">
								<font color="#000000">void CSampleView:<br />OnDraw(CDC * pDC)<br />{<br />if( :: SHGetFileInfo(_T("c:\\pwin95\\notepad.exe"),0,<br />&amp;stFileInfo,sizeof(stFileInfo),SHGFI_ICON))<br />{<br />pDC -&gt;DrawIcon(10,10,stFileInfo.hIcon)<br />}<br />}<br />Example(2):同样功能,Use ExtractIcon Function<br />void CSampleView:: OnDraw(CDC *pDC)<br />{<br />HICON hIcon=:: ExtractIcon(AfxGetInstanceHandle(),_T<br />("NotePad.exe"),0)<br />if (hIcon &amp;&amp;hIcon!=(HICON)-1)<br />pDC-&gt;DrawIcon(10,10,hIcon)<br />}</font>
								<br />
						</font>
						<br />    说明: 获得notepad.exe的路径正规上来说用GetWindowsDirectory函数得到, 如果是调用 win95下的画笔，应该用访问注册表的方法获得其路径，要作成一个比较考究的程序，考虑应该全面点. </font>
		</h2>
		<div class="postbody">
				<div class="postbody">
						<div class="postcontent">
								<p>
										<br />
										<br />（6） 如何改变窗口的图标?<br />向窗口发送 WM_SECTION消息。<br />Example:<br />HICON hIcon=AfxGetApp() -&gt;LoadIcon(IDI_ICON)<br />ASSERT(hIcon)<br />AfxGetMainWnd() -&gt;SendMessage(WM_SECTION,TRUE,(LPARAM)hIcon)<br /></p>（8） 如何将窗口居中显示?<br />Call Function CWnd::CenterWindows()<br /><br />Example(1):<br />Center Window( ) //Relative to it's parent<br />// Relative to Screen<br />Example(2):<br />CenterWindow(CWnd:: GetDesktopWindow( ))<br />//Relative to Application's MainWindow<br />AfxGetMainWnd( ) -&gt;CenterWindow( )<br /><p><br /> </p><p>（12） 如何创建一个字回绕的CEditView<br />重载CWnd : : PreCreateWindow和修改CREATESTRUCT结构，关闭CEditView对象的ES_AUTOHSCROLL和WS_HSCROLL风格位， 由于CEditView : : PreCreateWindow显示设置cs. style，调用基类函数后要修改cs . style。<br /><br />BOOL CSampleEDitView : : PreCreateWindow (CREATESTRUCT&amp;cs)<br />{<br />//First call basse class function .<br />BOOL bResutl =CEditView : : PreCreateWindow (cs)<br /><br />// Now specify the new window style .<br />cs.style &amp;= ~ (ES_AUTOHSCROLL ｜WS_HSCROLL)<br />return bResult<br />}<br /></p><p><br />（17） 如何单击除了窗口标题栏以外的区域使窗口移动<br />当窗口需要确定鼠标位置时Windows向窗口发送WM_NCHITTEST信息，可以处理该信息使Windows认为鼠标在窗口标题上。对于对话框和基于对话的应用程序，可以使用ClassWizard处理该信息并调用基类函数， 如果函数返回HTCLIENT 则表明鼠标在客房区域，返回HTCAPTION表明鼠标在Windows的标题栏中。<br />UINT CSampleDialog : : OnNcHitTest (Cpoint point )<br />{<br />UINT nHitTest =Cdialog: : OnNcHitTest (point )<br />return (nHitTest = =HTCLIENT)? HTCAPTION : nHitTest<br />}<br /><br />上述技术有两点不利之处，<br />其一是在窗口的客户区域双击时，窗口将极大；<br />其二， 它不适合包含几个视窗的主框窗口。<br />还有一种方法，当用户按下鼠标左键使主框窗口认为鼠标在其窗口标题上，使用ClassWizard在视窗中处理WM_LBUTTODOWN信息并向主框窗口发送一个WM_NCLBUTTONDOWN信息和一个单击测试HTCAPTION。<br />void CSampleView : : OnLButtonDown (UINT nFlags , Cpoint point<br />)<br />{<br />CView : : OnLButtonDow (nFlags , pont )<br /><br />//Fool frame window into thinking somene clicked<br />on<br />its caption bar .<br />GetParentFrame ( ) —&gt; PostMessage (<br />WM_NCLBUTTONDOWN ,<br />HTCAPTION , MAKELPARAM (poitn .x , point .y) )<br /><br />}<br />该技术也适用于对话框和基于对的应用程序，只是不必调用<br />CWnd: :GetParentFrame 。<br />void CSampleDialog : : OnLbuttonDown (UINT nFlags, Cpoint point )<br />{<br />Cdialog : : OnLButtonDow (nFlags, goint )<br />//Fool dialog into thinking simeone clicked on its<br />caption bar .<br />PostMessage (WM_NCLBUTTONDOWN , HTCAPTION , MAKELPARM (point.x<br />, point. y<br />) )<br />}</p><p>（18） 如何改变视窗的背景颜色<br />Windows向窗口发送一个WM_ERASEBKGND消息通知该窗口擦除背景，可以使用ClassWizard重载该消息的缺省处理程序来擦除背景（实际是画），并返回TRUE以防止Windows擦除窗口。<br />//Paint area that needs to be erased.<br />BOOL CSampleView : : OnEraseBkgnd (CDC* pDC)<br />{<br />// Create a pruple brush.<br />CBrush Brush (RGB (128 , 0 , 128) )<br /><br />// Select the brush into the device context .<br />CBrush* pOldBrush = pDC—&gt;SelcetObject (&amp;brush)<br /><br />// Get the area that needs to be erased .<br />CRect reClip<br />pDC—&gt;GetCilpBox (&amp;rcClip)<br />//Paint the area.<br />pDC—&gt; PatBlt (rcClip.left , rcClip.top , rcClip.Width ( ) , rcClip.Height( ) , PATCOPY )<br /><br />//Unselect brush out of device context .<br />pDC—&gt;SelectObject (pOldBrush )<br /><br />// Return nonzero to half fruther processing .<br />return TRUE<br />}</p><p>（20） 如何防止主框窗口在其说明中显示活动的文档名<br />创建主框窗口和MDI子窗口进通常具有FWS_ADDTOTITLE风格位，如果不希望在说明中自动添加文档名， 必须禁止该风格位， 可以使用ClassWizard重置<br />CWnd: : PreCreateWindow并关闭FWS_ADDTOTITLE风格。<br />BOOL CMainFrame : : PreCreateWindow (CREATESTRUCT&amp;cs)<br />{<br />//Turn off FWS_ADDTOTITLE in main frame .<br />cs.styel &amp; = ~FWS_ADDTOTITLE 　<br />return CMDIFrameWnd : : PreCreateWindow (cs )<br />}<br />关闭MDI子窗口的FWS _ADDTOTITLE风格将创建一个具有空标题的窗口，可以调用CWnd: : SetWindowText来设置标题。记住自己设置标题时要遵循接口风格指南。</p><p>（21） 如何获取有关窗口正在处理的当前消息的信息<br />调用CWnd: : GetCurrentMessage可以获取一个MSG指针。例如，可以使用ClassWizard将几个菜单项处理程序映射到一个函数中，然后调用GetCurrentMessage来确定所选中的菜单项。<br />viod CMainFrame : : OnCommmonMenuHandler ( )<br />{<br />//Display selected menu item in debug window .<br />TRACE ("Menu item %u was selected . \n" ,</p><p>（22） 如何在代码中获取工具条和状态条的指针<br />缺省时， 工作框创建状态条和工具条时将它们作为主框窗口的子窗口，状态条有一个AFX_IDW_STATUS_BAR标识符，工具条有一个AFX_IDW_TOOLBAR标识符，下例说明了如何通过一起调用CWnd: : GetDescendantWindow和AfxGetMainWnd来获取这些子窗口的指针：<br />//Get pointer to status bar .<br />CStatusBar * pStatusBar = (CStatusBar *) AfxGetMainWnd ( )<br />—&gt; GetDescendantWindow(AFX_IDW_STUTUS_BAR)<br /><br />//Get pointer to toolbar .<br />CToolBar * pToolBar = (CToolBar * ) AfxGetMainWnd ( )<br />—&gt; GetDescendantWindow(AFX_IDW_TOOLBAR)</p><p>（23） 如何使能和禁止工具条的工具提示<br />如果设置了CBRS_TOOLTIPS风格位，工具条将显示工具提示，要使能或者禁止工具提示，需要设置或者清除该风格位。下例通过调用CControlBar : : GetBarStyle和CControlBar : : SetBarStyle建立一个完成此功能的成员函数：<br />void CMainFrame : : EnableToolTips ( BOOL bDisplayTips )<br />{<br />ASSERT_VALID (m_wndToolBar)<br /><br />DWORD dwStyle = m _wndToolBar.GetBarStyle ( )<br /><br />if (bDisplayTips) dwStyle ｜=CBRS_TOOLTIPS<br /><br />else<br />dwStyle &amp; = ~CBRS_TOOLTIPS<br /><br />m_wndToolBar.SetBarStyle (dwStyle )<br />}</p><p>（24） 如何创建一个不规则形状的窗口<br />可以使用新的SDK函数SetWindowRgn。该函数将绘画和鼠标消息限定在窗口的一个指定的区域，实际上使窗口成为指定的不规则形状。 使用AppWizard创建一个基于对的应用程序并使用资源编辑器从主对话资源中删除所在的缺省控件、标题以及边界。<br />给对话类增加一个CRgn数据成员，以后要使用该数据成员建立窗口区域。<br />Class CRoundDlg : public CDialog<br />{<br />…<br />private :<br />Crgn m_rgn : // window region<br />…<br />}<br />修改OnInitDialog函数建立一个椭圆区域并调用SetWindowRgn将该区域分配给窗口：<br />BOOL CRoundDlg : : OnInitDialog ( )<br />{<br />CDialog : : OnInitDialog ( )<br /><br />//Get size of dialog .<br />CRect rcDialog<br />GetClientRect (rcDialog )<br /><br />// Create region and assign to window .<br />m_rgn . CreateEllipticRgn (0 , 0 , rcDialog.Width( ) , rcDialog.Height ( ) )<br />SetWindowRgn (GetSafeHwnd ( ) , (HRGN) m_ rgn ,TRUE )<br /><br />return TRUE<br />}<br /><br />通过建立区域和调用SetWindowRgn，已经建立一个不规则形状的窗口，下面的例子程序是修改OnPaint函数使窗口形状看起来象一个球形体。<br />voik CRoundDlg : : OnPaint ( )<br />{<br />CPaintDC de (this) // device context for painting<br />.<br />//draw ellipse with out any border<br />dc. SelecStockObject (NULL_PEN)<br />//get the RGB colour components of the sphere color<br />COLORREF color= RGB( 0 , 0 , 255)<br />BYTE byRed =GetRValue (color)<br />BYTE byGreen = GetGValue (color)<br />BYTE byBlue = GetBValue (color)<br /><br />// get the size of the view window<br />Crect rect<br />GetClientRect (rect)<br /><br />// get minimun number of units<br />int nUnits =min (rect.right , rect.bottom )<br /><br />//calculate he horiaontal and vertical step size<br />float fltStepHorz = (float) rect.right /nUnits<br />float fltStepVert = (float) rect.bottom /nUnits<br /><br /><br />int nEllipse = nUnits/3 // calculate how many to<br />draw<br />int nIndex<br />// current ellipse that is being draw<br /><br />CBrush brush<br />// bursh used for ellipse fill color<br />CBrush *pBrushOld // previous<br />brush that was selected into dc<br />//draw ellipse , gradually moving towards upper-right<br />corner<br />for (nIndex = 0 nIndes &lt; + nEllipse nIndes++)<br />{<br />//creat solid brush<br />brush . CreatSolidBrush (RGB ( ( (nIndex*byRed ) /nEllipse ).<br />( ( nIndex * byGreen ) /nEllipse ), ( (nIndex * byBlue)<br />/nEllipse ) ) )<br /><br />//select brush into dc<br />pBrushOld= dc .SelectObject (&amp;brhsh)<br /><br />//draw ellipse<br />dc .Ellipse ( (int) fltStepHorz * 2, (int) fltStepVert * nIndex ,<br />rect. right -( (int) fltStepHorz * nIndex )+ 1,<br />rect . bottom -( (int) fltStepVert * (nIndex *2) ) +1)<br /><br />//delete the brush<br />brush.DelecteObject ( )<br />}<br />}<br /><br />最后，处理WM_NCHITTEST消息，使当击打窗口的任何位置时能移动窗口。<br />UINT CRoundDlg : : OnNchitTest (Cpoint point )<br />{<br />//Let user move window by clickign anywhere on thewindow .<br />UINT nHitTest = CDialog : : OnNcHitTest (point)<br />rerurn (nHitTest = = HTCLIENT)? HTCAPTION: nHitTest<br /><br />}</p><p>（27） 如何创建和使用无模式对话框<br />MFC将模式和无模式对话封装在同一个类中，但是使用无模式对话需要几个对话需要几个额处的步骤。首先，使用资源编辑器建立对话资源并使用ClassWizard创建一个CDialog的派生类。模式和无模式对话的中止是不一样的：模式对话通过调用CDialog : : EndDialog 来中止，无模式对话则是调用CWnd: : DestroyWindow来中止的，函数CDialog : : OnOK和CDialog : : OnCancel调用EndDialog ,所以需要调用DestroyWindow并重置无模式对话的函数。<br />void CSampleDialog : : OnOK ( )<br />{<br />// Retrieve and validate dialog data .<br />if (! UpdateData (TRUE) )<br />{<br />// the UpdateData rountine<br />will set focus to correct item TRACEO (" UpdateData failed during dialog termination .\n")<br />return<br />}<br /><br />//Call DestroyWindow instead of EndDialog .<br />DestroyWindow ( )<br />}<br /><br />void CSampleDialog : : OnCancel ( )<br />{<br />//Call DestroyWindow instead of EndDialog .<br />DestroyWindow ( )<br />}<br /><br />其次，需要正确删除表示对话的C++对象。对于模式对来说，这很容易，需要创建函数返回后即可删除C++对象；无模式对话不是同步的，创建函数调用后立即返回，因而用户不知道何时删除C++对象。撤销窗口时工作框调用CWnd : : PostNcDestroy，可以重置该函数并执行清除操作，诸如删除this指针。<br />void CSampleDialog : : PostNcDestroy ( )<br />{<br />// Declete the C++ object that represents this dialog.<br />delete this<br />}<br /><br />最后，要创建无模式对话。可以调用CDialog : : DoModal创建一个模式对放，要创建一个无模式对话则要调用CDialog: : Create。下面的例子说明 了应用程序是如何创建无模式对话的： 象；无模式对话不是同步的，创建函数调用后立即返回，<br />void CMainFrame : : OnSampleDialog ( )<br />{<br />//Allocate a modeless dialog object .<br />CSampleDilog * pDialog =new CSampleDialog<br />ASSERT_VALID (pDialog) Destroy ( )<br /><br />//Create the modeless dialog . represents this dialog.<br />BOOL bResult = pDialog —&gt; Create (IDD_IDALOG)<br />ASSERT (bResult )<br />}<br /></p><p></p><p>（28） 如何防止主框窗口在其说明中显示活动的文档名<br />创建主框窗口和MDI子窗口进通常具有FWS_ADDTOTITLE风格位，如果不希望在说明中自动添加文档名， 必须禁止该风格位， 可以使用ClassWizard重置<br />CWnd: : PreCreateWindow并关闭FWS_ADDTOTITLE风格。<br />BOOL CMainFrame : : PreCreateWindow (CREATESTRUCT&amp;cs)<br />{<br />//Turn off FWS_ADDTOTITLE in main frame .<br />cs.styel &amp; = ~FWS_ADDTOTITLE 　<br />return CMDIFrameWnd : : PreCreateWindow (cs )<br />}<br />关闭MDI子窗口的FWS _ADDTOTITLE风格将创建一个具有空标题的窗口，可以调用CWnd: : SetWindowText来设置标题。记住自己设置标题时要遵循接口风格指南。</p><p><br />（30） 怎样加载其他的应用程序?<br />三个SDK函数 winexec, shellexecute,createprocess可以使用。<br />WinExec最简单，两个参数，前一个指定路径，后一个指定显示方式.后一个参数值得说一下，比如泥用 SW_SHOWMAXMIZED方式去加载一个无最大化按钮的程序，就是Neterm,calc等等，就不会出现正常的窗体，但是已经被加到任务列表里了。<br /><br />ShellExecute较 WinExex灵活一点，可以指定工作目录,下面的Example就是直接打开 c:\temp\1.txt,而不用加载与 txt文件关联的应用程序,很多安装程序完成后都会打开一个窗口，来显示Readme or Faq,我猜就是这么作的啦.<br /><br />ShellExecute(NULL,NULL,_T("1.txt"),NULL,_T("c:\\temp"),SW_SHOWMAXMIZED)<br /><br />CreateProcess最复杂，一共有十个参数，不过大部分都可以用NULL代替，它可以指定进程的安全属性，继承信息，类的优先级等等.来看个很简单的Example:<br />STARTUPINFO stinfo<br />//启动窗口的信息<br />PROCESSINFO procinfo //进程的信息<br /><br />CreateProcess(NULL,_T("notepad.exe"),NULL,NULL.FALSE,<br />NORMAL_PRIORITY_<br /><br />CLASS,NULL,NULL, &amp;stinfo,&amp;procinfo)<br /></p><p><br />（32） 如何使能和禁止工具条的工具提示<br />如果设置了CBRS_TOOLTIPS风格位，工具条将显示工具提示，要使能或者禁止工具提示，需要设置或者清除该风格位。下例通过调用CControlBar : : GetBarStyle和CControlBar : : SetBarStyle建立一个完成此功能的成员函数：<br />void CMainFrame : : EnableToolTips ( BOOL bDisplayTips )<br />{<br />ASSERT_VALID (m_wndToolBar)<br /><br />DWORD dwStyle = m _wndToolBar.GetBarStyle ( )<br /><br />if (bDisplayTips) dwStyle ｜=CBRS_TOOLTIPS<br /><br />else<br />dwStyle &amp; = ~CBRS_TOOLTIPS<br /><br />m_wndToolBar.SetBarStyle (dwStyle )<br />}<br /><br />//Get pointer to toolbar .<br />CToolBar * pToolBar = (CToolBar * ) AfxGetMainWnd ( )<br />—&gt; GetDescendantWindow(AFX_IDW_TOOLBAR)</p><p>（33） 如何设置工具条标题<br />工具条是一个窗口，所以可以在调用CWnd : : SetWindowText来设置标题，例子如下：<br />int CMainFrame : : OnCreate (LPCREATESTRUCT lpCreateStruct )<br />{<br />…<br />// Set the caption of the toolbar .<br />m_wndToolBar.SetWindowText (_T "Standdard")<br /></p><p>}<br /><br />（36） 如何改变对话或窗体视窗的背景颜色<br />调用CWinApp : : SetDialogBkColor可以改变所有应用程序的背景颜色。第一个参数指定了背景颜色，第二个参数指定了文本颜色。下例将应用程序对话设置为蓝色背景和黄色文本。<br />BOOL CSampleApp : : InitInstance ( )<br />{<br />…<br />//use blue dialog with yellow text .<br />SetDialogBkColor (RGB (0, 0, 255 ), RGB ( 255 ,255 , 0 ) )<br />…<br />}<br /><br />需要重画对话（或对话的子控件）时，Windows向对话发送消息WM_CTLCOLOR，通常用户可以让Windows选择绘画背景的刷子，也可重置该消息指定刷子。下例说明了创建一个红色背景对话的步骤。<br /><br />首先，给对话基类增加一人成员变量<br />CBursh :class CMyFormView : public CFormView<br />{<br />…<br /><br />private :<br />CBrush m_ brush // background brush<br /><br />…<br />}<br /><br />其次， 在类的构造函数中将刷子初始化为所需要的背景颜色。<br />CMyFormView : : CMyFormView ( )<br />{<br />// Initialize background brush .<br />m_brush .CreateSolidBrush (RGB ( 0, 0, 255) )<br />}<br /><br />最后，使用ClassWizard处理WM_CTLCOLOR消息并返回一个用来绘画对话背景的刷子句柄。注意：由于当重画对话控件时也要调用该函数，所以要检测nCtlColor参量。<br />HBRUSH CMyFormView : : OnCtlColor (CDC* pDC , CWnd*pWnd , UINT nCtlColor<br />)<br /><br />{<br />// Determine if drawing a dialog box . If we are, return +handle to<br />//our own background brush . Otherwise let windows handle it .<br />if (nCtlColor = = CTLCOLOR _ DLG )<br />return (HBRUSH) m_brush.GetSafeHandle ( )<br />return CFormView : : OnCtlColor (pDC, pWnd , nCtlColor<br />)<br />}</p><p></p><p>（39） 如何改变控件的字体<br />由于控件是也是窗口，用户可以调用CWnd: : SetFont指定新字体。该函数用一个Cfont指针，要保证在控件撤消之前不能撤消字体对象。下例将下压按钮的字体改为8点Arial字体：<br />//Declare font object in class declaration (.H file ).<br />private : Cfont m_font<br />// Set font in class implementation (.Cpp file ). Note m_wndButton is a<br />//member variable added by ClassWizard.DDX routines hook the member<br />//variable to a dialog button contrlo.<br />BOOL CSampleDialog : : OnInitDialog ( )<br />{<br />…<br />//Create an 8-point Arial font<br />m_font . CreateFont (MulDiv (8 , -pDC<br />—&gt; GetDeviceCaps(LOGPIXELSY) ,72). 0 , 0 , 0 , FW_NORMAL , 0 , 0,0, ANSI_CHARSER, OUT_STROKE_PRECIS ,<br /><br />CLIP_STROKE _PRECIS , DRAFT _QUALITY<br />VARIABLE_PITCH ｜FF_SWISS, _T("Arial") )<br /><br />//Set font for push button .<br />m_wndButton . SetFont (&amp;m _font )<br /><br />…<br />}</p><p>（40） 如何在OLE控件中使用OLE_COLOR数据类型<br />诸如COleControl : : GetFortColor和COleControl : : GetBackColor等函数返回OLE _COLOR数据类型的颜色，而GDI对象诸如笔和刷子使用的是COLORREF数据类型，调用COleControl : : TranslateColor可以很容易地将OLE_COLOR类型改为COLORREF类型。下例创建了一个当前背景颜色的刷子：<br /><br />void CSampleControl : : OnDraw (CDC* pdc<br />const Crect&amp; rcBounds , const Crect&amp; rcInvalid<br />)<br />{<br />//Create a brush of the cuttent background color.<br />CBrush brushBack (TranslateColor (GetBackColor () ) )<br /><br />//Paint the background using the current backgroundcolor .<br />pdc—&gt; FilllRect (rcBounds , &amp;brushBack)<br /><br />//other drawign commands<br /><br />…<br />}</p><p>（42） 为什么旋转按钮控件看起来倒转<br />需要调用CSpinCtrl : : SetRange 设置旋转按钮控件的范围，旋转按钮控件的缺省上限为0，缺省下限为100，这意味着增加时旋转按控件的值由100变为0。下例将旋转按钮控件的范围设置为0到100：<br />BOOL CAboutDlg : : OnInitDialog ( )<br />{<br />CDialog : : OnInitDialog ( )<br /><br />//set the lower and upper limit of the spin button<br />m_wndSpin . SetRange ( 0 ,100 )<br /><br />return TRUE<br />}<br /><br />Visual C++ 4.0 Print对话中的Copise旋转按钮控件也有同样的问题：按下Up按钮时拷贝的数目减少，而按下Down 按钮时拷贝的数目增加。</p><p>（43） 为什么旋转按钮控件不能自动地更新它下面的编辑控件<br />如果使用旋转按钮的autu buddy特性， 则必须保证在对话的标记顺序中buddy窗口优先于旋转按钮控件。从Layout菜单中选择Tab Order菜单项（或者按下Crtl+D）可以设置对话的标签顺序。</p><p>（44） 如何用位图显示下压按钮<br />Windows 95按钮有几处新的创建风格，尤其是BS_BITMAP和BS_ICON，要想具有位图按钮，创建按钮和调用CButton : : SetBitmap或CButton : : SetIcon时要指定BS_BITMAP或BS_ICON风格。<br /><br />首先，设置按钮的图标属性。然后，当对话初始化时调用CButton: : SetIcon。注意：下例用图标代替位图，使用位图时要小心，因为不知道背景所有的颜色——并非每个人都使用浅灰色。<br /><br />BOOL CSampleDlg : : OnInitDialog ( )<br />{<br />CDialog : : OnInitDialog ( )<br /><br />//set the images for the push buttons .<br />BOOL CSampleDlg : : OnInitDialog ( )<br />{<br />CDialog : : OnInitDialog ( )<br /><br />//set the images for the push buttons .<br />m_wndButton1.SetIcon (AfxGetApp ( ) —&gt; LoadIcon (IDI _ IPTION1))<br />m_wndButton2.SetIcon (AfxGetApp ( ) —&gt; LoadIcon (IDI _ IPTION2))<br />m_wndButton3.SetIcon (AfxGetApp ( ) —&gt; LoadIcon (IDI _ IPTION3))<br /><br />return TRUE<br />}</p><p></p><p>（45） 如何一个创建三态下压按钮<br />可以使用新的BS_PUSHBUTTON 风格位和检测框以及按钮来创建一个三态下压按钮。这很容易，只需将检测框和按钮拖拉到对话中并指定属性Push—like即可。不用任何附加程序就可以成为三态下压按钮。</p><p>（46） 如何动态创建控件<br />分配一个控件对象的实例并调用其Create成员函数。开发者最容易忽略两件事：忘记指定WS_VISBLE标签和在栈中分配控件对象。下例动态地创建一个下压按钮控件：<br />//In class declaration (.H file ).<br />private : CButton* m _pButton<br /><br />//In class implementation (.cpp file ) .<br />m_pButton =new CButton<br />ASSERT_VALID (m_pButton)<br />m_pButton —&gt;Create (_T ("Button Title ") , WS_CHILD ｜WS_VISIBLE ｜BS_PUSHBUTTON. Crect ( 0, 0, 100 , 24) , this , IDC _MYBUTTON )</p><p>（47） 如何限制编辑框中的准许字符<br />如果用户在编辑控件中只允许接收数字，可以使用一个标准的编辑控件并指定新的创建标志ES_NUMBERS,它是Windows 95新增加的标志，该标志限制 编辑控件只按收数字字符。如果用户需要复杂的编辑控件，可以使用Microsoft 的屏蔽编辑控件，它是一个很有用的OLE定制控件。<br />如果希望不使用OLE 定制控件自己处理字符，可以派生一个CEdit类并处理WM_CHAR消息，然后从编辑控件中过滤出特定的字符。首先，使用ClassWizard建立一个 CEdit的派生类，其次，在对话类中指定一个成员变量将编辑控件分类在OnInitdialog 中调用CWnd: : SubclassDlgItem .<br /><br />//In your dialog class declaration (.H file )<br />private : CMyEdit m_wndEdit // Instance of your new edit control .<br /><br />//In you dialog class implementation (.CPP file )<br />BOOL CSampleDialog : : OnInitDialog ( )<br />{<br />…<br /><br />//Subclass the edit lontrod .<br />m_wndEdit .SubclassDlgItem (IDC_EDIT,this)<br /><br />…<br />}<br /><br />使用ClassWizard处理WM_CHAR消息，计算nChar参量并决定所执行的操作，用户可以确定是否修改、传送字符。下例说明了如何显示字母字符，如果字符是字母字符，则调用CWnd OnChar，否则不调用OnChar.<br />//Only display alphabetic dharacters .<br />void CMyEdit : : OnChar (UINT nChar , UINT nRepCnt , UITN nFlags )<br />{<br />//Determine if nChar is an alphabetic character.<br />if (: : IsCharAlpha ( ( TCHAR) nChar ) )<br />CEdit : : OnChar (nChar, nRepCnt , nFlags )<br />}<br /><br />如果要修改字符，则不能仅仅简单地用修改过的nChar调用CEdit: : OnChar，然后CEdit: : OnChar调用CWnd: : Default获取原来的wParam 和lParam 的值，这样是不行的。要修改一个字符，需要首先修改nChar，然后用修改过的nChar调用CWnd: : DefWindowProc。下例说明了如何将字符转变为大写：<br />//Make all characters uppercase<br />void CMyEdit : : OnChar (UINT nChar , UINT nRepCnt , UINT nFlags )<br />{<br />//Make sure character is uppercase .<br />if (: : IsCharAlpha ( .( TCHAR) nChar)<br />nChar=: : CharUpper(nChar )<br /><br />//Bypass default OnChar processing and directly call<br />//default window proc.<br />DefWindProc (WM_CHAR, nChar , MAKELPARAM (nRepCnt, nFlags ))<br />}</p><p>（48） 如何改变控件的颜色<br />有两种方法。其一，可以在父类中指定控件的颜色，或者利用MFC4.0新的消息反射在控件类中指定颜色。 当控件需要重新着色时，工作框调用父窗口（通常是对话框）的CWnd: : OnCrtlColor,可以在父窗口类中重置该函数并指定控件的新的绘画属性。例如，下述代码将对话中的所有编辑控件文本颜色改为红色：<br />HBRUSH CAboutDig : : OnCtlColor (CDC * pDCM , CWnd * pWnd , UINT nCtlColor)<br /><br />{<br />HBRUSH hbr = CDialog : : OnCtlColor (pDC, pWnd , nCtlColor )<br /><br />//Draw red text for all edit controls .<br />if (nCtlColor= = CTLCOLOR_EDIT )<br />pDC —&gt; SetTextColor (RGB (255, 0 , 0 , ) )<br /><br />return hbr<br />}<br /><br />然而，由于每个父窗口必须处理通知消息并指定每个控件的绘画属性，所以，这种方法不是完全的面向对象的方法。控件处理该消息并指定绘画属性更合情合理。消息反射允许用户这样做。通知消息首先发送给父窗口，如果父窗口没有处理则发送给控件。创建一个定制彩色列表框控件必须遵循下述步骤。<br /><br />首先，使用ClassWizard 创建一个CListBox 的派生类并为该类添加下述数据成员。<br />class CMyListBox publilc CListBox<br />{<br />…<br />private<br />COLORREF m_clrFor // foreground color<br />COLORREF m_clrBack //background color<br />Cbrush m_brush //background brush<br />…<br />}<br />其次，在类的构造函数中，初始化数据中。<br />CMyListBox : : CMyListBox ()<br />{<br />//Initialize data members .<br />m_clrFore =RGB (255 , 255 , 0) //yellow text<br />m_clrBack=RGB (0 , 0 , 255) // blue background<br />m_brush . CreateSolidBrush (m _clrBack )<br />}<br /><br />最后，使用ClassWizard处理反射的WM_CTLCOLOR(=WM_CTLCOLOR)消息并指定新的绘画属性。<br />HBRUSH CMyListBox : : CtlColor (CDC* pDC, UINT nCtlColor )<br />{<br />pDC—&gt;SetTextColor (m_clrFore)<br />pDC—&gt;SetBkColor (m_clrBack)<br /><br />return (HBRUSH) m_brush.GetSafeHandle ()<br />}<br />现在，控件可以自己决定如何绘画，与父窗口无关。</p><p>（49） 当向列表框中添加多个项时如何防止闪烁<br />调用CWnd::SetRedraw 清除重画标志可以禁止CListBox（或者窗口）重画。当向列表框添加几个项时，用户可以清除重画标志，然后添加项，最后恢复重画标志。为确保重画列表框的新项，调用SetRedraw (TRUE) 之后调用CWnd::Invalidate。<br />//Disable redrawing.<br />pListBox-&gt;SetRedraw (FALSE)<br /><br />//Fill in the list box gere<br />//Enable drwing and make sure list box is redrawn.<br />pListBox-&gt;SetRedraw (TRUE)<br />pListBox-&gt;Invalidate ()</p><p>（50） 如何向编辑控件中添加文本<br />由于没有CEdit:: AppendText函数，用户只好自己做此项工作。调用CEdit:: SetSel移动到编辑控件末尾，然后调用CEdit:: ReplaceSel添加文本。下例是AppendText 的一种实现方法：<br /><br />void CMyEdit:: AppendText (LPCSTR pText)<br />{<br />int nLen=GetWindowTextLength ()<br />SetFocus ()<br />SetSel (nLen, nLen)<br /><br />ReplaceSel (pText)<br />}</p><p>（51） 如何访问预定义的GDI对象<br />可以通过调用CDC:: SlectStockObject使用Windows的几个预定义的对象，诸如刷子、笔以及字体。下例使用了Windows预定义的笔和刷子GDI对象在视窗中画一个椭圆。<br />//Draw ellipse using stock black pen and gray brush.<br />void CSampleView:: OnDraw (CDC* pDC)<br />{<br />//Determine size of view.<br />CRect rcView<br />GetClientRect (rcView)<br /><br />//Use stock black pen and stock gray brush to draw ellipse.<br />pDC-&gt;SelectStockObject (BLACK_PEN)<br />pDC-&gt;SelectStockObject (GRAY_BRUSH)<br />//Draw the ellipse.<br />pDC-&gt;Ellipse (reView)<br />}<br /><br />也可以调用新的SDK函数GetSysColorBrush获取一个系统颜色刷子，下例用背景色在视窗中画一个椭圆：<br />void CsampleView:: OnDraw (CDC* pDC)<br />{<br />//Determine size of view.<br />CRect rcView<br />GetClientRect (rcView)<br /><br />//Use background color for tooltips brush.<br />CBrush * pOrgBrush=pDC-&gt;SelectObject ( CBrush ::FromHandle( ::GetSysColorBrush (COLOR_INFOBK)))<br /><br />//Draw the ellipse.<br />pDC-&gt;Ellipse (rcView)<br /><br />//Restore original brush.<br />pDC-&gt;SelectObject (pOrgBrush)<br />}</p><p>（52） 如何获取GDI对象的属性信息<br />可以调用GDIObject:: GetObject。这个函数将指定图表设备的消息写入到缓冲区。下例创建了几个有用的辅助函数。<br />//Determine if font is bold.<br />BOOL IsFontBold (const CFont&amp;font)<br />{<br />LOGFONT stFont<br />font.GetObject (sizeof (LOGFONT), &amp;stFont)<br />return (stFont.lfBold)? TRUE: FALSE<br />}<br /><br />//Return the size of a bitmap.<br />CSize GetBitmapSize (const CBitmap&amp;bitmap)<br />{<br />BITMAP stBitmap<br />bitmap.GetObject (sizeof (BITMAP), &amp;stBitmap)<br />return CSize (stBitmap.bmWidth, stBitmap.bmHeight)<br />}<br /><br />//Create a pen with the same color as a brush.<br />BOOL CreatePenFromBrush (Cpen&amp;pen, cost Cbrush&amp;brush)<br />{<br />LOGBRUSH stBrush<br />brush.Getobject (sizeof (LOGBRUSH), &amp;stBrush)<br />return pen. Createpen (PS_SOLID, 0, stBrush.ibColor)<br />}</p><p>（53） 如何实现一个橡皮区矩形<br />CRectTracker是一个很有用的类，可以通过调用CRectTracker::TrackRubberBand 响应WM_LBUTTONDOWN消息来创建一个橡皮区矩形。<br />下例表明使用CRectTracker移动和重置视窗中的蓝色椭圆的大小是很容易的事情。<br /><br />首先，在文件档中声明一个CRectTracker数据成员：<br />class CSampleView : Public CView<br />{<br />…<br />public :<br />CrectTracker m_tracker<br />…<br />}<br /><br />其次，在文档类的构造函数中初始化CRectTracker 对象：<br />CSampleDoc:: CSampleDOC ()<br />{<br />//Initialize tracker position, size and style.<br />m_tracker.m_rect.SetRect (0, 0, 10, 10)<br />m_tracker.m_nStyle=CRectTracker:: resizeInside | CRectTracker ::dottedLine<br />}<br /><br />然后，在OnDraw函数中画椭圆和踪迹矩形：<br />void CSampleView:: OnDraw (CDC* pDC)<br />{<br />CSampleDoc* pDoc=GetDocument ()<br />ASSERT_VALID (pDoc)<br /><br />//Select blue brush into device context.<br />CBrush brush (RGB (0, 0, 255))<br />CBrush* pOldBrush=pDC-&gt;SelectObject (&amp;brush)<br /><br />//draw ellipse in tracking rectangle.<br />Crect rcEllipse<br />pDoc-&gt;m_tracker.GetTrueRect (rcEllipse)<br />pDC-&gt;Ellipse (rcEllipse)<br /><br />//Draw tracking rectangle.<br />pDoc-&gt;m_tracker.Draw (pDC)<br />//Select blue brush out of device context.<br />pDC-&gt;Selectobject (pOldBrush)<br />}<br /><br />最后，使用ClassWizard处理WM_LBUTTONDOWN消息，并增加下述代码。该段代码根据鼠标击键情况可以拖放、移动或者重置椭圆的大小。<br />void CSampleView::OnLButtonDown (UINT nFlags, CPoint point)<br />{<br />//Get pointer to document.<br />CSampleDoc* pDoc=GetDocument ()<br />ASSERT_VALID (pDoc)<br /><br />//If clicked on ellipse, drag or resize it.Otherwise create a<br />//rubber-band rectangle nd create a new ellipse.<br />BOOL bResult=pDoc-&gt;m_tracker.HitTest (point)!= CRectTracker::hitNothing<br /><br />//Tracker rectangle changed so update views.<br />if (bResult)<br />{<br />pDoc-&gt;m_tracker.Track (this,point,TRue)<br />pDoc-&gt;SetModifiedFlag ()<br />pDoc-&gt;UpdateAllViews (NULL)<br />}<br /><br />else<br />pDoc-&gt;m-tracker.TrackRubberBand(this,point,TRUE)<br />CView:: onLButtonDown (nFlags,point)<br />}</p><p>（54） 如何更新翻转背景颜色的文本<br />调用CDC:: SetBkmode并传送OPAQUE用当前的背景颜色填充背景，或者调用CDC::SetBkMode并传送TRANSPAARENT使背景保持不变，这两种方法都可以设置背景模式。下例设置背景模式为TRANSPARENT，可以两次更新串，用花色带黑阴影更新文本。黑色串在红色串之后，但由于设置了背景模式仍然可见。<br /><br />void CSampleView:: OnDraw (CDC* pDC)<br />{<br />//Determint size of view.<br />CRect rcView<br />GetClientRect (rcVieew)<br /><br />//Create sample string to display.<br />CString str (_T ("Awesome Shadow Text．．．"))<br />//Set the background mode to transparent.<br />pDC-&gt;SetBKMode (TRANSPARENT)<br /><br />//Draw black shadow text.<br />rcView.OffsetRect (1, 1)<br />pDc-&gt;SetTextColor (RGB (0, 0, 0))<br />pDC-&gt;DrawText (str, str.GetLength (), rcView, DT_SINGLELINE | DT_CENTER | DT_VCENTER)<br /><br />//Draw red text.<br />rcView.OffsetRect (-1,-1)<br />pDc-&gt;SetTextColor (RGB (255, 0, 0))<br />pDC-&gt;DrawText (str, str.GetLength (), rcView, DT_SINGLELINE | DT_CENTER | DT_VCENTER)<br /><br />}</p><p>（55） 如何创建一个具有特定点大小的字体<br />可以指定字体逻辑单位的大小，但有时指定字体的点的大小可能会更方便一些。可以如下将字体的点转换为字体的高度：<br /><br />int nHeigth=mulDiv (nPointSize, -dc.GetDeviceCaps (LOGPIXELSY), 72)<br />下例创建了一个8点的Apial字体：<br />…<br />CClientDC dc (AqfxGetMainWnd ())<br /><br />m_font. CreateFont (MulDiv (8, -dc.GetDeviceCaps (LOGPIXELSY), 72), 0, 0, 0, FW_NORMAL, 0, 0, 0, ANSI_CHARSET, OUT_STROKE_PRECIS, CLIP_STROKE_PRECIS, DRAFT_QUALITY, VARIABLE_PITCH | FF-SWISS,_T("Arial"))</p><p>（56） 如何计算一个串的大小<br />函数CDC:: Det text Extent 根据当前选择的字体计算一个串的高度和宽度。如果使用的不是系统字体而是其他字体，则在调用GetTextExtent之前将字体选进设备上下文中是很重要的，否则计算高度和宽度时将依据系统字体，由此得出的结果当然是不正确的。下述样板程序当改变下压按钮的标题时动态调整按钮的大小，按钮的大小由按钮的字体和标题的大小而定。响应消息WM_SETTEXT时调用OnSetText，该消息使用ON_MESSAE宏指令定义的用户自定义消息。<br /><br />LRESULT CMyButton:: OnSettext (WPARAM wParam, LPARAM lParam)<br />{<br />//Pass message to window procedure.<br />LRESULT bResult=CallWindowProc (*GetSuperWndProcAddr(), m_hWnd, GetCurrentMessage() -&gt;message,wParam,lParam)<br />//Get title of push button.<br />CString strTitle<br />GetWindowText (strTitle)<br /><br />//Select current font into device context.<br />CDC* pDC=GetDc ()<br />CFont*pFont=GetFont ()<br />CFont*pOldFont=pDC-&gt;SelectObject (pFont)<br /><br />//Calculate size of title.<br />CSize size=pDC-&gt;GetTextExent (strTitle,strTitle.GetLength())<br /><br />//Adjust the button's size based on its title.<br />//Add a 5-pixel border around the button.<br />SetWindowPos (NULL, 0, 0, size.cx+10, size.cy+10, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE)<br />//Clean up.<br />pDC-&gt;SelectFont (pOldFont)<br />ReleaseDC (pDC)<br /><br />return bResult<br />}<br /></p><p>（57） 如何显示旋转文本<br />只要用户使用TrueType或者GDI笔或字体就可以显示旋转文本(有些硬件设备也支持旋转光栅字体）。LOGFONT结构中的ifEscapement成员指定了文本行和x轴的角度，角度的单位是十分之一度而不是度，例如，ifEscapement为450表示字体旋转45度。为确保所有的字体沿坐标系统的同一方向旋转，一定要设置ifEscapement成员的CLIP_LH_ANGLES位，否则，有些字体可能反向旋转。下例使用了14点Arial字体每间隔15度画一个串。<br />void CSampleView:: OnDraw (CDC* pDC)<br />{<br />//Determine the size of the window.<br />CRect rcClient<br />GetClientRect (rcClient)<br /><br />//Create sample string.<br />CString str (_T ("Wheeee．．．I am rotating!"))<br />//Draw transparent, red text.<br />pDC-&gt;SetBkMode (TRANSPARENT)<br />pDC-&gt;SetTextColor (RGB (255,0,0))<br />CFont font<br />//font object<br />LOGFONT stFont //font definition<br />//Set font attributes that will not change.<br />memset (&amp;stFont, 0, sizeof (LOGFONT))<br />stFont.ifheight=MulDiv (14, -pDC-&gt;GetDeviceCaps(LOGPIXELSY), 72)<br />stFont.ifWeight=FW_NORMAL<br />stFont.ifClipPrecision=LCIP_LH_ANGLES<br />strcpy (stFont.lfFaceName, "Arial")<br /><br />//Draw text at 15degree intervals.<br />for (int nAngle=0 nAngle&lt;3600 nAngle+=150)<br />{<br />//Specify new angle.<br />stFont.lfEscapement=nAngle<br /><br />//Create and select font into dc.<br />font.CreateFontIndirect(&amp;stfont)<br />CFont* pOldFont=pDC -&gt;SelectObject(&amp;font)<br /><br />//Draw the text.<br />pDC-&gt;SelectObject(pOldFont)<br />font.DelectObjext()<br />}<br />}</p><p></p><p>（58） 如何正确显示包含标签字符的串<br />调用GDI文本绘画函数时需要展开标签字符，这可以通过调用CDC:: TabbedTextOut或者CDC:: DrawText并指定DT_EXPANDTABS标志来完成。TabbedTextOut函数允许指定标签位的数组，下例指定每20设备单位展开一个标签：<br /><br />void CSampleView:: OnDraw (CDC* pDC)<br />{<br />CTestDoc* pDoc=GetDocument ()<br />ASSERT_VALID (pDoC)<br /><br />CString str<br />str.Format (_T ("Cathy\tNorman\tOliver"))<br />int nTabStop=20 //tabs are every 20 pixels<br />pDC-&gt;TabbedtextOut (10, 10, str, 1, &amp;nTabStop, 10)<br />}</p><p>（59） 如何快速地格式化一个CString对象<br />调用CString:: Format，该函数和printf函数具有相同的参数，下例说明了如何使用Format函数：<br /><br />//Get size of window.<br />CRect rcWindow<br />GetWindowRect (rcWindow)<br />//Format message string.<br />CString strMessage<br />strMessage.Format (_T ("Window Size (%d, %d)"),<br /><br />rcWindow.Width (), rcWindow.Height ())<br /><br />//Display the message.<br />MessageBox (strmessage)</p><p>（60） 串太长时如何在其末尾显示一个省略号<br />调用CDC:: DrawText并指定DT_END_ELLIPSIS标志，这样就可以用小略号取代串末尾的字符使其适合于指定的边界矩形。如果要显示路径信息，指定DT_END_ELLIPSIS标志并省略号取代串中间的字符。<br /><br />void CSampleView:: OnDraw (CDC* pDC)<br />{<br />CTestDoc* pDoc=GetDocument ()<br />ASSERT_VALID (pDoc)<br /><br />//Add ellpsis to end of string if it does not fit<br />pDC-&gt;Drawtext (CString ("This is a long string"), CRect (10, 10, 80, 30), DT_LEFT | DT_END_ELLIPSIS)<br /><br />//Add ellpsis to middle of string if it does not fit<br />pDC-&gt;DrawText (AfxgetApp () -&gt;m_pszhelpfilePath, CRect (10, 40, 200, 60), DT_LEFT | DT_PATH_ELLIPSIS)<br />}<br /></p><p>（61） 为什么即使调用EnableMenuItem菜单项后，菜单项还处于禁止状态<br />需要将CFrameWnd:: m_bAutomenuEnable设置为FALSE，如果该数据成员为TRUE（缺省值），工作框将自动地禁止没有ON_UPDATE_COMMAND_UI或者ON_COMMAND的菜单项。<br /><br />//Disable MFC from automatically disabling menu items.<br />m_bAuoMenuEnable=FALSE<br />//Now enable the menu item.<br />CMenu* pMenu=GetMenu ()<br />ASSERT_VALID (pMenu)<br /><br />pMenu-&gt;EnableMenuItem (ID_MENU_ITEM,MF_BYCOMMAND | MF_ENABLED)</p><p></p><p>（62） 如何给系统菜单添加一个菜单项<br />给系统菜单添加一个菜单项需要进行下述三个步骤：<br />首先，使用Resource Symbols对话（在View菜单中选择Resource Symbols．．．可以显示该对话）定义菜单项ID，该ID应大于0x0F而小于0xF000；<br />其次，调用CWnd::GetSystemMenu获取系统菜单的指针并调用CWnd:: Appendmenu将菜单项添加到菜单中。下例给系统菜单添加两个新的<br />int CMainFrame:: OnCreate (LPCREATESTRUCT lpCreateStruct)<br />{<br />…<br />//Make sure system menu item is in the right range.<br />ASSERT (IDM_MYSYSITEM &amp;0xFFF0)==IDM_MYSYSITEM)<br />ASSERT (IDM-MYSYSITEM&lt;0xF000)<br /><br />//Get pointer to system menu.<br />CMenu* pSysmenu=GetSystemmenu (FALSE)<br />ASSERT_VALID (pSysMenu)<br />//Add a separator and our menu item to system menu.<br />CString StrMenuItem (_T ("New menu item"))<br />pSysMenu-&gt;Appendmenu (MF_SEPARATOR)<br />pSysMenu-&gt;AppendMenu (MF_STRING, IDM_MYSYSITEM, strMenuitem)<br /><br />…<br />}<br /><br />现在，选择系统菜单项时用户应进行检测。使用ClassWizard处理WM_SYSCOMMAND消息并检测用户菜单的nID参数：<br />void CMainFrame:: OnSysCommand (UINT nID,LPARAM lParam)<br />{<br />//Determine if our system menu item was selected.<br />if ( (nID &amp; 0xFFF0)==IDM_MYSYSITEM)<br />{<br />//TODO-process system menu item<br />}<br /><br />else<br />CMDIFrameWnd ::OnSysCommand (nID, lParam)<br />}<br />最后，一个设计良好的UI应用程序应当在系统菜单项加亮时在状态条显示一个帮助信息，这可以通过增加一个包含系统菜单基ID的串表的入口来实现。</p><p>（63） 如何确定顶层菜单所占据的菜单行数<br />这可以通过简单的减法和除法来实现。首先，用户需要计算主框窗口的高度和客户区；其次，从主框窗口的高度中减去客户区、框边界以及标题的高度；最后，除以菜单栏的高度。下例成员函数是一个计算主框菜单所占据的行数的代码实现。<br /><br />int CMainFrame:: GetMenuRows ()<br />{<br />CRect rcFrame,rcClient<br />GetWindowRect (rcFrame)<br />GetClientRect (rcClient)<br />return (rcFrame.Height () -rcClient.Height () - :: GetSystemMetrics(SM_CYCAPTION) - (:: getSystemMetrics(SM_CYFRAME) *2)) / :: GetSystemMetrics(SM_CYMENU)<br />}</p><p>（64） 在用户环境中如何确定系统显示元素的颜色<br />调用SDK函数GetSysColor可以获取一个特定显示元素的颜色。下例说明了如何在MFC函数CMainFrameWnd:: OnNcPaint中调用该函数设置窗口标题颜色。<br /><br />void CMiniFrameWnd:: OnNcPaint ()<br />{<br />…<br />dc.SetTextColor (:: GetSysColor (m_bActive ? COLOR_CAPTIONTEXT : COLOR_INACTIVECAPTIONTEXT))<br />…</p><p></p><p>（65） 如何查询和设置系统参数<br />在Windows 3.1 SDK中介绍过SDK函数SystemParametersInfo，调用该函数可以查询和设置系统参数，诸如按键的重复速率设置、鼠标双击延迟时间、图标字体以及桌面覆盖位图等等。<br /><br />//Create a font that is used for icon titles.<br />LOGFONT stFont<br />∶: SystemParametersInfo (SPIF_GETICONTITLELOGFONT, sizeof (LOGFONT), &amp;stFont, SPIF_SENDWININICHANGE)<br />m_font.CreateFontIndirect (&amp;stFont)<br /><br />//Change the wallpaper to leaves.bmp.<br />∶ : SystemParametersInfo (SPI_SETDESKWALLPAPER, 0, _T (" forest.bmp"), SPIF_UPDATEINIFILE)</p><p></p><p>（66） 如何确定当前屏幕分辨率<br />调用SDK函数GetSystemMetrics，该函数可以检索有关windows显示信息，诸如标题大小、边界大小以及滚动条大小等等。<br /><br />//Initialize CSize object with screen size.<br />CSize sizeScreen (GetSystemMetrics (SM_CXSCREEN),<br />GetSystemMetrics (SM_CYSCREEN))</p><p></p><p>（67） 如何使用一个预定义的Windows光标<br />调用CWinApp:: LoadStandardCursor并传送光标标识符。<br />BOOL CSampleDialog:: OnSetCursor (CWnd* pWnd,<br />UINT nHitTest, UINT<br />message)<br />{<br />//Display wait cursor if busy.<br />if (m_bBusy)<br />{<br />SetCursor (AfxGetApp () -&gt;LoadStandardCursor (IDC_WAIT))<br />return TRUE<br />}<br /><br />return CDialog:: OnSetCursor (pWnd. nHitTest,message)<br />}</p><p>（68） 如何检索原先的Task Manager应用程序使用的任务列表<br />原先的Task Manager应用程序显示顶层窗口的列表。为了显示该列表，窗口必须可见、包含一个标题以及不能被其他窗口拥有。调用CWnd:: GetWindow可以检索顶层窗口的列表，调用IsWindowVisible、GetWindowTextLength以及GetOwner可以确定窗口是否应该在列表中。下例将把TaskManager窗口的标题填充到列表中。<br /><br />void GetTadkList (CListBox&amp;list)<br />{<br />CString strCaption<br />//Caption of window.<br /><br />list.ResetContent ()<br />//Clear list box.<br /><br />//Get first Window in window list.<br />ASSERT_VALID (AfxGetMainWnd ())<br />CWnd* pWnd=AfxGetMainWnd () -&gt;GetWindow (GW_HWNDFIRST)<br /><br />//Walk window list.<br />while (pWnd)<br />{<br />// I window visible, has a caption, and does not have an owner?<br />if (pWnd -&gt;IsWindowVisible()<br />&amp;&amp; pWnd -&gt;GetWindowTextLength ()<br />&amp;&amp;! pWnd -&gt;GetOwner ())<br />{<br /><br />//Add caption o window to list box.<br /><br />pWnd -&gt;GetWindowText (strCaption)<br /><br />list.AddString (strCaption)<br />}<br />//Get next window in window list.<br />pWnd=pWnd -&gt;GetWindow(GW_HWNDNEXT)<br />}<br />}</p><p>（69） 如何确定Windows和Windows系统目录<br />有两个SDK函数可以完成该功能。GetWindowsDirectory和GetSystemDirectory，下例说明了如何使用这两个函数：<br /><br />TCHAR szDir [MAX_PATH]<br />//Get the full path of the windows directory.<br />∶ : GetWindowsDirectory (szDir, MAX_PATH)<br />TRACE ("Windows directory %s\n", szDir)<br />//Get the full path of the windows system directory.<br />∶ : GetSystemDirectory (szDir, MAX_PATH)<br />TRACE ("Windows system directory %s\n", szDir)</p><p>（70） 在哪儿创建临文件<br />调用SDK函数GetTemPath可以确定临时文件的目录，该函数首先为临时路径检测TMP环境变量：如果没有指定TMP，检测TMP环境变量，然后返回到当前目录。下例说明了如何创建一个临时文件。<br /><br />…<br />//get unique temporary file.<br />CString strFile<br />GetUniqueTempName (strFile)<br />TRY<br />{<br />//Create file and write data.Note that file is closed<br />//in the destructor of the CFile object.<br />CFile file (strFile,CFile ::modeCreate | Cfile:: modeWrite)<br /><br />//write data<br />}<br /><br />CATCH (CFileException, e)<br />{<br />//error opening file<br />}<br />END_CATCH<br />…<br /><br />Void GetuniqueTempName (CString&amp; strTempName)<br />{<br />//Get the temporary files directory.<br />TCHAR szTempPath [MAX_PATH]<br />DWORD dwResult=:: GetTempPath (MAX_PATH, szTempPath)<br />ASSERT (dwResult)<br /><br />//Create a unique temporary file.<br />TCHAR szTempFile [MAX_PATH]<br />UINT nResult=GetTempFileName (szTempPath, _T ("~ex"),0,szTempfile)<br />ASSERT (nResult)<br /><br />strTempName=szTempFile<br />}</p><p>（71） 我怎样才能建立一个等待光标?<br />调 用 BeginWaitCursor 函 数 来 启 动 等 待 光 标，调 用 EndWaitCursor 函 数 来 结 束 等 待 光 标。要 注 意，二 者 都 要 调 用 app 的 成 员 函 数，如 下 所 示:<br /><br />    AfxGetApp()-&gt;BeginWaitCursor();<br />    // 要做的事<br />    AfxGetApp()-&gt;EndWaitCursor();</p><p>（72） 我在MDI框架中有个 form 视窗。它有个取消按钮，我需要当用户按取消按钮时可关闭form视窗。我应该如何关闭该文档?<br />调 用 OnCloseDocument 函 数。</p><p>（73） 如何访问桌面窗口<br />静态函数CWnd:: GetDesktopWindow 返回桌面窗口的指针。下例说明了MFC函数CFrameWnd::BeginModalStae是如何使用该函数进入内部窗口列表的。<br /><br />void CFrameWnd::BeginModalState ()<br />{<br />…<br />//first count all windows that need to be disabled<br />UINT nCount=0<br />HWND hWnd= :: GetWindow (:: GetDesktopWindow(), GW_CHILD)<br />while (hWnd!=NULL)<br />{<br />if (:: IsWindowEnabled (hwnd)<br />&amp;&amp; CWnd::FromHandlePermanent (hWnd)!=NULL<br />&amp;&amp; AfxIsDescendant (pParent-&gt;m_hWnd, hWnd)<br />&amp;&amp; :: SendMessage (hWnd, WM_DISABLEMODAL, 0, 0)==0)<br />{<br />++nCount<br />}<br />hWnd=:: GetWindow (hWnd, GW_HWNDNEXT)<br />}<br />…</p><p></p><p> </p><p>（76） 我在我的程序中是了CDWordArray。我向它添加了约10,000个整数，这使得它变得非常非常慢。为什么会这么糟?<br />CDWordArray 是 很 好 用 的，只 是 因 为 你 没 有 指 定 数 组 的最大尺寸。因 此，当 你 添 加 新 元 素 时，该 类 会 从 堆 中 重 新 分 配 空 间。不 幸 的 是，该 类 会 在 每 次 插 入 新 元 素 时 都 为 数 组 重 新 分 配 空 间。如 果 你 向 它 添 加 了 很 多 新 元 素，所 有 这 些 分 配 和 复 制 数 组 的 操 作 会 就 会 使 它 变 慢。解 决 该 问 题 的 方 法 是，你 可 以 使 用 SetSize 函 数 的 第 二 个 参 数 来 改 变 这 种 重 新 分 配 的 频 率。例 如，如 果 你 把 该 参 数 设 置 为 500，则 每 次 数 组 空 间 超 出 时 它 才 重 新 分 配 并 添 加 500 个 新 空 间，而 不 是 1 个。这 样 一 来，你 就 可 以 不 用 重 新 分 配 而 添 加 了 另 外 499 个 元 素 空 间，这 也 会 大 大 提 高 程 序 的 运 行 速 度。</p><p></p><p>（77） 我该如何改变MDI框架窗口的子窗口的大小以使在窗口以一定的大小打开?<br />在 视 中 的 OnInitialUpdate 函 数 中 调 用 GetParentFrame 函 数。GetParentFrame 会 返 回 一 指 向 一 保 存 有 该 视 的 框 架 窗 口 的 指 针。然 后 调 用 在 框 架 窗 口 上 调 用 MoveWindow。</p><p>（78） 在我的程序的某些部分，我可以调用 MessageBox 函数来建立一个信息对话框，例如在视类中。但是，在其它部分我却不能，如文档类中。为什么？我怎样才能在我的应用程序类中建立一个信息对话框？<br />MessageBox 函 数 来 自 CWnd 类，所 以 你 只 能 在 从 CWnd 继 承 的 类 ( 如 CView ) 中 调 用 它。但 是，MFC 也 提 供 了 AfxMessageBox 函 数，你 可 以 在 任 何 地 方 调 用 它。</p><p></p><p>（79） 我需要在我的程序中设置全局变量，以使文档中的所有类都能访问。我应该吧它放到哪儿?<br />把 该 变 量 放 到 该 应 用 程 序 类 的 头 文 件 中 的 attribute 处。然 后，在 程 序 的 任 何 地 方，你 都 可 以 用 下 面 的 方 法 来 访 问 该 变 量：<br /><br />    CMyApp *app = (CMyApp *)AfxGetApp();<br />    app-&gt;MyGlobalVariable = ...</p><p><br />（81） 我怎样才能在我的应用程序中循环浏览已经打开的文档?<br />使用CDocTemplate中未公开的GetFirstDocPosition()和GetNextDoc()函数。 </p><p></p><p>（82）才能在我的应用程序中循环浏览已经打开的视?<br />使 用 CDocument 中 未 公 开 的 GetFirstViewPosition() 和 GetNextView() 函 数。</p><p>（83）数PreCreateWindow是干什么用的?<br />PreCreateWindow 允 许 你 在 调 用 CreateWindow 之 前 来 改 变 窗 口 属 性。</p><p>（84）该怎样防止MFC在窗口标题栏上把文档名预置成应用程序名?<br />在 PreCreateWindow 函 数 中 删 除 FWS_PREFIXTITLE 标 志 的 窗 口 样 式：<br /><br />    cs.style &amp;= ~FWS_PREFIXTITLE;</p><p></p><p>（85） 我应该怎样防止MFC在窗口标题栏上添加文档名?<br />在 PreCreateWindow 函 数 中 删 除 FWS_ADDTOTITLE 标 志 的 窗 口 样 式：<br /><br />    cs.style &amp;= ~FWS_ADDTOTITLE ;</p><p></p><p>（86） 我应该如何改变视窗口的大小?<br />因 为 视 窗 口 实 际 上 是 框 架 窗 口 的 子 窗 口，所 以 你 必 须 改 变 框 架 窗 口 的 大 小，而 不 是 改 变 视 窗 口。使 用 CView 类 中 的 GetParentFrame() 函 数 获 得 指 向 框 架 窗 口 的 指 针，然 后 调 用 MoveWindow() 函 数 来 改 变 框 架 的 大 小。这 会 使 变 尺 寸 的 视 充 满 框 架 窗 口。</p><p>（87） 我有一无模式对话框。我怎样才能在窗口退出时删除CDialog对象?<br />把“delete this”加 到 PostNcDestroy 中。这 主 要 用 在 需 要 自 动 删 除 对 象 的 场 合。</p><p></p><p>（88） 为什么把“delete this”放在PostNcDestroy中而不是OnNcDestroy?<br />OnNcDestroy 只 被 已 建 立 的 窗 口 调 用。如 果 建 立 窗 口 失 败 ( 如 PreCreateWindow )，则 没 有 窗 口 处 来 发 送 WM_NCDESTROY 消 息。PostNcDestroy 是 在 对 象 窗 口 被 完 全 删 除，在 OnNcDestroy 后，甚 至 在 窗 口 建 立 失 败 之 后 调 用 的。</p><p></p><p>（89） File菜单中的MRU列表是从哪儿来的？列表中的名字放在哪儿了？我怎样才能改变列表中项目的最大值？<br />在 应 用 程 序 类 的 InitInstance 函 数 中 对 LoadStdProfileSettings 的 调 用 中。该 调 用 接 受 一 个 参 数 ( 在 缺 省 情 况 下 如 果 没 有 传 递 值 则 为 4 )。MRU 文 件 名 是 从 INI 文 件 中 调 用 的。如 果 你 有 带 有 ID_FILE_MRU_FILE1 的 ID 的 菜 单 选 项，它 会 为 调 入 的 MRU 列 表 所 替 换。如 果 你 改 变 传 递 给 LoadStdProfileSettings 的 数 值 ( 最 大 为 16 )，则 你 就 改 变 了 所 装 如 文 件 名 的 最 大 值。</p><p>（90） 我在菜单中添加了新的项。但是，当我选该项时，在状态栏上没有出现任何提示信息。为什么?<br />打 开 资 源 文 件 中 的 菜 单 模 板。打 开 新 菜 单 选 项 的 属 性 对 话 框。在 对 话 框 的 底 部 的 Prompt 编 辑 框 中 ，你 可 以 如 下 指 定 状 态 栏 上 的 提 示 信 息 和 工 具 栏 上 的 提 示 信 息 ( 如 果 你 已 经 建 立 的 工 具 栏 按 钮 ):<br /><br />    Status bar string\nFlying tag<br /></p><p>（92） 我建立了一个对话框。但是当我显示该对话框时，第一个编辑框总是不能获得焦点，我必须单击它来使它获得焦点。我怎样才能使第一个编辑框在对话框打开时就获得焦点?<br />打 开 资 源 编 辑 器 中 的 对 话 框 模 板。在 Layout 菜单 中 选 择 Tab Order 选 项。按 你 的 需 求 单 击 对 话 框 中 的 控 制 来 重 新 排 列 这 些 控 制 的 tab 顺 序。</p><p>（93） 我怎样才能使一个窗口具有“always on top”特性?<br />在 调 用 OnFileNew 后，在 你 的 InitInstance 函 数 中 加 上 下 面 的 代 码：<br /><br />m_pMainWnd-&gt;SetWindowPos(&amp;CWnd::wndTopMost,0,0,0,0, SWP_NOMOVE | SWP_NOSIZE);</p><p>(94)   我要为我的form view添加文档模板。我先建立了对话框模板，然后使用ClassWizard建立了基于CFormView的新类，它也是从CDocument继承来的。我还建立了相应的资源并在InitInstance中添加了新的文档模板。但是，当我试图运行该程序时，出现了Assertion信息。为什么?</p><p>form 的 对 话 框 模 板 需 要 些 特 殊 设 置 以 便 可 用 于 CFromView。确 保 这 些 设 置 的 最 简 单 方 法 是 使 用 AppWizard 来 建 立 CFormView 应 用 程 序，并 查 看 AppWizard 所 建 立 的 对 话 框 模 板 所 选 择 的Styles Properties。你 会 发 现 该 对 话 框 模 板 具 有 下 列 样 式：没 有 标 题 栏、不 可 见 和“Child”。把 你 的 form view 的 对 话 框 属 性 变 成 这 样 就 可 以 了。<br /><br />(95)   我在一对话框中有一列表框，我需要tabbed列表框中的项目。但是，当我处理含有tab字符(用AddString添加的)的列表项时，tab被显示成小黑块而没有展开。哪儿出错了?</p><p>在 对 话 框 模 版 中，打 开 列 表 框 的 属 性。确 保 选 择 了“Use Tabstops” 样 式。然 后，确 保 在 对 话 框 类 中 OnInitDialog 函 数 中 调 用 SetTabStops。<br /><br />(96)  我建立了一个应用程序，并使用了CRecordset类。但是，当我运行该程序时，它试图要访问数据库，并给出“Internal Application Error”对话框。我应该怎样做?</p><p>通 常 情 况 下，当 你 的 程 序 中 向 数 据 库 发 送 信 息 的 SQL 语 句 出 现 问 题 时 才 出 现 该 对 话 框。例 如，参 见 下 面 的 例 子：<br /><br />    set.m_strFilter = "(ZipCode = '27111')";<br />如 果 ZipCode 列 被 定 义 为 字 符 串 时 不 会 出 现 问 题，如 果 定 义 为 long，则 会 出 现“Internal Application Error”对 话 框，这 是 由 于 类 型 不 匹 配 的 缘 故。如 果 你 删 除 27111 的 单 引 号，则 不 会 出 现 问 题。当 你 看 到“Internal Application Error”时，最 好 检 查 一 下 试 图 要 发 送 给 数 据 库 的 SQL 语 句。<br /></p><p>(98)     当我打开应用程序中的窗口时，我要传递该窗口的矩形尺寸。该矩形指定了窗口的外围大小，但是当我调用GetClientRect时，所得到的尺寸要比所希望的值要小(因为工具栏和窗口边框的缘故)。有其它方法来计算窗口的尺寸吗?</p><p>参 见 CWnd::CalcWindowRect。<br /><br />(99)   我在文档类中设置了一个整型变量。但是，当我试图把该变量写入Serialize函数中的archive文件中时，出现了类型错误。而文档中的其它变量没有问题。为什么?</p><p>archive 类 只 重 载 某 些 类 型 的 &gt;&gt; 和 &lt;&lt; 操 作 符。“int”类 型 没 有 在 其 中，也 许 是 因 为 int 变 量 在 Windows 3.1 与 Windows NT/95 有 所 不 同 的 缘 故 吧。“long”类 型 得 到 了 支 持，所 以 你 可 以 把 int 类 型 改 成 long 型。参 见 MFC 帮 助 文 件 中 CArchive 类。<br /></p><p><br />(100)  如何控制菜单的大小?<br />我用MFC的CMenu生成了一个动态菜单(例如File,Edit,View...Help), 我想控制这个菜单的大小(长+高).</p><p>方法一:查找 WM_MEASUREITEM 和 MEASUREITEMSTRUCT.<br />方法二:查询系统::GetSystemMetric(SM_CXMENUSIZE).</p><p>     /* 你可以通过如下代码来获得文本的大小:<br />        (A)获得被使用的字体 */</p><p>       NONCLIENTMETRICS ncm;<br />     HFONT hFontMenu;<br />     SIZE size;<br />     size.cy = size.cy = 0;</p><p>     memset(&amp;ncm, 0, sizeof(NONCLIENTMETRICS));<br />     ncm.cbSize = sizeof(NONCLIENTMETRICS);<br />     if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &amp;ncm, 0))<br />     {<br />          hFontMenu = CreateFontIndirect(&amp;ncm.lfMenuFont);<br />          /*<br />          (B) 获得菜单项的文本: */<br />          char szText[_MAX_PATH];</p><p>          pMenu-&gt;GetMenuString(0, szText, _MAX_PATH, MF_BYPOSITION);<br />          /*<br />          然后,获得菜单项文本的高度: */<br />          HFONT hFontOld;<br />          HDC hDC;</p><p>          hDC = ::GetDC(NULL);<br />          hFontOld = (HFONT) ::SelectObject(hDC, hFontMenu);<br />          GetTextExtentPoint32(hDC, szText, lstrlen(szText), &amp;size);<br />          SelectObject(hDC, hFontOld);<br />          ::ReleaseDC(NULL, hDC);<br />     }<br />     /*此时,size.cy即为高度,size.cx为宽度,你可以给菜单加上自定义的高度和宽度,通过比较,我发现宽度为4</p><p>比较合适。*/</p><p><br />(101)  改变LVIS_SELECTED的状态颜色?<br />我想将CListCtrl项和CTreeCtrl项在LVIS_SELECTED状态时的颜色变灰.</p><p>方法一:查找函数CustomDraw,它是IE4提供的公共控制,允许有你自己的代码.<br />方法二:生成一个draw控件,然后在DrawItem中处理文本颜色.</p><p>(102)   如何只存储文档的某一部分?<br />我只想存储文档的某一部分,能否象使用文件一样使用文档?(也就是有定位函数).将每个CArchive类设置为CFile类的派生类,这样你就能使用Seek等成员函数.</p><p>(103)   保存工具条菜单有bug吗?<br /></p><p>使用浮动菜单条时,SaveBarState和LoadBarState出现了问题.如果菜单是浮动的,重起应用程序时它会出现在左上角,而它固定在屏幕其它位置时,下一次启动就会出现在该位置,这是什么原因?你试试这个PToolBar-&gt;Create(this,...,ID_MYTOOLBAR);<br />你的工具条需要包括id,而不是象默认的工具条那样.</p><p>(104)   Tip of the day的bug</p><p>我创建了一个简单的mdi应用程序,使用.BSF(自定义的文档扩展名)作为它的文档我保存一个foo.bsf文档后,可以在资源管理器中双击该文件打开mdi应用程序同时打开foo.bsf文档.但当我给mdi应用程序加上a tip of the day组件之后,从资源管理器中双击foo.bsf后,就会给我一个警告:ASSERT(::IsWindow(m_hWnd)),然后mdi应用程序就死那了.<br /><br />当从dde启动应用程序(例如:双击相关文档)时,"Tip of the Day"是有bug的.你可以看看函数"ShowTipAtStartup",它在"InitInstance"中调用,可以看到tip of the day作为一个模式对话框显示,在处理其它消息时它一直进行消息循环你可心修改ShowTipAtStartup使其从dde启动时不出现tip of the day.<br />void CTipOfApp::ShowTipAtStartup(void)<br />        {<br />                // CG: This function added by 'Tip of the Day' component.<br /><br />                CCommandLineInfo cmdInfo;<br />                ParseCommandLine(cmdInfo);<br /><br />                if (<br />                        cmdInfo.m_bShowSplash &amp;&amp;<br />                        cmdInfo.m_nShellCommand != CCommandLineInf:FileDDE<br />                        )<br />                {<br />                        CTipDlg dlg;<br />                        if (dlg.m_bStartup)<br />                                dlg.DoModal();<br />                }<br />        }<br />如果还有其它bug,你可以设定cmdInfo.m_nShellCommand的过滤.<br /><br />(105)   如何可以让我的程序可以显示在其它的窗口上面?<br /><br />让用户选择"总是在最上面"最好是在系统菜单里加入一个选项.可以通过修改WM_SYSCOMMAND消息来发送用户的选择.菜单的命令标识(id)会作为一个参数传给OnSysCommand().要定义标识(id),将如下代码加入到CMainFrame.CPP中:<br /><br />    #define WM_ALWAYSONTOP WM_USER + 1<br />将"总在最上面"的菜单项加入到系统菜单中,将如下代码加入到函数CMainFrame::OnCreate()中:<br /><br />      CMenu* pSysMenu = GetSystemMenu(FALSE);<br />      pSysMenu-&gt;AppendMenu(MF_SEPARATOR);<br />      pSysMenu-&gt;AppendMenu(MF_STRING, WM_ALWAYSONTOP,<br />                     "&amp;Always On Top");<br />使用ClassWizard,加入对WM_SYSCOMMAND消息的处理,你应该改变消息过滤器,使用系统可以处理这个消息.<br />void CMainFrame::OnSysCommand(UINT nID, LPARAM lParam)<br />{<br />    switch ( nID )<br />    {<br />    case WM_ALWAYSONTOP:<br /><br />        if ( GetExStyle() &amp; WS_EX_TOPMOST )<br />        {<br />            SetWindowPos(&amp;wndNoTopMost, 0, 0, 0, 0,<br />                SWP_NOSIZE | SWP_NOMOVE);<br />            GetSystemMenu(FALSE)-&gt;CheckMenuItem(WM_ALWAYSONTOP,<br />                MF_UNCHECKED);<br />        }<br />        else<br />        {<br />            SetWindowPos(&amp;wndTopMost, 0, 0, 0, 0,<br />                SWP_NOSIZE | SWP_NOMOVE);<br />            GetSystemMenu(FALSE)-&gt;CheckMenuItem(WM_ALWAYSONTOP,MF_CHECKED);<br />        }<br /><br />        break;<br /><br />    default:<br />        CFrameWnd::OnSysCommand(nID, lParam);<br />    }<br />}<br /><br />(106)    如何控制窗口框架的最大最小尺寸?</p><p>要控制一个框架的的最大最小尺寸,你需要做两件事情.在CFrameWnd的继承类中处理消息WM_GETMINMAXINFO,结构MINMAXINFO设置了整个窗口类的限制,因此记住要考虑工具条,卷动条等等的大小.<br /><br />// 最大最小尺寸的象素点 - 示例<br />#define MINX 200<br />#define MINY 300<br />#define MAXX 300<br />#define MAXY 400<br /><br />void CMyFrameWnd::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI)<br />{<br />    CRect rectWindow;<br />    GetWindowRect(&amp;rectWindow);<br /><br />    CRect rectClient;<br />    GetClientRect(&amp;rectClient);<br /><br />      // get offset of toolbars, scrollbars, etc.<br />    int nWidthOffset = rectWindow.Width() - rectClient.Width();<br />    int nHeightOffset = rectWindow.Height() - rectClient.Height();<br /><br />    lpMMI-&gt;ptMinTrackSize.x = MINX + nWidthOffset;<br />    lpMMI-&gt;ptMinTrackSize.y = MINY + nHeightOffset;<br />    lpMMI-&gt;ptMaxTrackSize.x = MAXX + nWidthOffset;<br />    lpMMI-&gt;ptMaxTrackSize.y = MAXY + nHeightOffset;<br />}<br />第二步,在CFrameWnd的继承类的PreCreateWindow函数中去掉WS_MAXIMIZEBOX消息,否则在最大化时你将得不到预料的结果.<br /><br />BOOL CMyFrameWnd::PreCreateWindow(CREATESTRUCT&amp; cs)<br />{<br />    cs.style &amp;= ~WS_MAXIMIZEBOX;<br />    return CFrameWnd::PreCreateWindow(cs);<br />}<br /><br />(107)    如何改变窗口框架的颜色?</p><p>MDI框架的客户区被另一个窗口的框架所覆盖.为了改变客户区的背景色,你需要重画这个客户窗口.为了做到这点,你要处理消息WM_ERASEBKND产生一个新类,从CWnd继承,姑且称之为CMDIClient.给它加上一个成员变量,<br />#include "MDIClient.h"<br />class CMainFrame : public CMDIFrameWnd<br />{<br />...<br />protected:<br />CMDIClient m_wndMDIClient;<br />}<br />在CMainFrame中重载CMDIFrameWnd::OnCreateClient<br />BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)<br />{<br />    if ( CMDIFrameWnd::OnCreateClient(lpcs, pContext) )<br />    {<br />        m_wndMDIClient.SubclassWindow(m_hWndMDIClient);<br />        return TRUE;<br />    }<br />    else<br />        return FALSE;<br />}<br />然后就可以加入对消息WM_ERASEBKGND的处理了.<br /><br />(108)    如何将应用程序窗口置于屏幕正中?</p><p>要将你的应用程序窗口放置在屏幕正中央,只须在MainFrame的OnCreate函数中加入:<br />CenterWindow( GetDesktopWindow() );</p></div>
				</div>
		</div>
<img src ="http://www.cppblog.com/zgysx/aggbug/16952.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zgysx/" target="_blank">永遇乐</a> 2006-12-28 17:54 <a href="http://www.cppblog.com/zgysx/archive/2006/12/28/16952.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]windows消息大全</title><link>http://www.cppblog.com/zgysx/archive/2006/12/28/16946.html</link><dc:creator>永遇乐</dc:creator><author>永遇乐</author><pubDate>Thu, 28 Dec 2006 08:39:00 GMT</pubDate><guid>http://www.cppblog.com/zgysx/archive/2006/12/28/16946.html</guid><wfw:comment>http://www.cppblog.com/zgysx/comments/16946.html</wfw:comment><comments>http://www.cppblog.com/zgysx/archive/2006/12/28/16946.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zgysx/comments/commentRss/16946.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zgysx/services/trackbacks/16946.html</trackback:ping><description><![CDATA[
		<h2>
				<a id="viewpost1_TitleUrl" href="/mzty/archive/2006/11/24/15618.html">
						<font color="#223355">windows消息大全 </font>
				</a>
		</h2>
		<div class="postbody">
				<p style="MARGIN: 8px; LINE-HEIGHT: 150%">
						<font color="#223355">
						</font>
				</p>
				<table style="FLOAT: right; BORDER-COLLAPSE: collapse" cellspacing="0" cellpadding="0" border="0">
						<tbody>
								<tr>
										<font color="#223355">
										</font>
								</tr>
						</tbody>
				</table>消息，就是指Windows发出的一个通知，告诉应用程序某个事情发生了。例如，单击鼠标、改变窗口尺寸、按下键盘上的一个键都会使Windows发送一个消息给应用程序。消息本身是作为一个记录传递给应用程序的，这个记录中包含了消息的类型以及其他信息。例如，对于单击鼠标所产生的消息来说，这个记录中包含了单击鼠标时的坐标。这个记录类型叫做TMsg， 
<p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%"></p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">它在Windows单元中是这样声明的： </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">type </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">TMsg = packed record </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">hwnd: HWND; / /窗口句柄 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">message: UINT; / /消息常量标识符 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">wParam: WPARAM ; // 32位消息的特定附加信息 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">lParam: LPARAM ; // 32位消息的特定附加信息 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">time: DWORD; / /消息创建时的时间 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">pt: TPoint; / /消息创建时的鼠标位置 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">end; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%"></p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">消息中有什么？ </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">是否觉得一个消息记录中的信息像希腊语一样？如果是这样，那么看一看下面的解释： </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">hwnd 32位的窗口句柄。窗口可以是任何类型的屏幕对象，因为Win32能够维护大多数可视对象的句柄(窗口、对话框、按钮、编辑框等)。 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">message 用于区别其他消息的常量值，这些常量可以是Windows单元中预定义的常量，也可以是自定义的常量。 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">wParam 通常是一个与消息有关的常量值，也可能是窗口或控件的句柄。 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">lParam 通常是一个指向内存中数据的指针。由于W P a r a m、l P a r a m和P o i n t e r都是3 2位的， </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">因此，它们之间可以相互转换。 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%"></p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_NULL = $0000; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_CREATE = $0001; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">应用程序创建一个窗口 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_DESTROY = $0002; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">一个窗口被销毁 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MOVE = $0003; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">移动一个窗口 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_SIZE = $0005; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">改变一个窗口的大小 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_ACTIVATE = $0006; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">一个窗口被激活或失去激活状态； </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_SETFOCUS = $0007; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">获得焦点后 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_KILLFOCUS = $0008; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">失去焦点 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_ENABLE = $000A; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">改变enable状态 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_SETREDRAW = $000B; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">设置窗口是否能重画 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_SETTEXT = $000C; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">应用程序发送此消息来设置一个窗口的文本 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_GETTEXT = $000D; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">应用程序发送此消息来复制对应窗口的文本到缓冲区 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_GETTEXTLENGTH = $000E; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">得到与一个窗口有关的文本的长度（不包含空字符） </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_PAINT = $000F; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">要求一个窗口重画自己 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_CLOSE = $0010; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当一个窗口或应用程序要关闭时发送一个信号 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_QUERYENDSESSION = $0011; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当用户选择结束对话框或程序自己调用ExitWindows函数 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_QUIT = $0012; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">用来结束程序运行或当程序调用postquitmessage函数 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_QUERYOPEN = $0013; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当用户窗口恢复以前的大小位置时，把此消息发送给某个图标 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_ERASEBKGND = $0014; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当窗口背景必须被擦除时（例在窗口改变大小时） </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_SYSCOLORCHANGE = $0015; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当系统颜色改变时，发送此消息给所有顶级窗口 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_ENDSESSION = $0016; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当系统进程发出WM_QUERYENDSESSION消息后，此消息发送给应用程序， </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">通知它对话是否结束 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_SYSTEMERROR = $0017; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_SHOWWINDOW = $0018; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当隐藏或显示窗口是发送此消息给这个窗口 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_ACTIVATEAPP = $001C; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">发此消息给应用程序哪个窗口是激活的，哪个是非激活的； </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_FONTCHANGE = $001D; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当系统的字体资源库变化时发送此消息给所有顶级窗口 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_TIMECHANGE = $001E; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当系统的时间变化时发送此消息给所有顶级窗口 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_CANCELMODE = $001F; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">发送此消息来取消某种正在进行的摸态（操作） </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_SETCURSOR = $0020; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">如果鼠标引起光标在某个窗口中移动且鼠标输入没有被捕获时，就发消息给某个窗口 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MOUSEACTIVATE = $0021; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当光标在某个非激活的窗口中而用户正按着鼠标的某个键发送此消息给当前窗口 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_CHILDACTIVATE = $0022; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">发送此消息给MDI子窗口当用户点击此窗口的标题栏，或当窗口被激活，移动，改变大小 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_QUEUESYNC = $0023; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">此消息由基于计算机的训练程序发送，通过WH_JOURNALPALYBACK的hook程序 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">分离出用户输入消息 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_GETMINMAXINFO = $0024; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">此消息发送给窗口当它将要改变大小或位置； </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_PAINTICON = $0026; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">发送给最小化窗口当它图标将要被重画 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_ICONERASEBKGND = $0027; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">此消息发送给某个最小化窗口，仅当它在画图标前它的背景必须被重画 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_NEXTDLGCTL = $0028; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">发送此消息给一个对话框程序去更改焦点位置 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_SPOOLERSTATUS = $002A; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">每当打印管理列队增加或减少一条作业时发出此消息 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_DRAWITEM = $002B; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当button，combobox，listbox，menu的可视外观改变时发送 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">此消息给这些空件的所有者 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MEASUREITEM = $002C; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当button, combo box, list box, list view control, or menu item 被创建时 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">发送此消息给控件的所有者 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_DELETEITEM = $002D; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当the list box 或 combo box 被销毁 或 当 某些项被删除通过LB_DELETESTRING, LB_RESETCONTENT, CB_DELETESTRING, or CB_RESETCONTENT 消息 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_VKEYTOITEM = $002E; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">此消息有一个LBS_WANTKEYBOARDINPUT风格的发出给它的所有者来响应WM_KEYDOWN消息 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_CHARTOITEM = $002F; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">此消息由一个LBS_WANTKEYBOARDINPUT风格的列表框发送给他的所有者来响应WM_CHAR消息 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_SETFONT = $0030; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当绘制文本时程序发送此消息得到控件要用的颜色 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_GETFONT = $0031; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">应用程序发送此消息得到当前控件绘制文本的字体 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_SETHOTKEY = $0032; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">应用程序发送此消息让一个窗口与一个热键相关连 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_GETHOTKEY = $0033; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">应用程序发送此消息来判断热键与某个窗口是否有关联 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_QUERYDRAGICON = $0037; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">此消息发送给最小化窗口，当此窗口将要被拖放而它的类中没有定义图标，应用程序能返回一个图标或光标的句柄，当用户拖放图标时系统显示这个图标或光标 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_COMPAREITEM = $0039; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">发送此消息来判定combobox或listbox新增加的项的相对位置 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_GETOBJECT = $003D; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_COMPACTING = $0041; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">显示内存已经很少了 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_WINDOWPOSCHANGING = $0046; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">发送此消息给那个窗口的大小和位置将要被改变时，来调用setwindowpos函数或其它窗口管理函数 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_WINDOWPOSCHANGED = $0047; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">发送此消息给那个窗口的大小和位置已经被改变时，来调用setwindowpos函数或其它窗口管理函数 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_POWER = $0048;（适用于16位的windows） </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当系统将要进入暂停状态时发送此消息 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_COPYDATA = $004A; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当一个应用程序传递数据给另一个应用程序时发送此消息 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_CANCELJOURNAL = $004B; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当某个用户取消程序日志激活状态，提交此消息给程序 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_NOTIFY = $004E; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当某个控件的某个事件已经发生或这个控件需要得到一些信息时，发送此消息给它的父窗口 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_INPUTLANGCHANGEREQUEST = $0050; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当用户选择某种输入语言，或输入语言的热键改变 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_INPUTLANGCHANGE = $0051; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当平台现场已经被改变后发送此消息给受影响的最顶级窗口 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_TCARD = $0052; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当程序已经初始化windows帮助例程时发送此消息给应用程序 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_HELP = $0053; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">此消息显示用户按下了F1，如果某个菜单是激活的，就发送此消息个此窗口关联的菜单，否则就 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">发送给有焦点的窗口，如果当前都没有焦点，就把此消息发送给当前激活的窗口 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_USERCHANGED = $0054; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当用户已经登入或退出后发送此消息给所有的窗口，当用户登入或退出时系统更新用户的具体 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">设置信息，在用户更新设置时系统马上发送此消息； </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_NOTIFYFORMAT = $0055; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">公用控件，自定义控件和他们的父窗口通过此消息来判断控件是使用ANSI还是UNICODE结构 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">在WM_NOTIFY消息，使用此控件能使某个控件与它的父控件之间进行相互通信 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_CONTEXTMENU = $007B; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当用户某个窗口中点击了一下右键就发送此消息给这个窗口 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_STYLECHANGING = $007C; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当调用SETWINDOWLONG函数将要改变一个或多个 窗口的风格时发送此消息给那个窗口 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_STYLECHANGED = $007D; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当调用SETWINDOWLONG函数一个或多个 窗口的风格后发送此消息给那个窗口 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_DISPLAYCHANGE = $007E; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当显示器的分辨率改变后发送此消息给所有的窗口 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_GETICON = $007F; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">此消息发送给某个窗口来返回与某个窗口有关连的大图标或小图标的句柄； </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_SETICON = $0080; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">程序发送此消息让一个新的大图标或小图标与某个窗口关联； </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_NCCREATE = $0081; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当某个窗口第一次被创建时，此消息在WM_CREATE消息发送前发送； </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_NCDESTROY = $0082; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">此消息通知某个窗口，非客户区正在销毁 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_NCCALCSIZE = $0083; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当某个窗口的客户区域必须被核算时发送此消息 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_NCHITTEST = $0084;//移动鼠标，按住或释放鼠标时发生 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_NCPAINT = $0085; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">程序发送此消息给某个窗口当它（窗口）的框架必须被绘制时； </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_NCACTIVATE = $0086; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">此消息发送给某个窗口 仅当它的非客户区需要被改变来显示是激活还是非激活状态； </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_GETDLGCODE = $0087; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">发送此消息给某个与对话框程序关联的控件，widdows控制方位键和TAB键使输入进入此控件 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">通过响应WM_GETDLGCODE消息，应用程序可以把他当成一个特殊的输入控件并能处理它 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_NCMOUSEMOVE = $00A0; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当光标在一个窗口的非客户区内移动时发送此消息给这个窗口 //非客户区为：窗体的标题栏及窗 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">的边框体 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_NCLBUTTONDOWN = $00A1; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当光标在一个窗口的非客户区同时按下鼠标左键时提交此消息 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_NCLBUTTONUP = $00A2; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当用户释放鼠标左键同时光标某个窗口在非客户区十发送此消息； </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_NCLBUTTONDBLCLK = $00A3; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当用户双击鼠标左键同时光标某个窗口在非客户区十发送此消息 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_NCRBUTTONDOWN = $00A4; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当用户按下鼠标右键同时光标又在窗口的非客户区时发送此消息 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_NCRBUTTONUP = $00A5; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当用户释放鼠标右键同时光标又在窗口的非客户区时发送此消息 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_NCRBUTTONDBLCLK = $00A6; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当用户双击鼠标右键同时光标某个窗口在非客户区十发送此消息 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_NCMBUTTONDOWN = $00A7; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当用户按下鼠标中键同时光标又在窗口的非客户区时发送此消息 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_NCMBUTTONUP = $00A8; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当用户释放鼠标中键同时光标又在窗口的非客户区时发送此消息 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_NCMBUTTONDBLCLK = $00A9; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当用户双击鼠标中键同时光标又在窗口的非客户区时发送此消息 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_KEYFIRST = $0100; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_KEYDOWN = $0100; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">//按下一个键 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_KEYUP = $0101; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">//释放一个键 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_CHAR = $0102; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">//按下某键，并已发出WM_KEYDOWN， WM_KEYUP消息 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_DEADCHAR = $0103; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当用translatemessage函数翻译WM_KEYUP消息时发送此消息给拥有焦点的窗口 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_SYSKEYDOWN = $0104; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当用户按住ALT键同时按下其它键时提交此消息给拥有焦点的窗口； </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_SYSKEYUP = $0105; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当用户释放一个键同时ALT 键还按着时提交此消息给拥有焦点的窗口 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_SYSCHAR = $0106; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当WM_SYSKEYDOWN消息被TRANSLATEMESSAGE函数翻译后提交此消息给拥有焦点的窗口 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_SYSDEADCHAR = $0107; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当WM_SYSKEYDOWN消息被TRANSLATEMESSAGE函数翻译后发送此消息给拥有焦点的窗口 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_KEYLAST = $0108; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_INITDIALOG = $0110; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">在一个对话框程序被显示前发送此消息给它，通常用此消息初始化控件和执行其它任务 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_COMMAND = $0111; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当用户选择一条菜单命令项或当某个控件发送一条消息给它的父窗口，一个快捷键被翻译 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_SYSCOMMAND = $0112; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当用户选择窗口菜单的一条命令或当用户选择最大化或最小化时那个窗口会收到此消息 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_TIMER = $0113; //发生了定时器事件 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_HSCROLL = $0114; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当一个窗口标准水平滚动条产生一个滚动事件时发送此消息给那个窗口，也发送给拥有它的控件 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_VSCROLL = $0115; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当一个窗口标准垂直滚动条产生一个滚动事件时发送此消息给那个窗口也，发送给拥有它的控件 WM_INITMENU = $0116; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当一个菜单将要被激活时发送此消息，它发生在用户菜单条中的某项或按下某个菜单键，它允许程序在显示前更改菜单 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_INITMENUPOPUP = $0117; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当一个下拉菜单或子菜单将要被激活时发送此消息，它允许程序在它显示前更改菜单，而不要改变全部 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MENUSELECT = $011F; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当用户选择一条菜单项时发送此消息给菜单的所有者（一般是窗口） </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MENUCHAR = $0120; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当菜单已被激活用户按下了某个键（不同于加速键），发送此消息给菜单的所有者； </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_ENTERIDLE = $0121; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当一个模态对话框或菜单进入空载状态时发送此消息给它的所有者，一个模态对话框或菜单进入空载状态就是在处理完一条或几条先前的消息后没有消息它的列队中等待 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MENURBUTTONUP = $0122; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MENUDRAG = $0123; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MENUGETOBJECT = $0124; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_UNINITMENUPOPUP = $0125; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MENUCOMMAND = $0126; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_CHANGEUISTATE = $0127; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_UPDATEUISTATE = $0128; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_QUERYUISTATE = $0129; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_CTLCOLORMSGBOX = $0132; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">在windows绘制消息框前发送此消息给消息框的所有者窗口，通过响应这条消息，所有者窗口可以通过使用给定的相关显示设备的句柄来设置消息框的文本和背景颜色 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_CTLCOLOREDIT = $0133; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当一个编辑型控件将要被绘制时发送此消息给它的父窗口；通过响应这条消息，所有者窗口可以通过使用给定的相关显示设备的句柄来设置编辑框的文本和背景颜色 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_CTLCOLORLISTBOX = $0134; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当一个列表框控件将要被绘制前发送此消息给它的父窗口；通过响应这条消息，所有者窗口可以通过使用给定的相关显示设备的句柄来设置列表框的文本和背景颜色 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_CTLCOLORBTN = $0135; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当一个按钮控件将要被绘制时发送此消息给它的父窗口；通过响应这条消息，所有者窗口可以通过使用给定的相关显示设备的句柄来设置按纽的文本和背景颜色 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_CTLCOLORDLG = $0136; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当一个对话框控件将要被绘制前发送此消息给它的父窗口；通过响应这条消息，所有者窗口可以通过使用给定的相关显示设备的句柄来设置对话框的文本背景颜色 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_CTLCOLORSCROLLBAR= $0137; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当一个滚动条控件将要被绘制时发送此消息给它的父窗口；通过响应这条消息，所有者窗口可以通过使用给定的相关显示设备的句柄来设置滚动条的背景颜色 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_CTLCOLORSTATIC = $0138; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当一个静态控件将要被绘制时发送此消息给它的父窗口；通过响应这条消息，所有者窗口可以通过使用给定的相关显示设备的句柄来设置静态控件的文本和背景颜色 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MOUSEFIRST = $0200; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MOUSEMOVE = $0200; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">// 移动鼠标 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_LBUTTONDOWN = $0201; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">//按下鼠标左键 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_LBUTTONUP = $0202; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">//释放鼠标左键 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_LBUTTONDBLCLK = $0203; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">//双击鼠标左键 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_RBUTTONDOWN = $0204; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">//按下鼠标右键 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_RBUTTONUP = $0205; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">//释放鼠标右键 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_RBUTTONDBLCLK = $0206; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">//双击鼠标右键 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MBUTTONDOWN = $0207; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">//按下鼠标中键 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MBUTTONUP = $0208; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">//释放鼠标中键 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MBUTTONDBLCLK = $0209; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">//双击鼠标中键 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MOUSEWHEEL = $020A; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当鼠标轮子转动时发送此消息个当前有焦点的控件 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MOUSELAST = $020A; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_PARENTNOTIFY = $0210; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当MDI子窗口被创建或被销毁，或用户按了一下鼠标键而光标在子窗口上时发送此消息给它的父窗口 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_ENTERMENULOOP = $0211; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">发送此消息通知应用程序的主窗口that已经进入了菜单循环模式 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_EXITMENULOOP = $0212; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">发送此消息通知应用程序的主窗口that已退出了菜单循环模式 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_NEXTMENU = $0213; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_SIZING = 532; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当用户正在调整窗口大小时发送此消息给窗口；通过此消息应用程序可以监视窗口大小和位置也可以修改他们 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_CAPTURECHANGED = 533; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">发送此消息 给窗口当它失去捕获的鼠标时； </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MOVING = 534; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当用户在移动窗口时发送此消息，通过此消息应用程序可以监视窗口大小和位置也可以修改他们； </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_POWERBROADCAST = 536; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">此消息发送给应用程序来通知它有关电源管理事件； </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_DEVICECHANGE = 537; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当设备的硬件配置改变时发送此消息给应用程序或设备驱动程序 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_IME_STARTCOMPOSITION = $010D; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_IME_ENDCOMPOSITION = $010E; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_IME_COMPOSITION = $010F; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_IME_KEYLAST = $010F; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_IME_SETCONTEXT = $0281; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_IME_NOTIFY = $0282; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_IME_CONTROL = $0283; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_IME_COMPOSITIONFULL = $0284; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_IME_SELECT = $0285; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_IME_CHAR = $0286; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_IME_REQUEST = $0288; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_IME_KEYDOWN = $0290; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_IME_KEYUP = $0291; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MDICREATE = $0220; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">应用程序发送此消息给多文档的客户窗口来创建一个MDI 子窗口 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MDIDESTROY = $0221; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">应用程序发送此消息给多文档的客户窗口来关闭一个MDI 子窗口 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MDIACTIVATE = $0222; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">应用程序发送此消息给多文档的客户窗口通知客户窗口激活另一个MDI子窗口，当客户窗口收到此消息后，它发出WM_MDIACTIVE消息给MDI子窗口（未激活）激活它； </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MDIRESTORE = $0223; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">程序 发送此消息给MDI客户窗口让子窗口从最大最小化恢复到原来大小 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MDINEXT = $0224; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">程序 发送此消息给MDI客户窗口激活下一个或前一个窗口 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MDIMAXIMIZE = $0225; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">程序发送此消息给MDI客户窗口来最大化一个MDI子窗口； </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MDITILE = $0226; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">程序 发送此消息给MDI客户窗口以平铺方式重新排列所有MDI子窗口 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MDICASCADE = $0227; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">程序 发送此消息给MDI客户窗口以层叠方式重新排列所有MDI子窗口 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MDIICONARRANGE = $0228; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">程序 发送此消息给MDI客户窗口重新排列所有最小化的MDI子窗口 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MDIGETACTIVE = $0229; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">程序 发送此消息给MDI客户窗口来找到激活的子窗口的句柄 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MDISETMENU = $0230; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">程序 发送此消息给MDI客户窗口用MDI菜单代替子窗口的菜单 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_ENTERSIZEMOVE = $0231; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_EXITSIZEMOVE = $0232; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_DROPFILES = $0233; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MDIREFRESHMENU = $0234; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MOUSEHOVER = $02A1; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_MOUSELEAVE = $02A3; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_CUT = $0300; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">程序发送此消息给一个编辑框或combobox来删除当前选择的文本 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_COPY = $0301; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">程序发送此消息给一个编辑框或combobox来复制当前选择的文本到剪贴板 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_PASTE = $0302; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">程序发送此消息给editcontrol或combobox从剪贴板中得到数据 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_CLEAR = $0303; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">程序发送此消息给editcontrol或combobox清除当前选择的内容； </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_UNDO = $0304; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">程序发送此消息给editcontrol或combobox撤消最后一次操作 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_RENDERFORMAT = $0305； </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%"></p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_RENDERALLFORMATS = $0306; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_DESTROYCLIPBOARD = $0307; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当调用ENPTYCLIPBOARD函数时 发送此消息给剪贴板的所有者 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_DRAWCLIPBOARD = $0308; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当剪贴板的内容变化时发送此消息给剪贴板观察链的第一个窗口；它允许用剪贴板观察窗口来 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">显示剪贴板的新内容； </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_PAINTCLIPBOARD = $0309; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当剪贴板包含CF_OWNERDIPLAY格式的数据并且剪贴板观察窗口的客户区需要重画； </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_VSCROLLCLIPBOARD = $030A; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_SIZECLIPBOARD = $030B; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当剪贴板包含CF_OWNERDIPLAY格式的数据并且剪贴板观察窗口的客户区域的大小已经改变是此消息通过剪贴板观察窗口发送给剪贴板的所有者； </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_ASKCBFORMATNAME = $030C; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">通过剪贴板观察窗口发送此消息给剪贴板的所有者来请求一个CF_OWNERDISPLAY格式的剪贴板的名字 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_CHANGECBCHAIN = $030D; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当一个窗口从剪贴板观察链中移去时发送此消息给剪贴板观察链的第一个窗口； </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_HSCROLLCLIPBOARD = $030E; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">此消息通过一个剪贴板观察窗口发送给剪贴板的所有者 ；它发生在当剪贴板包含CFOWNERDISPALY格式的数据并且有个事件在剪贴板观察窗的水平滚动条上；所有者应滚动剪贴板图象并更新滚动条的值； </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_QUERYNEWPALETTE = $030F; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">此消息发送给将要收到焦点的窗口，此消息能使窗口在收到焦点时同时有机会实现他的逻辑调色板 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_PALETTEISCHANGING= $0310; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当一个应用程序正要实现它的逻辑调色板时发此消息通知所有的应用程序 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_PALETTECHANGED = $0311; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">此消息在一个拥有焦点的窗口实现它的逻辑调色板后发送此消息给所有顶级并重叠的窗口，以此来改变系统调色板 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_HOTKEY = $0312; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">当用户按下由REGISTERHOTKEY函数注册的热键时提交此消息 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_PRINT = 791; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">应用程序发送此消息仅当WINDOWS或其它应用程序发出一个请求要求绘制一个应用程序的一部分； </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_PRINTCLIENT = 792; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_HANDHELDFIRST = 856; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_HANDHELDLAST = 863; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_PENWINFIRST = $0380; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_PENWINLAST = $038F; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_COALESCE_FIRST = $0390; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_COALESCE_LAST = $039F; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_DDE_FIRST = $03E0; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_DDE_INITIATE = WM_DDE_FIRST + 0; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">一个DDE客户程序提交此消息开始一个与服务器程序的会话来响应那个指定的程序和主题名； </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_DDE_TERMINATE = WM_DDE_FIRST + 1; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">一个DDE应用程序（无论是客户还是服务器）提交此消息来终止一个会话； </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_DDE_ADVISE = WM_DDE_FIRST + 2; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">一个DDE客户程序提交此消息给一个DDE服务程序来请求服务器每当数据项改变时更新它 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_DDE_UNADVISE = WM_DDE_FIRST + 3; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">一个DDE客户程序通过此消息通知一个DDE服务程序不更新指定的项或一个特殊的剪贴板格式的项 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_DDE_ACK = WM_DDE_FIRST + 4; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">此消息通知一个DDE（动态数据交换）程序已收到并正在处理WM_DDE_POKE, WM_DDE_EXECUTE, WM_DDE_DATA, WM_DDE_ADVISE, WM_DDE_UNADVISE, or WM_DDE_INITIAT消息 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_DDE_DATA = WM_DDE_FIRST + 5; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">一个DDE服务程序提交此消息给DDE客户程序来传递个一数据项给客户或通知客户的一条可用数据项 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_DDE_REQUEST = WM_DDE_FIRST + 6; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">一个DDE客户程序提交此消息给一个DDE服务程序来请求一个数据项的值； </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_DDE_POKE = WM_DDE_FIRST + 7; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">一个DDE客户程序提交此消息给一个DDE服务程序，客户使用此消息来请求服务器接收一个未经同意的数据项；服务器通过答复WM_DDE_ACK消息提示是否它接收这个数据项； </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_DDE_EXECUTE = WM_DDE_FIRST + 8; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">一个DDE客户程序提交此消息给一个DDE服务程序来发送一个字符串给服务器让它象串行命令一样被处理，服务器通过提交WM_DDE_ACK消息来作回应； </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_DDE_LAST = WM_DDE_FIRST + 8; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_APP = $8000; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">WM_USER = $0400; </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">此消息能帮助应用程序自定义私有消息； </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">///////////////////////////////////////////////////////////////////// </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">通知消息(Notification message)是指这样一种消息，一个窗口内的子控件发生了一些事情，需要通知父窗口。通知消息只适用于标准的窗口控件如按钮、列表框、组合框、编辑框，以及Windows 95公共控件如树状视图、列表视图等。例如，单击或双击一个控件、在控件中选择部分文本、操作控件的滚动条都会产生通知消息。 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">按扭 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">B N _ C L I C K E D //用户单击了按钮 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">B N _ D I S A B L E //按钮被禁止 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">B N _ D O U B L E C L I C K E D //用户双击了按钮 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">B N _ H I L I T E //用户加亮了按钮 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">B N _ PA I N T按钮应当重画 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">B N _ U N H I L I T E加亮应当去掉 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">组合框 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">C B N _ C L O S E U P组合框的列表框被关闭 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">C B N _ D B L C L K用户双击了一个字符串 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">C B N _ D R O P D O W N组合框的列表框被拉出 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">C B N _ E D I T C H A N G E用户修改了编辑框中的文本 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">C B N _ E D I T U P D AT E编辑框内的文本即将更新 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">C B N _ E R R S PA C E组合框内存不足 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">C B N _ K I L L F O C U S组合框失去输入焦点 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">C B N _ S E L C H A N G E在组合框中选择了一项 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">C B N _ S E L E N D C A N C E L用户的选择应当被取消 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">C B N _ S E L E N D O K用户的选择是合法的 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">C B N _ S E T F O C U S组合框获得输入焦点 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">编辑框 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">E N _ C H A N G E编辑框中的文本己更新 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">E N _ E R R S PA C E编辑框内存不足 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">E N _ H S C R O L L用户点击了水平滚动条 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">E N _ K I L L F O C U S编辑框正在失去输入焦点 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">E N _ M A X T E X T插入的内容被截断 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">E N _ S E T F O C U S编辑框获得输入焦点 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">E N _ U P D AT E编辑框中的文本将要更新 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">E N _ V S C R O L L用户点击了垂直滚动条消息含义 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">列表框 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">L B N _ D B L C L K用户双击了一项 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">L B N _ E R R S PA C E列表框内存不够 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">L B N _ K I L L F O C U S列表框正在失去输入焦点 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">L B N _ S E L C A N C E L选择被取消 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">L B N _ S E L C H A N G E选择了另一项 </p><p style="MARGIN: 5px; TEXT-INDENT: 26px; LINE-HEIGHT: 150%">L B N _ S E T F O C U S列表框获得输入焦点 </p></div>
<img src ="http://www.cppblog.com/zgysx/aggbug/16946.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zgysx/" target="_blank">永遇乐</a> 2006-12-28 16:39 <a href="http://www.cppblog.com/zgysx/archive/2006/12/28/16946.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]windows消息机制</title><link>http://www.cppblog.com/zgysx/archive/2006/12/28/16945.html</link><dc:creator>永遇乐</dc:creator><author>永遇乐</author><pubDate>Thu, 28 Dec 2006 08:36:00 GMT</pubDate><guid>http://www.cppblog.com/zgysx/archive/2006/12/28/16945.html</guid><wfw:comment>http://www.cppblog.com/zgysx/comments/16945.html</wfw:comment><comments>http://www.cppblog.com/zgysx/archive/2006/12/28/16945.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zgysx/comments/commentRss/16945.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zgysx/services/trackbacks/16945.html</trackback:ping><description><![CDATA[
		<h2>
				<a id="viewpost1_TitleUrl" href="/mzty/archive/2006/11/24/15619.html">windows消息机制</a>
		</h2>
		<div class="postbody">
				<p>一 Windows中有一个系统消息队列，对于每一个正在执行的Windows应用程序,系统为其建立一个“消息队列”，即应用程序队列，用来存放该程序可能创建的各种窗口的消息。应用程序中含有一段称作“消息循环”的代码，用来从消息队列中检索这些消息并把它们分发到相应的窗口函数中。</p>
				<p>
						<img height="211" alt="o_windowsmessage2.jpg" src="http://www.cppblog.com/images/cppblog_com/mzty/2021/o_windowsmessage2.jpg" width="450" border="0" />
						<br />
						<br />二 Windows为当前执行的每个Windows程序维护一个「消息队列」。在发生输入事件之后，Windows将事件转换为一个「消息」并将消息放入程序的消息队列中。程序通过执行一块称之为「消息循环」的程序代码从消息队列中取出消息：<br />while(GetMessage (&amp;msg, NULL, 0, 0))        <br />{        <br />    TranslateMessage (&amp;msg) ;        <br />    DispatchMessage (&amp;msg) ;        <br />}</p>
				<p>msg变量是型态为MSG的结构，型态MSG在WINUSER.H中定义如下：<br />typedef struct tagMSG        <br />{        <br />    HWND   hwnd ;        <br />    UINT   message ;        <br />    WPARAM wParam ;        <br />    LPARAM lParam ;        <br />    DWORD  time ;        <br />    POINT  pt ;        <br />}        <br />MSG, * PMSG ;<br />      <br />POINT数据型态也是一个结构，它在WINDEF.H中定义如下：<br />typedef struct tagPOINT        <br />{        <br />    LONG  x ;        <br />    LONG  y ;        <br />}        <br />POINT, * PPOINT;<br />TranslateMessage(&amp;msg); 将msg结构传给Windows，进行一些键盘转换。（关于这一点，我们将在第六章中深入讨论。）<br />DispatchMessage(&amp;msg);又将msg结构回传给Windows。然后，Windows将该消息发送给适当的窗口消息处理程序，让它进行处理。这也就是说，Windows将呼叫窗口消息处理程序。在HELLOWIN中，这个窗口消息处理程序就是WndProc函数。处理完消息之后，WndProc传回到Windows。此时，Windows还停留在DispatchMessage呼叫中。在结束DispatchMessage呼叫的处理之后，Windows回到HELLOWIN程序中，并且接着从下一个GetMessage呼叫开始消息循环。<br />        <br />三 队列化消息与非队列化消息<br />    <br />消息能够被分为「队列化的」和「非队列化的」。队列化的消息是由Windows放入程序消息队列中的。在程序的消息循环中，重新传回并分配给窗口消息处理程序。非队列化的消息在Windows呼叫窗口时直接送给窗口消息处理程序。也就是说，队列化的消息被「发送」给消息队列，而非队列化的消息则「发送」给窗口消息处理程序。任何情况下，窗口消息处理程序都将获得窗口所有的消息--包括队列化的和非队列化的。窗口消息处理程序是窗口的「消息中心」。</p>
				<p>队列化消息基本上是使用者输入的结果，以击键（如WM_KEYDOWN和WM_KEYUP消息）、击键产生的字符（WM_CHAR）、鼠标移动（WM_MOUSEMOVE）和鼠标按钮（WM_LBUTTONDOWN）的形式给出。队列化消息还包含时钟消息（WM_TIMER）、更新消息（WM_PAINT）和退出消息（WM_QUIT）。</p>
				<p>非队列化消息则是其它消息。在许多情况下，非队列化消息来自呼叫特定的Windows函数。例如，当WinMain呼叫CreateWindow时，Windows将建立窗口并在处理中给窗口消息处理程序发送一个WM_CREATE消息。当WinMain呼叫ShowWindow时，Windows将给窗口消息处理程序发送WM_SIZE和WM_SHOWWINDOW消息。当WinMain呼叫UpdateWindow时，Windows将给窗口消息处理程序发送WM_PAINT消息。键盘或鼠标输入时发出的队列化消息信号，也能在非队列化消息中出现。例如，用键盘或鼠标选择了一个菜单项时，键盘或鼠标消息就是队列化的，而说明菜单项已选中的WM_COMMAND消息则可能就是非队列化的。</p>
				<p>四 SendMessage()与PostMessage()之间的区别是什么？<br />它们两者是用于向应用程序发送消息的。PostMessagex()将消息直接加入到应用程序的消息队列中，不等程序返回就退出；而SendMessage()则刚好相反，应用程序处理完此消息后，它才返回。我想下图能够比较好的体现这两个函数的关系：<br /><br /><img height="407" alt="o_postmessage.gif" src="http://www.cppblog.com/images/cppblog_com/mzty/2021/o_postmessage.gif" width="609" border="0" /></p>
				<p>
						<br />五 函数peekmessage和getmessage的区别？</p>
				<p>两个函数主要有以下两个区别:<br />1.GetMessage将等到有合适的消息时才返回,而PeekMessage只是撇一下消息队列。<br />2.GetMessage会将消息从队列中删除,而PeekMessage可以设置最后一个参数wRemoveMsg来决定是否将消息保留在队列中。</p>
		</div>
<img src ="http://www.cppblog.com/zgysx/aggbug/16945.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zgysx/" target="_blank">永遇乐</a> 2006-12-28 16:36 <a href="http://www.cppblog.com/zgysx/archive/2006/12/28/16945.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>禁止程序多开,并将原程序带到前台</title><link>http://www.cppblog.com/zgysx/archive/2006/12/15/16483.html</link><dc:creator>永遇乐</dc:creator><author>永遇乐</author><pubDate>Fri, 15 Dec 2006 08:18:00 GMT</pubDate><guid>http://www.cppblog.com/zgysx/archive/2006/12/15/16483.html</guid><wfw:comment>http://www.cppblog.com/zgysx/comments/16483.html</wfw:comment><comments>http://www.cppblog.com/zgysx/archive/2006/12/15/16483.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zgysx/comments/commentRss/16483.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zgysx/services/trackbacks/16483.html</trackback:ping><description><![CDATA[
		<p>CString strMutexName = "MySingleInstance"; <br />HANDLE hMutex = CreateMutex(NULL,FALSE,strMutexName);  <br /> if (  hMutex )<br /> {<br />  if ( ERROR_ALREADY_EXISTS == ::GetLastError() )<br />  {//如果已有先前的实例,则退出<br />    <br />      HWND hWnd= ::FindWindow([程序窗口类名], [程序窗口名称]);<br />      if( hWnd)<br />      {<br />       ::ShowWindow( hWnd, SW_SHOWNORMAL);<br />       ::SetForegroundWindow( hWnd);<br />       ::BringWindowToTop( hWnd);<br />       ::FlashWindow( hWnd, TRUE );<br />      }<br />      exit(0);<br />   }<br />}</p>
<img src ="http://www.cppblog.com/zgysx/aggbug/16483.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zgysx/" target="_blank">永遇乐</a> 2006-12-15 16:18 <a href="http://www.cppblog.com/zgysx/archive/2006/12/15/16483.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>设置revc()的等待超时时间</title><link>http://www.cppblog.com/zgysx/archive/2006/12/11/16276.html</link><dc:creator>永遇乐</dc:creator><author>永遇乐</author><pubDate>Mon, 11 Dec 2006 08:39:00 GMT</pubDate><guid>http://www.cppblog.com/zgysx/archive/2006/12/11/16276.html</guid><wfw:comment>http://www.cppblog.com/zgysx/comments/16276.html</wfw:comment><comments>http://www.cppblog.com/zgysx/archive/2006/12/11/16276.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zgysx/comments/commentRss/16276.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zgysx/services/trackbacks/16276.html</trackback:ping><description><![CDATA[
		<p> </p>
		<p>#include &lt;stdio.h&gt;<br />#include &lt;winsock2.h&gt;</p>
		<p>
				<br />#define TCP</p>
		<p>#pragma comment(lib,"ws2_32.lib")</p>
		<p>int main( int argc ,char* argv[])<br />{<br /> WSAData wsaData;</p>
		<p> WSAStartup(WINSOCK_VERSION,&amp;wsaData);<br /> DWORD begin,finish;</p>
		<p> struct timeval tv;<br /> tv.tv_sec = 5000;<br /> tv.tv_usec = 0;<br /> int optlen = sizeof(struct timeval);</p>
		<p>
				<br /> //<br /> SOCKET sock = socket(PF_INET,SOCK_STREAM,0);</p>
		<p> struct sockaddr_in to;<br /> int len = sizeof(struct sockaddr_in);<br /> memset(&amp;to,0,len);</p>
		<p> to.sin_addr.s_addr = inet_addr("202.108.9.39");;<br /> to.sin_port = htons(80);<br /> to.sin_family = AF_INET;</p>
		<p> if ( connect(sock,(struct sockaddr*)&amp;to,len) == SOCKET_ERROR )<br /> {<br />  closesocket(sock);<br />  return 0;<br /> }</p>
		<p> <font color="#ff3333">//设置超时值为tv<br /> if ( setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(char*)&amp;tv,optlen) ==<br />  SOCKET_ERROR)<br /></font> {<br />  closesocket(sock);<br />  return 0;<br /> }</p>
		<p> char buf[100];<br /> if ( recv(sock,buf,100,0) == SOCKET_ERROR )<br /> {<br />  printf("d");<br /> }</p>
		<p> return 0;<br />}</p>
<img src ="http://www.cppblog.com/zgysx/aggbug/16276.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zgysx/" target="_blank">永遇乐</a> 2006-12-11 16:39 <a href="http://www.cppblog.com/zgysx/archive/2006/12/11/16276.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>打开文件对话框与目录选择对话框</title><link>http://www.cppblog.com/zgysx/archive/2006/12/06/16053.html</link><dc:creator>永遇乐</dc:creator><author>永遇乐</author><pubDate>Wed, 06 Dec 2006 08:17:00 GMT</pubDate><guid>http://www.cppblog.com/zgysx/archive/2006/12/06/16053.html</guid><wfw:comment>http://www.cppblog.com/zgysx/comments/16053.html</wfw:comment><comments>http://www.cppblog.com/zgysx/archive/2006/12/06/16053.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zgysx/comments/commentRss/16053.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zgysx/services/trackbacks/16053.html</trackback:ping><description><![CDATA[
		<p>
				<font color="#ff0000">打开文件对话框<br /></font>const char pszFilter[] = _T("EXE File (*.txt)|*.txt|All Files (*.*)|*.*||");<br />CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,<br />  pszFilter, this);<br /><br />dlg.m_ofn.lpstrInitialDir = "c:\\WINDOWS\\";  //设置对话框默认呈现的路径<br /><br />if(dlg.DoModal() == IDOK)<br />{<br />CString strFilePath = dlg.GetPathName();<br />/*如果有多个文件,则<br />for(POSITION pos = dlg.GetStartPosition(); pos!=NULL; )<br />  {<br />   CString strFilePathName = dlg.GetNextPathName(pos);<br />*/<br />}</p>
		<p>
				<font color="#ff0000">保存文件对话框<br /></font>const char pszFilter[] = _T("EXE Files (*.txt)|*.txt||");<br />CFileDialog dlgSave( FALSE,   //FALSE为保存<br />  _T(".txt"), //自动加上的扩展名<br />  _T("Output.txt"),  //默认保存的文件名<br />  OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,<br />  pszFilter, this);<br /><br /><br /><br /><font style="BACKGROUND-COLOR: #ffffff" color="#ffff00"><font color="#ff0000">目录选择对话框</font><br /></font><br /> BROWSEINFO bi;<br /> char szPathName[MAX_PATH];<br /> char szTitle[] = "选择路径";<br /> ZeroMemory(&amp;bi, sizeof(BROWSEINFO));<br /> <br /> bi.hwndOwner = GetSafeHwnd();<br /> bi.pszDisplayName = szPathName;<br /> bi.lpszTitle = szTitle;<br /> bi.ulFlags = 0x0040 ; <br /> CString str;<br />CString strDir;  //选择的目录</p>
		<p> LPITEMIDLIST idl = SHBrowseForFolder(&amp;bi);<br /> if(idl == NULL)<br /> {<br />  strDir= "";<br />  return;<br /> }<br /> <br /> SHGetPathFromIDList(idl, str.GetBuffer(MAX_PATH * 2));<br /> str.ReleaseBuffer();<br /> if(str != "" &amp;&amp; str.GetAt(str.GetLength() - 1) != '\\')<br />  str += "\\";<br /> strDir = str;<br /></p>
<img src ="http://www.cppblog.com/zgysx/aggbug/16053.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zgysx/" target="_blank">永遇乐</a> 2006-12-06 16:17 <a href="http://www.cppblog.com/zgysx/archive/2006/12/06/16053.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在对话框上以路径形式显示字符串(当字符串长度过长时,中间的字符串用省略号代替)</title><link>http://www.cppblog.com/zgysx/archive/2006/12/06/16052.html</link><dc:creator>永遇乐</dc:creator><author>永遇乐</author><pubDate>Wed, 06 Dec 2006 08:13:00 GMT</pubDate><guid>http://www.cppblog.com/zgysx/archive/2006/12/06/16052.html</guid><wfw:comment>http://www.cppblog.com/zgysx/comments/16052.html</wfw:comment><comments>http://www.cppblog.com/zgysx/archive/2006/12/06/16052.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/zgysx/comments/commentRss/16052.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zgysx/services/trackbacks/16052.html</trackback:ping><description><![CDATA[
		<p>在对话框上以路径形式显示字符串(当字符串长度过长时,中间的字符串用省略号代替)<br /><br />CPaintDC dc(this);<br />CFont NewFont, * pOldFont;<br />NewFont.CreatePointFont(90, _T("宋体"), NULL);<br />pOldFont = dc.SelectObject(&amp;NewFont);<br />dc.SetBkMode(TRANSPARENT);</p>
		<p>CRect rect;<br />//IDC_STATIC_PATH是显示字符串的static控件的ID, 注意控件的要设为不可见<br />GetDlgItem(IDC_STATIC_PATH)-&gt;GetWindowRect(rect); <br />ScreenToClient(rect);</p>
		<p>dc.DrawText(m_strCorePath, -1, rect, DT_LEFT | DT_PATH_ELLIPSIS | DT_VCENTER | DT_SINGLELINE);<br />dc.SelectObject(pOldFont);</p>
<img src ="http://www.cppblog.com/zgysx/aggbug/16052.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zgysx/" target="_blank">永遇乐</a> 2006-12-06 16:13 <a href="http://www.cppblog.com/zgysx/archive/2006/12/06/16052.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使窗口透明</title><link>http://www.cppblog.com/zgysx/archive/2006/11/07/14808.html</link><dc:creator>永遇乐</dc:creator><author>永遇乐</author><pubDate>Tue, 07 Nov 2006 10:16:00 GMT</pubDate><guid>http://www.cppblog.com/zgysx/archive/2006/11/07/14808.html</guid><wfw:comment>http://www.cppblog.com/zgysx/comments/14808.html</wfw:comment><comments>http://www.cppblog.com/zgysx/archive/2006/11/07/14808.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/zgysx/comments/commentRss/14808.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zgysx/services/trackbacks/14808.html</trackback:ping><description><![CDATA[
		<p>#define LWA_COLORKEY 0x00000001  // Use color as the transparency color.<br />#define WS_EX_LAYERED 0x00080000<br />#define LWA_ALPHA 2   // Use bAlpha to determine the opacity of the layer<br />typedef BOOL (WINAPI *lpfnSetLayeredWindowAttributes)(HWND hWnd, COLORREF crKey, BYTE bAlpha, DWORD dwFlags);<br />lpfnSetLayeredWindowAttributes MySetLayeredWindowAttributes;</p>
		<p>窗口半透明<br />HMODULE hUser32 = GetModuleHandle("user32.dll");<br />MySetLayeredWindowAttributes = (lpfnSetLayeredWindowAttributes)GetProcAddress(hUser32,"SetLayeredWindowAttributes");<br />if(MySetLayeredWindowAttributes == NULL)<br />{<br /> AfxMessageBox("载入系统dll失败,程序即将退出!");<br /> exit(0);<br />}</p>
		<p>::SetWindowLong(GetSafeHwnd(), GWL_EXSTYLE, GetWindowLong(GetSafeHwnd(), GWL_EXSTYLE) ^ WS_EX_LAYERED);<br />MySetLayeredWindowAttributes(GetSafeHwnd(), 0, <br /> 130, //这个参数是控制窗口透明的层度, 为0时窗口全透明,包括标题栏. 为255时,不透明<br /> LWA_ALPHA);//LWA_COLORKEY<br />FreeLibrary(hUser32);</p>
		<p>
				<br />使对话框窗口的客户区全透明<br />COLORREF maskColor= 14215660; 这是颜色掩码,与这个颜色相同的将不被显示出来<br />SetWindowLong(GetSafeHwnd(), GWL_EXSTYLE, GetWindowLong(GetSafeHwnd(), GWL_EXSTYLE) | WS_EX_LAYERED);<br />MySetLayeredWindowAttributes(GetSafeHwnd(), maskColor, 10, LWA_COLORKEY);</p>
		<p>
				<br /> </p>
<img src ="http://www.cppblog.com/zgysx/aggbug/14808.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zgysx/" target="_blank">永遇乐</a> 2006-11-07 18:16 <a href="http://www.cppblog.com/zgysx/archive/2006/11/07/14808.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用std::streambuf_iterator读取文件</title><link>http://www.cppblog.com/zgysx/archive/2006/11/04/14668.html</link><dc:creator>永遇乐</dc:creator><author>永遇乐</author><pubDate>Sat, 04 Nov 2006 08:54:00 GMT</pubDate><guid>http://www.cppblog.com/zgysx/archive/2006/11/04/14668.html</guid><wfw:comment>http://www.cppblog.com/zgysx/comments/14668.html</wfw:comment><comments>http://www.cppblog.com/zgysx/archive/2006/11/04/14668.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zgysx/comments/commentRss/14668.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zgysx/services/trackbacks/14668.html</trackback:ping><description><![CDATA[
		<p>#include &lt;fstream&gt;<br />#include &lt;string&gt;</p>
		<p>using namespace std;</p>
		<p>void main()<br />{<br /> ifstream inputFile("Data.txt");<br /> if(!inputFile.is_open())<br />           return;<br />//这条语句在VC6下编译报错,VC6对模板支持不够<br /> string str((istreambuf_iterator&lt;char&gt;(inputFile)), istreambuf_iterator&lt;char&gt;());<br /> inputFile.close();<br />}</p>
<img src ="http://www.cppblog.com/zgysx/aggbug/14668.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zgysx/" target="_blank">永遇乐</a> 2006-11-04 16:54 <a href="http://www.cppblog.com/zgysx/archive/2006/11/04/14668.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>VC 中使用自定义资源</title><link>http://www.cppblog.com/zgysx/archive/2006/10/31/14419.html</link><dc:creator>永遇乐</dc:creator><author>永遇乐</author><pubDate>Tue, 31 Oct 2006 04:10:00 GMT</pubDate><guid>http://www.cppblog.com/zgysx/archive/2006/10/31/14419.html</guid><wfw:comment>http://www.cppblog.com/zgysx/comments/14419.html</wfw:comment><comments>http://www.cppblog.com/zgysx/archive/2006/10/31/14419.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zgysx/comments/commentRss/14419.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zgysx/services/trackbacks/14419.html</trackback:ping><description><![CDATA[
		<p>举例: 将一个文件做为资源导入到VC工程的*.rc文件中,程序运行时再将资源释放出来写到文件中去.</p>
		<p>bool DeliverResource(const CString&amp; strDestPath, const char * pszID, const char * pszType)<br />{<br /> HRSRC hRsrc = FindResource(NULL, pszID, pszType);<br /> if(NULL == hRsrc)<br />  return false;<br /> DWORD dwSize = SizeofResource(NULL, hRsrc);<br /> if(0 == dwSize)<br />  return false;<br /> HGLOBAL hGlobal = LoadResource(NULL, hRsrc);<br /> if(NULL == hGlobal)<br />  return false;<br /> LPVOID pBuffer = LockResource(hGlobal);<br /> if(NULL == pBuffer)<br />  return false;</p>
		<p> tool::CreateMidDir(strDestPath);<br /> FILE *fp = fopen(strDestPath, "wb");<br /> DWORD dwRemain = dwSize;<br /> while(dwRemain &gt; 0)<br /> {<br />  dwRemain -= fwrite(pBuffer, sizeof(char), dwRemain, fp);<br /> }<br /> fclose(fp);<br /> return true;<br />}</p>
<img src ="http://www.cppblog.com/zgysx/aggbug/14419.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zgysx/" target="_blank">永遇乐</a> 2006-10-31 12:10 <a href="http://www.cppblog.com/zgysx/archive/2006/10/31/14419.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Windows 内存映射文件的使用</title><link>http://www.cppblog.com/zgysx/archive/2006/10/31/14414.html</link><dc:creator>永遇乐</dc:creator><author>永遇乐</author><pubDate>Tue, 31 Oct 2006 03:35:00 GMT</pubDate><guid>http://www.cppblog.com/zgysx/archive/2006/10/31/14414.html</guid><wfw:comment>http://www.cppblog.com/zgysx/comments/14414.html</wfw:comment><comments>http://www.cppblog.com/zgysx/archive/2006/10/31/14414.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zgysx/comments/commentRss/14414.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zgysx/services/trackbacks/14414.html</trackback:ping><description><![CDATA[
		<p>举例:像操作字符串一样地操作一个文件中的内容<br /><br /><br />bool OperateFileJustLikeToString(const char * pszFileName)<br />{<br /> const HANDLE hFile = CreateFile(pszFileName, \<br />  GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, \<br />  NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);<br /> if(hFile == INVALID_HANDLE_VALUE)<br />  return false;</p>
		<p> DWORD dwLength = GetFileSize(hFile, NULL);<br /> //创建内存映射对象,内存映射文件的大小 = 文件长度 + (WCHAR)'\0'<br /> //因为我们要在文件的末尾加上一个字符串的结束符'\0', 当我们将这个文件映射到内存中时,我们就可以像操作字符串一样地来操作文件了<br /> const HANDLE hFileMap = CreateFileMapping(<br />  hFile, NULL, PAGE_READWRITE, 0, <br />  dwLength + sizeof(WCHAR), <br />  NULL);<br /> <br /> char * pFile = (char *)MapViewOfFile(hFileMap, FILE_MAP_WRITE, 0, 0, 0);<br /> pFile[dwLength / sizeof(char)] = '\0';<br /> <br /> //现在对文件的操作就变成了对一字符串pFile的操作了,所有的字符串函数都能<br /> //对pFile这个字符串进行操作, 而操作的结果则会被保存到文件中去(但是并不<br />是改变pFile<br /> //中的内容后会立刻写到文件中去,但是在调用UnmapViewOfFile()后,保证先前对pFile的修改全部保存到文件中了)<br /> //...........<br /> //statement();<br /> //............</p>
		<p> UnmapViewOfFile(pFile);<br /> CloseHandle(hFileMap);</p>
		<p> //我们改变了文件的长度,因此要重新设置文件的结束符以删除留在文件尾部的多余内容(比如删除我们先前加到文件末尾的'\0'字符)<br /> SetFilePointer(hFile,dwLength , NULL, FILE_BEGIN);<br /> SetEndOfFile(hFile);  //设定当前文件指针所在处为文件结束处.该处后面的内容将被删除<br /> CloseHandle(hFile);<br /> return true;<br />}</p>
<img src ="http://www.cppblog.com/zgysx/aggbug/14414.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zgysx/" target="_blank">永遇乐</a> 2006-10-31 11:35 <a href="http://www.cppblog.com/zgysx/archive/2006/10/31/14414.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用键盘钩子(不用DLL)</title><link>http://www.cppblog.com/zgysx/archive/2006/10/30/14376.html</link><dc:creator>永遇乐</dc:creator><author>永遇乐</author><pubDate>Mon, 30 Oct 2006 06:10:00 GMT</pubDate><guid>http://www.cppblog.com/zgysx/archive/2006/10/30/14376.html</guid><wfw:comment>http://www.cppblog.com/zgysx/comments/14376.html</wfw:comment><comments>http://www.cppblog.com/zgysx/archive/2006/10/30/14376.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/zgysx/comments/commentRss/14376.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zgysx/services/trackbacks/14376.html</trackback:ping><description><![CDATA[
		<p>#define WH_KEYBOARD_LL     13<br /><br />定义一个钩子函数<br />LRESULT CALLBACK HookFun(int nCode, WPARAM wParam, LPARAM lParam);</p>
		<p>HHOOK g_hHook = NULL;</p>
		<p>首先要安装钩子<br />g_hHook = SetWindowsHookEx(WH_KEYBOARD_LL, HookFun, GetModuleHandle(NULL), NULL);<br />if(g_hHook == NULL)<br /> AfxMessageBox("hook failure!");</p>
		<p>
				<br />在程序结束时要卸载钩子<br />UnhookWindowsHookEx(g_hHook);</p>
		<p>钩子函数的实现<br />LRESULT CALLBACK HookFun(int nCode, WPARAM wParam, LPARAM lParam)<br />{<br />  CWPSTRUCT* p = (CWPSTRUCT*) lParam;<br /> if (nCode == HC_ACTION) <br /> { <br />  switch (wParam) //wParam中是消息ID<br />  { <br />  case WM_KEYDOWN: <br />   {  <br />      if(p-&gt;lParam == 'l' || p-&gt;lParam == 'L') <br />      {<br />           // 'l' 键被按下 <br />            //do somthing<br />       }<br />    <br />    if(p-&gt;lParam == VK_ESCAPE)<br />    {//用户按下了Esc<br />      //do somthing<br />    }  <br />  } <br /> }<br /> return CallNextHookEx(NULL, nCode, wParam, lParam);<br />}</p>
<img src ="http://www.cppblog.com/zgysx/aggbug/14376.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zgysx/" target="_blank">永遇乐</a> 2006-10-30 14:10 <a href="http://www.cppblog.com/zgysx/archive/2006/10/30/14376.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用C函数获取文件的长度</title><link>http://www.cppblog.com/zgysx/archive/2006/10/20/13891.html</link><dc:creator>永遇乐</dc:creator><author>永遇乐</author><pubDate>Fri, 20 Oct 2006 02:32:00 GMT</pubDate><guid>http://www.cppblog.com/zgysx/archive/2006/10/20/13891.html</guid><wfw:comment>http://www.cppblog.com/zgysx/comments/13891.html</wfw:comment><comments>http://www.cppblog.com/zgysx/archive/2006/10/20/13891.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zgysx/comments/commentRss/13891.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zgysx/services/trackbacks/13891.html</trackback:ping><description><![CDATA[#include &lt;io.h&gt;<br /><br />int GetFileSize(const char * pszFilePath)<br />{<br />   FILE *fp = fopen(pszFilePath,  "rb"); <br />   VERIFY(fp != NULL);<br />    const int nFile = _fileno(fp);<br />    const int nFileLength = _filelength(nFile);<br />   fclose(fp)<br />    return nFileLength;<br />}<img src ="http://www.cppblog.com/zgysx/aggbug/13891.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zgysx/" target="_blank">永遇乐</a> 2006-10-20 10:32 <a href="http://www.cppblog.com/zgysx/archive/2006/10/20/13891.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Windows中用鼠标拖放文件</title><link>http://www.cppblog.com/zgysx/archive/2006/10/19/13851.html</link><dc:creator>永遇乐</dc:creator><author>永遇乐</author><pubDate>Thu, 19 Oct 2006 00:47:00 GMT</pubDate><guid>http://www.cppblog.com/zgysx/archive/2006/10/19/13851.html</guid><wfw:comment>http://www.cppblog.com/zgysx/comments/13851.html</wfw:comment><comments>http://www.cppblog.com/zgysx/archive/2006/10/19/13851.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zgysx/comments/commentRss/13851.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zgysx/services/trackbacks/13851.html</trackback:ping><description><![CDATA[
		<p>添加对WM_DROPFILES响应的函数<br />void CMyDlg::OnDropFiles(HDROP hDropInfo) <br />{<br /> char szFilePath[MAX_PATH];<br /> int nFileCount;<br />//取得拖放的文件个数<br /> nFileCount = DragQueryFile(hDropInfo, 0xFFFFFFFF, NULL, MAX_PATH);<br /><br /> //获取拖放的文件路径<br /> UINT nCharNum = DragQueryFile(hDropInfo, 0, szFilePath, MAX_PATH);<br /> //szFilePath中保存着文件路径或者一个目录<br />//doSomething();<br /> <br /> DragFinish(hDropInfo);<br /> CDialog::OnDropFiles(hDropInfo);<br />}</p>
<img src ="http://www.cppblog.com/zgysx/aggbug/13851.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zgysx/" target="_blank">永遇乐</a> 2006-10-19 08:47 <a href="http://www.cppblog.com/zgysx/archive/2006/10/19/13851.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>程序中显示与隐示的调用 dll</title><link>http://www.cppblog.com/zgysx/archive/2006/10/13/13619.html</link><dc:creator>永遇乐</dc:creator><author>永遇乐</author><pubDate>Fri, 13 Oct 2006 00:39:00 GMT</pubDate><guid>http://www.cppblog.com/zgysx/archive/2006/10/13/13619.html</guid><wfw:comment>http://www.cppblog.com/zgysx/comments/13619.html</wfw:comment><comments>http://www.cppblog.com/zgysx/archive/2006/10/13/13619.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zgysx/comments/commentRss/13619.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zgysx/services/trackbacks/13619.html</trackback:ping><description><![CDATA[
		<p>//===================================<br />//MyAlg.h<br />//===================================<br />/*<br />隐示装载的dll</p>
		<p>从dll中导出一个类,  使用这个dll中类的可执行代码工程必须和这个dll工程用的是同一编译器<br />否则这个dll将不可用<br />*/</p>
		<p>class CMyAlg<br />{<br />public:<br /> __declspec(dllimport) int Add(int a, int b);<br />};<br /><br /><br />//===================================<br />//MyAlg.cpp<br />//===================================<br />#include "MyAlg.h"<br />int CMyAlg::Add(int a, int b)<br />{<br /> return (a + b);<br />}<br /><br /><br /><br /><br /><br />//===================================<br />//alg.h<br />//===================================<br /><br />/*<br />显示装载的dll</p>
		<p>从dll中导出一人函数和一个变量, 这个不会出现像导出类所碰到的问题, 要以C<br />风格的型式导出<br />*/<br />extern "C" __declspec(dllimport) int Add(int a, int b);<br />extern "C" __declspec(dllimport) int g_nValue;<br /><br /><br /><br /><br /><br /><br /><br />//===================================<br />//test.cpp  测试前面写好的dll<br />//===================================<br /><br />#include &lt;stdio.h&gt;</p>
		<p>#define   EXPLICIT_LOAD<br /><br />#ifdef EXPLICIT_LOAD //定义了显示方法加载DLL<br />#include &lt;windows.h&gt;<br />#endif</p>
		<p>#ifdef IMPLICIT_LOAD //定义了隐示方法加载DLL<br />#include "MyAlg.h"<br />#include "alg.h"<br />#pragma comment(lib, "Class.lib") //dll中导出一个类<br />#pragma comment(lib, "Win32Dll.lib")//dll中导出一个函数和变量<br />#endif</p>
		<p>
				<br />void main(void)<br />{<br />#ifdef IMPLICIT_LOAD <br />//使用隐示方法加载DLL,可以调用dll中导出的函数、变量和类<br /> CMyAlg alg;<br /> printf("使用隐示方法加载DLL\n");<br /> printf("CMyAlg::Add(%d, %d) = %d, \n", 1, 2, alg.Add(1, + 2));<br /> printf("Add(%d, %d) = %d, g_nValue = %d\n\n", 1, 2, Add(1, 2), g_nValue);<br />#endif</p>
		<p>
				<br />#ifdef EXPLICIT_LOAD <br />//使用显示的方法加载DLL，只能调用dll中以C风格导出的函数<br /> printf("使用显示的方法加载DLL\n");<br /> HINSTANCE hIns = LoadLibrary("Win32Dll.dll");<br /> if(hIns = NULL)<br /> {<br />  printf("Load dll failure!\n");<br />  return;<br /> }<br /> <br /> typedef int(* pAdd)(int, int);<br /> pAdd pfun = (pAdd)GetProcAddress(hIns, "Add");<br /> printf("pfun(1, 2) = %d, pfun(1,2)\n");</p>
		<p> FreeLibrary(hIns);<br />#endif</p>
		<p> getchar();<br />}</p>
<img src ="http://www.cppblog.com/zgysx/aggbug/13619.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zgysx/" target="_blank">永遇乐</a> 2006-10-13 08:39 <a href="http://www.cppblog.com/zgysx/archive/2006/10/13/13619.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转载]boost库的使用介绍</title><link>http://www.cppblog.com/zgysx/archive/2006/10/05/13365.html</link><dc:creator>永遇乐</dc:creator><author>永遇乐</author><pubDate>Thu, 05 Oct 2006 02:55:00 GMT</pubDate><guid>http://www.cppblog.com/zgysx/archive/2006/10/05/13365.html</guid><wfw:comment>http://www.cppblog.com/zgysx/comments/13365.html</wfw:comment><comments>http://www.cppblog.com/zgysx/archive/2006/10/05/13365.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zgysx/comments/commentRss/13365.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zgysx/services/trackbacks/13365.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 1.boost::any								boost::any是一种通用的数据类型，可以将各种类型包装后统一放入容器内最重要的它是类型安全的。有点象COM里面的variant.		使用方法：any::type() 返回包装的类型any_cast可用于any到其他类型的转化												 																#include 	...&nbsp;&nbsp;<a href='http://www.cppblog.com/zgysx/archive/2006/10/05/13365.html'>阅读全文</a><img src ="http://www.cppblog.com/zgysx/aggbug/13365.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zgysx/" target="_blank">永遇乐</a> 2006-10-05 10:55 <a href="http://www.cppblog.com/zgysx/archive/2006/10/05/13365.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转载]STL的使用时应注意的细节</title><link>http://www.cppblog.com/zgysx/archive/2006/10/05/13364.html</link><dc:creator>永遇乐</dc:creator><author>永遇乐</author><pubDate>Thu, 05 Oct 2006 02:35:00 GMT</pubDate><guid>http://www.cppblog.com/zgysx/archive/2006/10/05/13364.html</guid><wfw:comment>http://www.cppblog.com/zgysx/comments/13364.html</wfw:comment><comments>http://www.cppblog.com/zgysx/archive/2006/10/05/13364.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/zgysx/comments/commentRss/13364.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zgysx/services/trackbacks/13364.html</trackback:ping><description><![CDATA[
		<p>1．循环中删除map元素的写法<br />typedef map&lt;int,int&gt; mymap;<br />typedef map&lt;int,int&gt;::iterator myiter;<br />mymap m;    m[1] = 2;    m[2] = -1;    m[3] = 3;    m[4] = 0;    m[5] = -5;    m[6] = 1;<br />myiter iter = m.begin();<br /> while(iter!=m.end())    <br />{<br />        if(iter-&gt;second&lt;0)   <br />            m.erase(iter++);<br />        else    <br />            ++iter;<br />}<br /></p>
		<p>2．vector&lt;char&gt;来储存二进制流<br /><br /><br />3．vector 的at方法会进行边界检查，[]操作符则不会<br /><br /><br />4.从ifstream读出一行到string，使用std::getline(ifstream的成员函数getline做不到)<br /></p>
		<p>5.警惕string的引用记数技术实现带来的潜在问题<br />string greet("Hello, world");<br />string hi(greet);<br />char *ptr = (char *)hi.c_str();<br />ptr[0] = 'h';<br />两个字符串都被修改。</p>
		<p>在多线程之间引用多个有关系的string，可能导致引用计数失效，造成多次删除，或者memory leak.<br />保险的做法是:<br />string s1("hello") ; string s2 (s1.c_str()); //force copy</p>
		<p>避免iterator失效，不提取无效的iterator<br />比如：<br />vector&lt;int&gt; iv;<br />vector&lt;int&gt;::iterator end = iv .end();<br />for(int i=0;i&lt;10;++i)<br />    iv.insert(end,i);<br />会crash ,因为end指针，随着insert后可能失效<br />改为：<br />vector&lt;int&gt; iv;<br />for(int i=0;i&lt;10;++i)<br />    iv.insert(iv.end(),i);<br />或者：<br />vector&lt;int&gt; iv;<br />for(int i=0;i&lt;10;++i)<br />    iv.push_back(i); //prefer</p>
		<p>
				<br /> </p>
<img src ="http://www.cppblog.com/zgysx/aggbug/13364.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zgysx/" target="_blank">永遇乐</a> 2006-10-05 10:35 <a href="http://www.cppblog.com/zgysx/archive/2006/10/05/13364.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用MFC提供的Http类下载和上传文件</title><link>http://www.cppblog.com/zgysx/archive/2006/09/28/13088.html</link><dc:creator>永遇乐</dc:creator><author>永遇乐</author><pubDate>Thu, 28 Sep 2006 03:34:00 GMT</pubDate><guid>http://www.cppblog.com/zgysx/archive/2006/09/28/13088.html</guid><wfw:comment>http://www.cppblog.com/zgysx/comments/13088.html</wfw:comment><comments>http://www.cppblog.com/zgysx/archive/2006/09/28/13088.html#Feedback</comments><slash:comments>18</slash:comments><wfw:commentRss>http://www.cppblog.com/zgysx/comments/commentRss/13088.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zgysx/services/trackbacks/13088.html</trackback:ping><description><![CDATA[
		<p>1、下载文件<br />Download(const CString&amp; strFileURLInServer, //待下载文件的URL<br />const CString &amp; strFileLocalFullPath)//存放到本地的路径<br />{<br /> ASSERT(strFileURLInServer != "");<br /> ASSERT(strFileLocalFullPath != "");<br /> CInternetSession session;<br /> CHttpConnection* pHttpConnection = NULL;<br /> CHttpFile* pHttpFile = NULL;<br /> CString strServer, strObject;<br /> INTERNET_PORT wPort;</p>
		<p> DWORD dwType;<br /> const int nTimeOut = 2000;<br /> session.SetOption(INTERNET_OPTION_CONNECT_TIMEOUT, nTimeOut); //重试之间的等待延时<br /> session.SetOption(INTERNET_OPTION_CONNECT_RETRIES, 1);   //重试次数<br /> char* pszBuffer = NULL;  </p>
		<p> try<br /> {<br />  AfxParseURL(strFileURLInServer, dwType, strServer, strObject, wPort);<br />  pHttpConnection = session.GetHttpConnection(strServer, wPort);<br />  pHttpFile = pHttpConnection-&gt;OpenRequest(CHttpConnection::HTTP_VERB_GET, strObject);<br />  if(pHttpFile-&gt;SendRequest() == FALSE)<br />   return false;<br />  DWORD dwStateCode;</p>
		<p>  pHttpFile-&gt;QueryInfoStatusCode(dwStateCode);<br />  if(dwStateCode == HTTP_STATUS_OK)<br />  {<br />    HANDLE hFile = CreateFile(strFileLocalFullPath, GENERIC_WRITE,<br />         FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,<br />         NULL);  //创建本地文件<br />   if(hFile == INVALID_HANDLE_VALUE)<br />   {<br />    pHttpFile-&gt;Close();<br />    pHttpConnection-&gt;Close();<br />    session.Close();<br />    return false;<br />   }<br /> <br />   char szInfoBuffer[1000];  //返回消息<br />   DWORD dwFileSize = 0;   //文件长度<br />   DWORD dwInfoBufferSize = sizeof(szInfoBuffer);<br />   BOOL bResult = FALSE;<br />   bResult = pHttpFile-&gt;QueryInfo(HTTP_QUERY_CONTENT_LENGTH,<br />           (void*)szInfoBuffer,&amp;dwInfoBufferSize,NULL);</p>
		<p>   dwFileSize = atoi(szInfoBuffer);<br />   const int BUFFER_LENGTH = 1024 * 10;<br />   pszBuffer = new char[BUFFER_LENGTH];  //读取文件的缓冲<br />   DWORD dwWrite, dwTotalWrite;<br />   dwWrite = dwTotalWrite = 0;<br />   UINT nRead = pHttpFile-&gt;Read(pszBuffer, BUFFER_LENGTH); //读取服务器上数据</p>
		<p>   while(nRead &gt; 0)<br />   {<br />    WriteFile(hFile, pszBuffer, nRead, &amp;dwWrite, NULL);  //写到本地文件<br />    dwTotalWrite += dwWrite;<br />    nRead = pHttpFile-&gt;Read(pszBuffer, BUFFER_LENGTH);<br />   }</p>
		<p>   delete[]pszBuffer;<br />   pszBuffer = NULL;<br />   CloseHandle(hFile);<br />  }<br />  else<br />  {<br />   delete[]pszBuffer;<br />   pszBuffer = NULL;<br />   if(pHttpFile != NULL)<br />   {<br />    pHttpFile-&gt;Close();<br />    delete pHttpFile;<br />    pHttpFile = NULL;<br />   }<br />   if(pHttpConnection != NULL)<br />   {<br />    pHttpConnection-&gt;Close();<br />    delete pHttpConnection;<br />    pHttpConnection = NULL;<br />   }<br />   session.Close();<br />    return false;<br />  }<br /> }<br /> catch(...)<br /> {<br />  delete[]pszBuffer;<br />  pszBuffer = NULL;<br />  if(pHttpFile != NULL)<br />  {<br />   pHttpFile-&gt;Close();<br />   delete pHttpFile;<br />   pHttpFile = NULL;<br />  }<br />  if(pHttpConnection != NULL)<br />  {<br />   pHttpConnection-&gt;Close();<br />   delete pHttpConnection;<br />   pHttpConnection = NULL;<br />  }<br />  session.Close();<br />  return false;<br /> }</p>
		<p> if(pHttpFile != NULL)<br />  pHttpFile-&gt;Close();<br /> if(pHttpConnection != NULL)<br />  pHttpConnection-&gt;Close();<br /> session.Close();<br /> return true;<br />}<br /><br />2、上传文件<br />UploadFile(LPCTSTR strURL, //负责接收上传操作的页面的URL<br />LPCTSTR strLocalFileName)  //待上传的本地文件路径<br />{<br /> ASSERT(strURL != NULL &amp;&amp; strLocalFileName != NULL);</p>
		<p> BOOL bResult = FALSE;<br /> DWORD dwType = 0;<br /> CString strServer;<br /> CString strObject;<br /> INTERNET_PORT wPort = 0;<br /> DWORD dwFileLength = 0;<br /> char * pFileBuff = NULL;</p>
		<p> CHttpConnection * pHC = NULL;<br /> CHttpFile * pHF = NULL;<br /> CInternetSession cis;</p>
		<p> bResult =  AfxParseURL(strURL, dwType, strServer, strObject, wPort);<br /> if(!bResult)<br />  return FALSE;<br /> CFile file;<br /> try<br /> {<br />  if(!file.Open(strLocalFileName, CFile::shareDenyNone | CFile::modeRead))<br />   return FALSE;<br />  dwFileLength = file.GetLength();<br />  if(dwFileLength &lt;= 0)<br />   return FALSE;<br />  pFileBuff = new char[dwFileLength];<br />  memset(pFileBuff, 0, sizeof(char) * dwFileLength);<br />  file.Read(pFileBuff, dwFileLength);</p>
		<p>  const int nTimeOut = 5000;<br />  cis.SetOption(INTERNET_OPTION_CONNECT_TIMEOUT, nTimeOut); //联接超时设置<br />  cis.SetOption(INTERNET_OPTION_CONNECT_RETRIES, 1);  //重试1次<br />  pHC = cis.GetHttpConnection(strServer, wPort);  //取得一个Http联接</p>
		<p>  pHF = pHC-&gt;OpenRequest(CHttpConnection::HTTP_VERB_POST, strObject);<br />  if(!pHF-&gt;SendRequest(NULL, 0, pFileBuff, dwFileLength))<br />  {<br />   delete[]pFileBuff;<br />   pFileBuff = NULL;<br />   pHF-&gt;Close();<br />   pHC-&gt;Close();<br />   cis.Close();<br />   return FALSE;<br />  }<br />  DWORD dwStateCode = 0;<br />  pHF-&gt;QueryInfoStatusCode(dwStateCode);</p>
		<p>  if(dwStateCode == HTTP_STATUS_OK)<br />   bResult = TRUE;<br /> }</p>
		<p> catch(CInternetException * pEx)<br /> {<br />  char sz[256] = "";<br />  pEx-&gt;GetErrorMessage(sz, 25);<br />  CString str;<br />  str.Format("InternetException occur!\r\n%s", sz);<br />  AfxMessageBox(str);<br /> }<br /> catch(CFileException&amp; fe)<br /> {<br />  CString str;<br />  str.Format("FileException occur!\r\n%d", fe.m_lOsError);<br />  AfxMessageBox(str);<br /> }<br /> catch(...)<br /> {<br />  DWORD dwError = GetLastError();<br />  CString str;<br />  str.Format("Unknow Exception occur!\r\n%d", dwError);<br />  AfxMessageBox(str);<br /> }</p>
		<p> delete[]pFileBuff;<br /> pFileBuff = NULL;<br /> file.Close();<br /> pHF-&gt;Close();<br /> pHC-&gt;Close();<br /> cis.Close();<br /> return bResult;<br />}</p>
<img src ="http://www.cppblog.com/zgysx/aggbug/13088.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zgysx/" target="_blank">永遇乐</a> 2006-09-28 11:34 <a href="http://www.cppblog.com/zgysx/archive/2006/09/28/13088.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>