﻿<?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++博客-wrhwww</title><link>http://www.cppblog.com/wrhwww/</link><description /><language>zh-cn</language><lastBuildDate>Sun, 05 Apr 2026 17:10:42 GMT</lastBuildDate><pubDate>Sun, 05 Apr 2026 17:10:42 GMT</pubDate><ttl>60</ttl><item><title>几个非常好的Opencv网站</title><link>http://www.cppblog.com/wrhwww/archive/2018/07/10/215765.html</link><dc:creator>wrh</dc:creator><author>wrh</author><pubDate>Mon, 09 Jul 2018 21:49:00 GMT</pubDate><guid>http://www.cppblog.com/wrhwww/archive/2018/07/10/215765.html</guid><wfw:comment>http://www.cppblog.com/wrhwww/comments/215765.html</wfw:comment><comments>http://www.cppblog.com/wrhwww/archive/2018/07/10/215765.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/wrhwww/comments/commentRss/215765.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/wrhwww/services/trackbacks/215765.html</trackback:ping><description><![CDATA[<h2 style="font-size: 1.1em; font-family: 'Lucida Grande', Verdana, Arial, sans-serif; font-variant: normal; white-space: normal; word-spacing: 0px; text-transform: none; color: rgb(51,51,51); font-style: normal; text-align: left; widows: 1; margin-top: 10px; letter-spacing: normal; line-height: 20px; background-color: rgb(214,211,214); text-indent: 0px; -webkit-text-stroke-width: 0px"><a id="viewpost1_TitleUrl" style="text-decoration: none; color: rgb(0,102,255)" href="http://www.cppblog.com/wrhwww/archive/2013/03/17/198516.html">几个非常好的Opencv网站</a></h2><img src ="http://www.cppblog.com/wrhwww/aggbug/215765.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/wrhwww/" target="_blank">wrh</a> 2018-07-10 05:49 <a href="http://www.cppblog.com/wrhwww/archive/2018/07/10/215765.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>CComboBox 控件,响应ON_CBN_SELCHANGE消息时为何鼠标光标不显示?</title><link>http://www.cppblog.com/wrhwww/archive/2014/09/18/208353.html</link><dc:creator>wrh</dc:creator><author>wrh</author><pubDate>Thu, 18 Sep 2014 11:12:00 GMT</pubDate><guid>http://www.cppblog.com/wrhwww/archive/2014/09/18/208353.html</guid><wfw:comment>http://www.cppblog.com/wrhwww/comments/208353.html</wfw:comment><comments>http://www.cppblog.com/wrhwww/archive/2014/09/18/208353.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/wrhwww/comments/commentRss/208353.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/wrhwww/services/trackbacks/208353.html</trackback:ping><description><![CDATA[解决方法：<br /><br /><span style="color: #333333; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 24px; background-color: #f5f5f5;">ShowDropDown();之后SetCursor(LoadCursor(NULL,&nbsp;IDC_ARROW));即可</span><img src ="http://www.cppblog.com/wrhwww/aggbug/208353.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/wrhwww/" target="_blank">wrh</a> 2014-09-18 19:12 <a href="http://www.cppblog.com/wrhwww/archive/2014/09/18/208353.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>几个非常好的Opencv网站</title><link>http://www.cppblog.com/wrhwww/archive/2013/03/17/198516.html</link><dc:creator>wrh</dc:creator><author>wrh</author><pubDate>Sun, 17 Mar 2013 12:53:00 GMT</pubDate><guid>http://www.cppblog.com/wrhwww/archive/2013/03/17/198516.html</guid><wfw:comment>http://www.cppblog.com/wrhwww/comments/198516.html</wfw:comment><comments>http://www.cppblog.com/wrhwww/archive/2013/03/17/198516.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/wrhwww/comments/commentRss/198516.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/wrhwww/services/trackbacks/198516.html</trackback:ping><description><![CDATA[<a href="http://www.cvchina.info/codes/">http://www.cvchina.info/codes/</a><br /><br /><a href="http://www.tuicool.com/topics/11020052?st=0&amp;lang=1&amp;pn=1">http://www.tuicool.com/topics/11020052?st=0&amp;lang=1&amp;pn=1</a> 
<div id="commentbody-2258">
<p><br /><br /></p>
<h1>OpenCV_基于局部自适应阈值的图像二值化</h1>
<p><br /><a href="http://www.tuicool.com/articles/Mvqeui">http://www.tuicool.com/articles/Mvqeui</a><br /><br /><br />一个很好的快速小波变换（FWT）源码 C++的 <a href="http://www.codeproject.com/KB/graphics/2D_FWT_lib.aspx" rel="nofollow">http://www.codeproject.com/KB/graphics/2D_FWT_lib.aspx</a> </p>
<p>很好用哦</p></div><br /><br /><br /><img src ="http://www.cppblog.com/wrhwww/aggbug/198516.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/wrhwww/" target="_blank">wrh</a> 2013-03-17 20:53 <a href="http://www.cppblog.com/wrhwww/archive/2013/03/17/198516.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MFC 下拉框下拉条目宽、高根据内容自动设置 </title><link>http://www.cppblog.com/wrhwww/archive/2013/02/27/198126.html</link><dc:creator>wrh</dc:creator><author>wrh</author><pubDate>Wed, 27 Feb 2013 14:21:00 GMT</pubDate><guid>http://www.cppblog.com/wrhwww/archive/2013/02/27/198126.html</guid><wfw:comment>http://www.cppblog.com/wrhwww/comments/198126.html</wfw:comment><comments>http://www.cppblog.com/wrhwww/archive/2013/02/27/198126.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/wrhwww/comments/commentRss/198126.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/wrhwww/services/trackbacks/198126.html</trackback:ping><description><![CDATA[<p>有时候下拉框（MFC标准叫组合框，CComboBox）中条目文本很多，超过了下拉框的宽度，如果不加设置的话，超过的部分文本将无法显示，查找MSDN，发现解决方法，代码如下：</p><br />
<p><font color="#000000" face="Verdana">代码 </font></p>
<p><font color="#000000" face="Verdana">// The pointer to my combo box.<br />&nbsp;&nbsp;&nbsp; extern CComboBox* pmyComboBox;</font></p>
<p><font color="#000000" face="Verdana">&nbsp;&nbsp;&nbsp; // Set the height of every item so the item<br />&nbsp;&nbsp;&nbsp; // is completely visible.<br />&nbsp;&nbsp;&nbsp; CString str;<br />&nbsp;&nbsp;&nbsp; CSize&nbsp;&nbsp; sz;<br />&nbsp;&nbsp;&nbsp; int&nbsp;&nbsp;&nbsp;&nbsp; dx=0;<br />&nbsp;&nbsp;&nbsp; CDC*&nbsp;&nbsp;&nbsp; pDC = pmyComboBox-&gt;GetDC();<br />&nbsp;&nbsp;&nbsp; for (int i=0;i &lt; pmyComboBox-&gt;GetCount();i++)<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pmyComboBox-&gt;GetLBText( i, str );<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sz = pDC-&gt;GetTextExtent(str);</font></p>
<p><font color="#000000" face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Only want to set the item height if the current height<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // is not big enough.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (pmyComboBox-&gt;GetItemHeight(i) &lt; sz.cy)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pmyComboBox-&gt;SetItemHeight( i, sz.cy );</font></p>
<p><font color="#000000" face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Only want to set the item width if the current width<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // is not big enough.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (pmyComboBox-&gt;GetDroppedWidth() &lt; sz.cx)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pmyComboBox-&gt;SetDroppedWidth(sz.cx + 20);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; pmyComboBox-&gt;ReleaseDC(pDC);<br /><br /></font></p>
<p>效果图：</p>
<p><img src="http://pic002.cnblogs.com/img/stuarts/201005/2010051016474433.png"  alt="" /></p><br /><br /><img src ="http://www.cppblog.com/wrhwww/aggbug/198126.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/wrhwww/" target="_blank">wrh</a> 2013-02-27 22:21 <a href="http://www.cppblog.com/wrhwww/archive/2013/02/27/198126.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在vs2008中安装opencv2.0</title><link>http://www.cppblog.com/wrhwww/archive/2012/07/15/183545.html</link><dc:creator>wrh</dc:creator><author>wrh</author><pubDate>Sun, 15 Jul 2012 05:59:00 GMT</pubDate><guid>http://www.cppblog.com/wrhwww/archive/2012/07/15/183545.html</guid><wfw:comment>http://www.cppblog.com/wrhwww/comments/183545.html</wfw:comment><comments>http://www.cppblog.com/wrhwww/archive/2012/07/15/183545.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/wrhwww/comments/commentRss/183545.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/wrhwww/services/trackbacks/183545.html</trackback:ping><description><![CDATA[<p><font size="4"><span style="font-weight: bold">一、准备工作</span><br /></font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这里我用到的平台是 Microsoft Visual Studio 2008 和OpenCV2.0<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OpenCV2.0下载地址 http://www.opencv.org.cn/index.php/Download。安装OpenCV2.0，假定安装目录为：D:Program FilesOpenCV2.0<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CMake下载地址 http://www.cmake.org/cmake/resources/software.html (选择 Win32 Installer 安装版本）。<br /><br /><font size="4"><span style="font-weight: bold">二、编译OpenCV</span></font><br /><span style="font-weight: bold">1. 用CMake导出VC++ 项目文件</span><br />&#9632; 运行cmake-gui，设置路径为OpenCV安装路径（例如：D:\Program Files\OpenCV2.0），并创建子目录 D:\Program Files\OpenCV2.0\vc2008，用于存放编译结果。<br />&#9632; 然后点 configure，在弹出的对话框内选择 Visual Studio 9 2008。<br />&#9632; Microsoft Visual Studio 2008 正式版支持OpenMP，所以ENABLE_OPENMP这个选项要勾上；如果是Express版本，则不支持OpenMP，所以需要取消ENABLE_OPENMP选项。<br />&#9632; 最后再点击Generate。<br /><span><img class="blogimg" border="0" src="http://hiphotos.baidu.com/%C4%A6%CE%F7%B1%F9%B5%B6/pic/item/4100633492f14d87d0a2d38e.jpg" small="0"  alt="" /><br /></span><span><img class="blogimg" border="0" src="http://hiphotos.baidu.com/%C4%A6%CE%F7%B1%F9%B5%B6/pic/item/ecb719cae4bef576f21fe788.jpg" small="0"  alt="" /><br /></span><span><img class="blogimg" border="0" src="http://hiphotos.baidu.com/%C4%A6%CE%F7%B1%F9%B5%B6/pic/item/6df50513b422f613dd540189.jpg" small="0"  alt="" /><br /></span><span style="font-weight: bold">2. 编译 OpenCV Debug 和 Release版本库</span><br />完成上一步骤后，将在D:\Program Files\OpenCV2.0\vc2008目录下生成OpenCV.sln的VC Solution File，请用VC++ 2008 Express打开OpenCV.sln，然后执行如下操作：<br />&#9632; 在Debug下，选择Solution Explorer里的 Solution OpenCV，点右键，运行"Rebuild Solution"；如编译无错误，再选择INSTALL项目，运行"Build"。<br />&#9632; 在Release下，选择Solution Explorer里的 Solution OpenCV，点右键，运行"Rebuild Solution"；如编译无错误，再选择INSTALL项目，运行"Build"。 <br />此时，OpenCV的*d.dll文件（for debug）和*.dll文件（for release）将出现在D:\Program Files\OpenCV2.0\vc2008\bin目录中；OpenCV的*d.lib文件（for debug） 和*.lib文件（for release）将出现在D:\Program Files\OpenCV2.0\vc2008\lib目录；头文件*.h出现在D:\Program Files\OpenCV2.0\vc2008\include\opencv中。<br />至此Microsoft Visual Studio 2008 调用的OpenCV动态库生成完毕。</p>
<p><span><img class="blogimg" border="0" src="http://hiphotos.baidu.com/%C4%A6%CE%F7%B1%F9%B5%B6/pic/item/6df50513b428f613dd540197.jpg" small="0"  alt="" /><br /></span><span><img class="blogimg" border="0" src="http://hiphotos.baidu.com/%C4%A6%CE%F7%B1%F9%B5%B6/pic/item/98b43936fabd86010a55a991.jpg" small="0"  alt="" /><br /></span><span><img class="blogimg" border="0" src="http://hiphotos.baidu.com/%C4%A6%CE%F7%B1%F9%B5%B6/pic/item/eff7c12407d82603c8955991.jpg" small="0"  alt="" /><br /></span><span><img class="blogimg" border="0" src="http://hiphotos.baidu.com/%C4%A6%CE%F7%B1%F9%B5%B6/pic/item/74aa3e1fc956d2c5e0fe0b92.jpg" small="0"  alt="" /><br /></span><span><img class="blogimg" border="0" src="http://hiphotos.baidu.com/%C4%A6%CE%F7%B1%F9%B5%B6/pic/item/cf6a77387ad0b0f2d5622593.jpg" small="0"  alt="" /><br /></span><font size="4"><span style="font-weight: bold">三、配置Windows环境变量Path</span><br /></font>将D:\Program Files\OpenCV2.0\vc2008\bin加入Windows系统环境变量Path中。<br />加入后，必须注销当前用户或者重新启动才能生效。<br /><span><img class="blogimg" border="0" src="http://hiphotos.baidu.com/%C4%A6%CE%F7%B1%F9%B5%B6/pic/item/baeb6a0f047804ddab64579d.jpg" small="0"  alt="" /><br /></span><span><img class="blogimg" border="0" src="http://hiphotos.baidu.com/%C4%A6%CE%F7%B1%F9%B5%B6/pic/item/9bcd50514c37f01442a75b9e.jpg" small="0"  alt="" /><br /></span><font size="4"><span style="font-weight: bold">四、为Microsoft Visual Studio 2008 配置OpenCV环境</span><br /></font>打开Microsoft Visual Studio 2008，菜单 Tools -&gt; Options -&gt; Projects and Solutions -&gt; VC++ Directories。<br />&#9632; Show directories for选择include files，加入目录 D:\Program Files\OpenCV2.0\vc2008\include\opencv <br />&#9632; Show directories for选择library files，加入目录 D:\Program Files\OpenCV2.0\vc2008\lib <br /><span><img class="blogimg" border="0" src="http://hiphotos.baidu.com/%C4%A6%CE%F7%B1%F9%B5%B6/pic/item/4b20cd4f2b770806afc3ab9a.jpg" small="0"  alt="" /><br /></span><font size="4"><span style="font-weight: bold">五、使用OpenCV 2.0 编程</span><br /></font>以后每创建一个OpenCV 的Win32 控制台程序，都需要添加依赖的库<br />&#9632; 选择Solution Explorer里的 &#8220;项目名称&#8221;，点击鼠标右键，选择Properties；<br />&#9632; 为项目的Debug配置增加依赖的库：cxcore200d.lib cv200d.lib highgui200d.lib；<br />&#9632; 为项目的Release配置增加依赖的库：cxcore200.lib cv200.lib highgui200.lib</p><img src ="http://www.cppblog.com/wrhwww/aggbug/183545.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/wrhwww/" target="_blank">wrh</a> 2012-07-15 13:59 <a href="http://www.cppblog.com/wrhwww/archive/2012/07/15/183545.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>linux 虚拟机VMWare上网</title><link>http://www.cppblog.com/wrhwww/archive/2012/04/25/172772.html</link><dc:creator>wrh</dc:creator><author>wrh</author><pubDate>Wed, 25 Apr 2012 14:36:00 GMT</pubDate><guid>http://www.cppblog.com/wrhwww/archive/2012/04/25/172772.html</guid><wfw:comment>http://www.cppblog.com/wrhwww/comments/172772.html</wfw:comment><comments>http://www.cppblog.com/wrhwww/archive/2012/04/25/172772.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/wrhwww/comments/commentRss/172772.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/wrhwww/services/trackbacks/172772.html</trackback:ping><description><![CDATA[<p><font face="Times New Roman">1.</font> 把你的虚拟网卡<font face="Times New Roman">VMnet8(</font>在<font face="Times New Roman">Win</font>系统的网上邻居里<font face="Times New Roman">)</font>设置为自动获得<font face="Times New Roman">IP</font>、自动获得<font face="Times New Roman">DNS</font>服务器，启用。</p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr></p>
<p><font face="Times New Roman">2.<br /></font></p>
<p>把你虚拟机中操作系统的<font face="Times New Roman">Editing Auto Ethernet-&gt;IPV4 Setting</font> 设置成如上图所示。</p>
<p>有些<font face="Times New Roman">Linux</font>可以如下设置：&#8220;本地连接&#8221;也设置为自动获得<font face="Times New Roman">IP</font>、自动获得<font face="Times New Roman">DNS</font>服务器（在虚拟机中，右键&#8220;本地连接&#8221;－双击&#8220;<font face="Times New Roman">Internet</font> 协议&#8221;<font face="Times New Roman">,</font>看看是不是自动的吧！固定<font face="Times New Roman">IP</font>的也在这里改！）</p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr></p>
<p><font face="Times New Roman">3.</font>当然是将虚拟机的上网方式选为<font face="Times New Roman">NAT</font>咯。</p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr></p>
<p>右键你要设置的虚拟机选&#8220;设置&#8221;（因为有的不止虚拟一台），在&#8220;硬件&#8221;中选&#8220;以太网&#8221;， 将右边的网络连接改为<font face="Times New Roman">NAT</font>－确定。</p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr></p>
<p><font face="Times New Roman">4.</font>点菜单栏里的&#8220;编辑&#8221;－选&#8220;虚拟网络设置&#8221;，先将&#8220;自动桥接&#8221;给去掉（去掉钩钩），再选&#8220;<font face="Times New Roman">DHCP</font>&#8221;开启<font face="Times New Roman">DHCP</font>服务，点&#8220;开始&#8221;－应用，再按同样的方法开启&#8220;<font face="Times New Roman">NAT</font>&#8221;的功能。</p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr></p>
<p><font face="Times New Roman">5.</font>最重要的是你的两个服务必须开启：<font face="Times New Roman">VMware DHCP Service</font> 和<font face="Times New Roman">VMware NAT Service</font>。</p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr></p>
<p>具体操作如下<font face="Times New Roman">:</font> 开始<font face="Times New Roman">---</font>设置<font face="Times New Roman">--</font>控制面板<font face="Times New Roman">---</font>管理工具<font face="Times New Roman">---</font>服务，确保 <font face="Times New Roman">VMware DHCP Service</font> 和<font face="Times New Roman">VMware NAT Service</font> 服务已经启动</p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr></p>
<p>//====================================另外的方法</p>
<p>&nbsp;<wbr></p>
<p>Ubuntu虚拟机共享主机上网<br />WinXP+VMware WorkStation+Ubuntu7.10<br /><br />一.Bridged方式共享上网<br /><br />1.设置Ubuntu的网络连接方式为Bridged<br /><br />2.共享ADSL连接<br />ADSL连接属性中选中&#8220;Internet连接共享&#8221;，下拉列表中然后选择&#8220;本地连接&#8221;，系统会自动把&#8220;本地连接&#8221;设置为192.168.0.1。注意此设置会在断开连接并重启后才生效<br /><br />3.Ubuntu网络设置<br /><br />IP:192.168.0.X<br />网关:192.268.0.1<br />DNS:192.168.0.1(系统-&gt;系统管理-&gt;网络-&gt;DNS)<br /><br />二.NAT方式共享上网<br /><br />1.设置Ubuntu的网络连接方式为NAT<br />2.开启VMware DHCP Service和VMware NAT Service两个服务<br />3.Ubuntu中网络设置为自动配置(DHCP)或者手动设置IP及DNS<br /><br />手动设置方法：<br /><br />1.XP中ipconfig，得到VMnet8的IP为192.168.93.1<br /><br />2.Ubuntu中设置网络IP为192.168.93.X(X为3-254，网上很多人说只能是128-254，自动分配时一般也是128，但经验证3-254都行，DNS设置为192.168.93.2<br /><br />以上方法均经验证，绝无多余步骤。</p><img src ="http://www.cppblog.com/wrhwww/aggbug/172772.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/wrhwww/" target="_blank">wrh</a> 2012-04-25 22:36 <a href="http://www.cppblog.com/wrhwww/archive/2012/04/25/172772.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>VS2005调试dmp文件常见问题 </title><link>http://www.cppblog.com/wrhwww/archive/2012/01/10/163935.html</link><dc:creator>wrh</dc:creator><author>wrh</author><pubDate>Tue, 10 Jan 2012 05:54:00 GMT</pubDate><guid>http://www.cppblog.com/wrhwww/archive/2012/01/10/163935.html</guid><wfw:comment>http://www.cppblog.com/wrhwww/comments/163935.html</wfw:comment><comments>http://www.cppblog.com/wrhwww/archive/2012/01/10/163935.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/wrhwww/comments/commentRss/163935.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/wrhwww/services/trackbacks/163935.html</trackback:ping><description><![CDATA[<strong>1、 Dump文件放在哪里？<br /><br /></strong>Dump文件不用非要放在你编译出来的位置，你完全可以建立一个新的文件夹来放它。但若不是存放在编译出来的位置，需要将编译生成的PDB文件拷贝到Dump文件目录，或是利用VS2005打开Dump文件后，设置PDB文件路径。<br /><br /><br /><br /><strong>2、 如何恢复当时的现场？</strong><br /><br />可能你要问，怎么可能，这个dump文件可是用户发给我的，我不可能去用户家里调试吧？这个恢复现场可不是指的非要到那台机器上去，而是要把产生dump文件对应的二进制文件拿到。<br /><br />但是恢复现场需要所有的二进制文件都要对应，你一定要有导致用户崩溃的那些Exe和DLL。既然是你发布的程序，Exe文件当然你会有。所以这里只考虑DLL就行了。<br /><br />Dump文件中记录了所有DLL文件的版本号和时间戳，所以你一定可以同过某种途径拿到它。如果你能从用户那里拿到最好，如果不方便，用户不可能用的是我们平常不常用的操作系统，所以找个有对应系统的机器一般都会有。但是记住不仅是文件名称要一致，还要核对版本和时间戳，如果不同一样没有办法用。<br /><br />如果客户用了某个特殊的补丁怎么办？<br /><br />其实这个问题也很好解决，只要它不阻碍阅读堆栈，就不用管它，调试Dump和运行程序不一样，缺少一两个DLL没有任何问题。<br /><br /><br /><br /><strong>3、 如果真的需要怎么办？</strong><br /><br />符号文件现在主要是指PDB文件。<br /><br />如果没有符号文件，那么调试的时候可能导致堆栈错误。<br /><br />如果你丢失了这个发布版本中你编译出来的那些exe和DLL的PDB，那么这个损失是严重的，重新编译出来的版本是不能使用的。<br /><br />我自己的DLL都有了，可是缺的是系统的DLL的对应PDB文件怎么办？图1.4中已经介绍了方法。微软在它的符号数据库上为我们提供了所有的PDB文件，还有部分非关键DLL。设置好后程序将自动下载需要的PDB及DLL文件。<br /><br /><br /><br /><strong>4、 拿到需要的文件了，这些文件应该放在哪里？</strong><br /><br />符号数据库中的文件不用动，把其它的exe和DLL、PDB文件放在dump文件目录里就行了。<br /><br /><br /><br /><strong>5、 我用的是VS2005，明明有源代码，为什么显示不了？</strong><br /><br />这个是dump调试的最头痛问题，代码可能已经改过了，即使你从SVN拿到当时的版本，时间戳也是错的，VS2005就是不让你显示代码。其实只要在<br /><br />Tools/Options，Debugging/General中去掉<br /><br />Require source files to exactly match the original version的复选就行了。 <img src ="http://www.cppblog.com/wrhwww/aggbug/163935.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/wrhwww/" target="_blank">wrh</a> 2012-01-10 13:54 <a href="http://www.cppblog.com/wrhwww/archive/2012/01/10/163935.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>利用VS2005进行dump文件调试</title><link>http://www.cppblog.com/wrhwww/archive/2012/01/10/163934.html</link><dc:creator>wrh</dc:creator><author>wrh</author><pubDate>Tue, 10 Jan 2012 05:53:00 GMT</pubDate><guid>http://www.cppblog.com/wrhwww/archive/2012/01/10/163934.html</guid><wfw:comment>http://www.cppblog.com/wrhwww/comments/163934.html</wfw:comment><comments>http://www.cppblog.com/wrhwww/archive/2012/01/10/163934.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/wrhwww/comments/commentRss/163934.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/wrhwww/services/trackbacks/163934.html</trackback:ping><description><![CDATA[<p class="MsoNormal"><span>前言：利用</span><span lang="EN-US">drwtsn32或</span><span lang="EN-US">NTSD进行程序崩溃处理，都可以生成可用于调试的</span><span lang="EN-US">dmp格式文件。使用</span><span lang="EN-US">VS2005打开生成的</span><span lang="EN-US">DMP文件，能很方便的找出</span><span lang="EN-US">BUG所在位置。本文将讨论以下内容：</span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span lang="EN-US">1</span><span>、</span><span lang="EN-US">&nbsp;&nbsp;</span><span>程序编译选项</span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span lang="EN-US">2</span><span>、</span><span lang="EN-US">&nbsp;&nbsp;</span><span>利用</span><span lang="EN-US">VS2005&nbsp;分析</span><span lang="EN-US">dump文件</span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span lang="EN-US">3</span><span>、</span><span lang="EN-US">&nbsp;&nbsp;</span><span>常见问题讨论</span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><strong><span>一、</span></strong><strong><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></strong><strong><span>程序编译选项</span></strong><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span lang="EN-GB">PDB files contains all debug information like type definition and function prototype</span><span lang="EN-GB">.</span><span lang="EN-GB">&nbsp;</span><span lang="EN-GB">When application crashes, we need the PDB files to analyze the root cause, so make sure these PDB files will be created when building it.</span><span lang="EN-GB">&nbsp;You must do the following setting:</span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span lang="EN-GB">C/C++/General/Debug Information Format=Program Database (/Zi).</span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span lang="EN-GB"><a href="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/VS2005dump_10A8C/clip_image001_2.jpg"><img title="clip_image001" border="0" alt="clip_image001" src="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/VS2005dump_10A8C/clip_image001_thumb.jpg" width="753" height="591" /></a></span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span>图</span><span lang="EN-US">1.1&nbsp;调试信息格式</span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span lang="EN-GB">Linker/Debugging/Generate Program Database File=&#8221;Name and location of your PDB files&#8221;</span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span lang="EN-GB"><a href="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/VS2005dump_10A8C/clip_image002_2.jpg"><img title="clip_image002" border="0" alt="clip_image002" src="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/VS2005dump_10A8C/clip_image002_thumb.jpg" width="753" height="591" /></a></span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span>图</span><span lang="EN-US">1.2 PDB文件输出路径</span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span lang="EN-US">PDB<span>文件路径最好设置在同一个文件夹中，这样方便</span><span lang="EN-US">dmp文件调试时调用。</span><span lang="EN-US"></span></span></p>
<p class="msolistparagraph1"><span>调试时，所有的</span><span lang="EN-US">PDB文件和源文件必须严格匹配（</span><span lang="EN-GB">the PDB files&nbsp;<strong><span>should be</span></strong>&nbsp;the one generated by build the source code<span>），并存储在一个安全的位置。当客户报告了一个错误时，你需要这些文件来帮忙以便定位错误于源代码中并解决问题。</span></span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><strong><span>二、</span></strong><strong><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></strong><strong><span lang="EN-US">VS2005&nbsp;</span></strong><strong><span>分析</span><span lang="EN-US">dump</span><span>文件</span></strong><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span lang="EN-GB">In this simple application, there is an unhandled Access Violation Reading exception, because GetNameFromDatabase returns a NULL pointer, and this pointer is passed into IsPrefix and then it&#8217;s used directly without NULL pointer checking.</span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span lang="EN-GB"><a href="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/VS2005dump_10A8C/clip_image003_2.jpg"><img title="clip_image003" border="0" alt="clip_image003" src="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/VS2005dump_10A8C/clip_image003_thumb.jpg" width="377" height="667" /></a></span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span>图</span><span lang="EN-GB">1.3&nbsp;演示代码</span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span lang="EN-GB">&nbsp;</span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span>利用</span><span lang="EN-GB">Release模式编译该测试程序，在客户机上运行该程序，将根据</span><span lang="EN-GB">NTSD设置生成相对应的</span><span lang="EN-GB">DMP格式文件。</span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span>可以使用</span><span lang="EN-GB">Visual Studio.Net、</span><span lang="EN-GB">NTSD或是其他的调试工具对</span><span lang="EN-GB">DMP格式文件进行分析。</span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span lang="EN-GB">&nbsp;</span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span lang="EN-GB">l</span><span lang="EN-GB">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Start Visual Studio.Net</span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span lang="EN-GB">Click File/Open Solution and make sure the files of type is *.dmp then click Open.</span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span lang="EN-GB"><a href="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/VS2005dump_10A8C/clip_image004_2.jpg"><img title="clip_image004" border="0" alt="clip_image004" src="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/VS2005dump_10A8C/clip_image004_thumb.jpg" width="703" height="370" /></a></span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span>图</span><span lang="EN-GB">1.3&nbsp;</span><span lang="EN-GB">Open Dump File (GUI)</span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span lang="EN-GB">&nbsp;</span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span lang="EN-GB">l</span><span lang="EN-GB">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Set Symbol Path</span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span lang="EN-GB">Click Tools/Options, Debugging/Symbols<span>，增加</span><span lang="EN-GB">PDB文件路径。若调试的程序需要微软基础库的</span><span lang="EN-GB">PDB信息，可以增加一个路径为：</span></span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span lang="EN-GB"><a href="http://msdl.microsoft.com/download/symbols">http://msdl.microsoft.com/download/symbols</a></span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span>在界面下方</span><span lang="EN-GB">Cache Symbol From symbol&#8230;选择本地存储这些</span><span lang="EN-GB">Symbols的路径。</span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span lang="EN-GB"><a href="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/VS2005dump_10A8C/clip_image005_2.jpg"><img title="clip_image005" border="0" alt="clip_image005" src="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/VS2005dump_10A8C/clip_image005_thumb.jpg" width="648" height="360" /></a></span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span>图</span><span lang="EN-GB">1.4 Symbol Path</span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span>如果</span><span lang="EN-GB">DMP文件没有放入本身</span><span lang="EN-GB">PDB文件所在目录，也可以在此处增加一个本地目录。点</span><span lang="EN-GB">OK后，</span><span lang="EN-GB">VS2005将从网络中下载所需要的</span><span lang="EN-GB">Symbols，需要等待一段时间。如果是多次调试同一个程序错误所生成的</span><span lang="EN-GB">DMP文件，可以在对话框中选择&#8220;</span><span lang="EN-GB">Search the above locations only when symbols are loaded manually&#8221;。从而可以节省网络带宽。</span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span lang="EN-GB">&nbsp;</span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span lang="EN-GB">l</span><span lang="EN-GB">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Set Source code path</span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span lang="EN-US">Open Solution Property Pages and set the source code path.</span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span lang="EN-GB"><a href="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/VS2005dump_10A8C/clip_image006_2.jpg"><img title="clip_image006" border="0" alt="clip_image006" src="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/VS2005dump_10A8C/clip_image006_thumb.jpg" width="260" height="134" /></a></span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span>图</span><span lang="EN-US">1.5&nbsp;属性菜单</span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span lang="EN-US"><a href="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/VS2005dump_10A8C/clip_image007_2.jpg"><img title="clip_image007" border="0" alt="clip_image007" src="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/VS2005dump_10A8C/clip_image007_thumb.jpg" width="698" height="456" /></a></span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span>图</span><span lang="EN-US">1.6 Debug Source Files</span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span lang="EN-US">&nbsp;</span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span lang="EN-GB">l</span><span lang="EN-GB">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Start to Debug the Dump File</span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span lang="EN-US">Click the Debug menu, it will ask you to save as a solution, save it. Then it will go to the line which caused the crash of your application.</span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span lang="EN-GB"><a href="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/VS2005dump_10A8C/clip_image008_2.jpg"><img title="clip_image008" border="0" alt="clip_image008" src="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/VS2005dump_10A8C/clip_image008_thumb.jpg" width="1284" height="772" /></a></span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span>图</span><span lang="EN-US">1.7&nbsp;调试窗口，定位到源代码</span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span lang="EN-US">&nbsp;</span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><strong><span>三、</span></strong><strong><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></strong><strong><span>常见问题讨论</span></strong><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span lang="EN-US">1</span><span>、</span><span lang="EN-US">&nbsp; Dump<span>文件放在哪里？</span></span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span lang="EN-US">Dump<span>文件不用非要放在你编译出来的位置，你完全可以建立一个新的文件夹来放它。但若不是存放在编译出来的位置，需要将编译生成的</span><span lang="EN-US">PDB文件拷贝到</span><span lang="EN-US">Dump文件目录，或是利用</span><span lang="EN-US">VS2005打开</span><span lang="EN-US">Dump文件后，设置</span><span lang="EN-US">PDB文件路径。参照图</span><span lang="EN-US">1.4。</span></span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span lang="EN-US">&nbsp;</span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span lang="EN-US">2</span><span>、</span><span lang="EN-US">&nbsp;&nbsp;</span><span>如何恢复当时的现场？</span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span>可能你要问，怎么可能，这个<span lang="EN-US">dump</span>文件可是用户发给我的，我不可能去用户家里调试吧？这个恢复现场可不是指的非要到那台机器上去，而是要把产生<span lang="EN-US">dump</span>文件对应的二进制文件拿到。<span lang="EN-US"></span></span></p>
<p class="msolistparagraph1"><span>但是恢复现场需要所有的二进制文件都要对应，你一定要有导致用户崩溃的那些<span lang="EN-US">Exe</span>和<span lang="EN-US">DLL</span>。既然是你发布的程序，<span lang="EN-US">Exe</span>文件当然你会有。所以这里只考虑<span lang="EN-US">DLL</span>就行了。<span lang="EN-US"></span></span></p>
<p class="msolistparagraph1"><span lang="EN-US">Dump</span><span>文件中记录了所有<span lang="EN-US">DLL</span>文件的版本号和时间戳，所以你一定可以同过某种途径拿到它。如果你能从用户那里拿到最好，如果不方便，用户不可能用的是我们平常不常用的操作系统，所以找个有对应系统的机器一般都会有。但是记住不仅是文件名称要一致，还要核对版本和时间戳，如果不同一样没有办法用。<span lang="EN-US"></span></span></p>
<p class="msolistparagraph1"><span>如果客户用了某个特殊的补丁怎么办？<span lang="EN-US"></span></span></p>
<p class="msolistparagraph1"><span>其实这个问题也很好解决，只要它不阻碍阅读堆栈，就不用管它，调试<span lang="EN-US">Dump</span>和运行程序不一样，缺少一两个<span lang="EN-US">DLL</span>没有任何问题。<span lang="EN-US"></span></span></p>
<p class="msolistparagraph1"><span lang="EN-US">&nbsp;</span></p>
<p class="msolistparagraph1"><span lang="EN-US">3</span><span>、</span><span lang="EN-US">&nbsp;&nbsp;</span><span>如果真的需要怎么办？</span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span>符号文件现在主要是指<span lang="EN-US">PDB</span>文件。<span lang="EN-US"></span></span></p>
<p class="msolistparagraph1"><span>如果没有符号文件，那么调试的时候可能导致堆栈错误。<span lang="EN-US"></span></span></p>
<p class="msolistparagraph1"><span>如果你丢失了这个发布版本中你编译出来的那些</span><span lang="EN-US">exe和</span><span lang="EN-US">DLL的</span><span lang="EN-US">PDB，那么这个损失是严重的，重新编译出来的版本是不能使用的。</span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span>我自己的</span><span lang="EN-US">DLL都有了，可是缺的是系统的</span><span lang="EN-US">DLL的对应</span><span lang="EN-US">PDB文件怎么办？图</span><span lang="EN-US">1.4中已经介绍了方法。微软在它的符号数据库上为我们提供了所有的</span><span lang="EN-US">PDB文件，还有部分非关键</span><span lang="EN-US">DLL。设置好后程序将自动下载需要的</span><span lang="EN-US">PDB及</span><span lang="EN-US">DLL文件。</span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span lang="EN-US">&nbsp;</span></p>
<p class="msolistparagraph1"><span lang="EN-US">4</span><span>、</span><span lang="EN-US">&nbsp;&nbsp;</span><span>拿到需要的文件了，这些文件应该放在哪里？</span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span>符号数据库中的文件不用动，把其它的</span><span lang="EN-US">exe和</span><span lang="EN-US">DLL、</span><span lang="EN-US">PDB文件放在</span><span lang="EN-US">dump文件目录里就行了。</span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span lang="EN-US">&nbsp;</span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span lang="EN-US">5</span><span>、</span><span lang="EN-US">&nbsp;&nbsp;</span><span>我用的是</span><span lang="EN-US">VS2005，明明有源代码，为什么显示不了？</span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span>这个是</span><span lang="EN-US">dump调试的最头痛问题，代码可能已经改过了，即使你从</span><span lang="EN-US">SVN拿到当时的版本，时间戳也是错的，</span><span lang="EN-US">VS2005就是不让你显示代码。其实只要在</span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span lang="EN-US">Tools/Options<span>，</span><span lang="EN-US">Debugging/General中去掉</span></span><span lang="EN-US"></span></p>
<p class="msolistparagraph1"><span lang="EN-US">Require source files to exactly match the original version<span>的复选就行了。</span></span></p><img src ="http://www.cppblog.com/wrhwww/aggbug/163934.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/wrhwww/" target="_blank">wrh</a> 2012-01-10 13:53 <a href="http://www.cppblog.com/wrhwww/archive/2012/01/10/163934.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>VC++中CMAP的使用</title><link>http://www.cppblog.com/wrhwww/archive/2011/10/21/158802.html</link><dc:creator>wrh</dc:creator><author>wrh</author><pubDate>Fri, 21 Oct 2011 01:38:00 GMT</pubDate><guid>http://www.cppblog.com/wrhwww/archive/2011/10/21/158802.html</guid><wfw:comment>http://www.cppblog.com/wrhwww/comments/158802.html</wfw:comment><comments>http://www.cppblog.com/wrhwww/archive/2011/10/21/158802.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/wrhwww/comments/commentRss/158802.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/wrhwww/services/trackbacks/158802.html</trackback:ping><description><![CDATA[映射表类（CMap）是MFC集合类中的一个模板类，也称作为&#8220;字典&#8221;，就像一种只有两列的表格，一列是关键字，一列是数据项，它们是一一对应的。关键字是唯一的，给出一个关键字，映射表类会很快找到对应的数据项。映射表的查找是以哈希表的方式进行的，因此在映射表中查找数值项的速度很快。映射类最适用于需要根据关键字进行快速检索的场合，我们的程序中就用映射表来保存计时器标志值和类实例指针，用计时器的标志值作为关键字。 <font face="Arial">他这个有点像数组，比如你要查找a[index]，不必先遍历前面的index个元素，只不过数组的下标是哈希表键值，它是以键值对的形式出现的。</font><font face="Arial">举个例子来说吧，公司的所有职员都有一个工号和自己的姓名，工号就是姓名的关键字，给出一个工号，就可以很快的找到相应的姓名。<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 举例如下：<br />1、定义一个CMAP，向这个CMAP中增加数据项（键-值对）。<br />CMap&lt;CString, LPCTSTR, CString, LPCTSTR&gt;m_ItemMap;<br />CString strKey = _T(""), str = _T("");<br />int i;<br />for(i = 0; i &lt; 5; i++)<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; strKey.Format("%d", i);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font face="Arial">//这个是键</font><font face="Arial"><br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; str.Format("A%d", i);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font face="Arial">//键对应的</font><font face="Arial">值 <br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; m_ItemMap.SetAt(strKey, str);<br />&nbsp;&nbsp;&nbsp; }<br />2、遍历正个CMAP的常用方法。<br />&nbsp;&nbsp;&nbsp; POSITION pos = m_ItemMap.GetStartPosition();<br />&nbsp;&nbsp;&nbsp; while(pos)<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; m_ItemMap.GetNextAssoc(pos, strKey, str);<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; cout&lt;&lt; strKey&lt;&lt; ":"&lt;&lt; str&lt;&lt; endl;<br />&nbsp;&nbsp;&nbsp; }<br />3、在CMAP中查找相应的数据项。<br />&nbsp;&nbsp;&nbsp; CString pReset;<br />&nbsp;&nbsp;&nbsp; if(m_ItemMap.Lookup("1", pReset))<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; cout&lt;&lt;pReset&lt;&lt;endl;<br />&nbsp;&nbsp;&nbsp; }<br /></font><br /><br />=======================================================================现在，我们来学习MFC中，最常用的数据结构中的最后一个CMap模板。之前，我们已经依次学完了CArray，CList，并且也对它们进行了初步的剖析。 
<p style="text-align: left; text-indent: 21pt" align="left"><span style="color: teal">其实，我一直认为CMap是最简单的一个数据类型，如果说，大家对这个数据类型产生不良感觉的话，大多是因为对Hash表的陌生。</span></p>
<p style="text-align: left; text-indent: 21pt" align="left"><span style="color: teal">显然，CMap就是对Hash表的一种实现。对于Hash表来说，我们需要提供成对的Key与Value进行操作，其实，也就是将我们日常使用的数组下标替换成现在Key，至于MFC是采用了什么样的散列函数，我们不必知道。</span></p>
<p style="text-align: left; text-indent: 21pt" align="left"><span style="color: teal">Hash</span><span style="color: teal">表可以认为是数组的一种优化，或者说是对数组缺陷的一种弥补，因为我们知道，数组在具备了高效存取性能的同时，无法动态的调整自身的大小，又严重的影响了它的使用效果。这给了Hash表可乘之机，Hash表总是使用了某种算法尽可能的来达到将成对的元素存储到一个额定的离散的内存空间，它既继承了链表对自身的动态调整，又尽可能的使读写维持在高速的水平，当然无论如何还是要比数组慢的多。</span></p>
<p style="text-align: left; text-indent: 21pt" align="left"><span style="color: teal">如果你非要让我告诉你，Hash表是什么样的一个数据结构的话，很遗憾，我无法准确的描述，这就相当于你问我&#8220;凤凰是什么样子&#8221;，不过我可以告诉你孔雀的样子。常用的Hash表非常像一个十字数组，似乎十字数组又成为了众多读者的障碍，如果你暂时还不能理解的话，请你去翻阅Hash表的详细论述，当然你也可以在不久之后，在本处看到这些经典数据结构的精讲。</span></p>
<p style="text-align: left; text-indent: 21pt" align="left"><span style="color: teal">现在，我们来看一个CMap的用法，至于它的参数，你可以看本空间一篇专门描述CArray，CList以及CMap参数用法的文章《CArray，CList，CMap如何实化（实例化）》。下面是我自己编写的例子：</span></p>
<p style="text-align: left; text-indent: 21pt" align="left"><span style="color: teal">class Point</span></p>
<p style="text-align: left; text-indent: 21pt" align="left"><span style="color: teal">{</span></p>
<p style="text-align: left; text-indent: 21pt" align="left"><span style="color: teal">public:</span></p>
<p style="text-align: left; text-indent: 21pt" align="left"><span style="color: teal">&nbsp;&nbsp;&nbsp; Point()</span></p>
<p style="text-align: left; text-indent: 21pt" align="left"><span style="color: teal">&nbsp;&nbsp;&nbsp; {</span></p>
<p style="text-align: left; text-indent: 21pt" align="left"><span style="color: teal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_x = 0;</span></p>
<p style="text-align: left; text-indent: 21pt" align="left"><span style="color: teal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_y = 0;</span></p>
<p style="text-align: left; text-indent: 21pt" align="left"><span style="color: teal">&nbsp;&nbsp;&nbsp; }</span></p>
<p style="text-align: left; text-indent: 21pt" align="left"><span style="color: teal">&nbsp;&nbsp;&nbsp; Point(int x, int y)</span></p>
<p style="text-align: left; text-indent: 21pt" align="left"><span style="color: teal">&nbsp;&nbsp;&nbsp; {</span></p>
<p style="text-align: left; text-indent: 21pt" align="left"><span style="color: teal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_x = x;</span></p>
<p style="text-align: left; text-indent: 21pt" align="left"><span style="color: teal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_y = y;</span></p>
<p style="text-align: left; text-indent: 21pt" align="left"><span style="color: teal">&nbsp;&nbsp;&nbsp; }</span></p>
<p style="text-align: left; text-indent: 21pt" align="left"><span style="color: teal">public:</span></p>
<p style="text-align: left; text-indent: 21pt" align="left"><span style="color: teal">&nbsp;&nbsp;&nbsp; int m_x;</span></p>
<p style="text-align: left; text-indent: 21pt" align="left"><span style="color: teal">&nbsp;&nbsp;&nbsp; int m_y;</span></p>
<p style="text-align: left; text-indent: 21pt" align="left"><span style="color: teal">};</span></p>
<p style="text-align: left; text-indent: 21pt" align="left"><span style="color: teal">typedef CMap&lt;const char*, const char*, Point, Point&amp;&gt;&nbsp;&nbsp;&nbsp;&nbsp; CMapPnt; //</span><span style="color: teal">请在使用之前定义</span></p>
<p style="text-align: left; text-indent: 21pt" align="left"><span style="color: teal">int main()</span></p>
<p style="text-align: left; text-indent: 21pt" align="left"><span style="color: teal">{</span></p>
<p style="text-align: left; text-indent: 21pt" align="left"><span style="color: teal">&nbsp;&nbsp;&nbsp; Point elem1(1, 100), elem2(2, 200), elem3(3, 300), point;</span></p>
<p style="text-align: left; text-indent: 21pt" align="left"><span style="color: teal">&nbsp;&nbsp;&nbsp; CMapPnt mp;</span></p>
<p style="text-align: left; text-indent: 21pt" align="left"><span style="color: teal">&nbsp;&nbsp;&nbsp; // insert 3 elements into map</span><span style="color: teal">，<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #1</span></span></p>
<p style="text-align: left; text-indent: 21pt" align="left"><span style="color: teal">&nbsp;&nbsp;&nbsp; mp.SetAt("1st", elem1);</span></p>
<p style="text-align: left; text-indent: 21pt" align="left"><span style="color: teal">&nbsp;&nbsp;&nbsp; mp.SetAt("2nd", elem2);</span></p>
<p style="text-align: left; text-indent: 21pt" align="left"><span style="color: teal">&nbsp;&nbsp;&nbsp; mp.SetAt("3th", elem3);</span></p>
<p style="text-align: left; text-indent: 21pt" align="left"><span>&nbsp;&nbsp;&nbsp; </span></p>
<p style="text-align: left; text-indent: 21pt" align="left"><span style="color: teal">&nbsp;&nbsp;&nbsp; // search a point named "2nd" from map&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;#2</span></p>
<p style="text-align: left; text-indent: 21pt" align="left"><span style="color: teal">&nbsp;&nbsp;&nbsp; mp.Lookup("2nd", point);</span></p>
<p style="text-align: left; text-indent: 21pt" align="left"><span style="color: teal">&nbsp;&nbsp;&nbsp; printf("2nd: m_x: %d, m_y: %d\n", point.m_x, point.m_y);</span></p>
<p style="text-align: left; text-indent: 42pt" align="left"><span style="color: teal">// insert a new pair into map&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #3</span></p>
<p style="text-align: left; text-indent: 42pt" align="left"><span style="color: teal">Point elem4(4, 400);</span></p>
<p style="text-align: left; text-indent: 42pt" align="left"><span style="color: teal">mp["4th"] = elem4;</span></p>
<p style="text-align: left; text-indent: 42pt" align="left"><span style="color: teal">cout&lt;&lt;"count: "&lt;&lt;mp.GetCount()&lt;&lt;endl;</span></p>
<p style="text-align: left; text-indent: 42pt" align="left"><span style="color: teal">// traverse the entire map&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #4</span></p>
<p style="text-align: left; text-indent: 42pt" align="left"><span style="color: teal">size_t index = 0;</span></p>
<p style="text-align: left; text-indent: 42pt" align="left"><span style="color: teal">const char* pszKey;</span></p>
<p style="text-align: left; text-indent: 42pt" align="left"><span style="color: teal">POSITION ps = mp.GetStartPosition();</span></p>
<p style="text-align: left; text-indent: 42pt" align="left"><span style="color: teal">while( ps )</span></p>
<p style="text-align: left; text-indent: 42pt" align="left"><span style="color: teal">{&nbsp;&nbsp; </span></p>
<p style="text-align: left; text-indent: 63pt" align="left"><span style="color: teal">mp.GetNextAssoc(ps, pszKey, point);</span></p>
<p style="text-align: left; text-indent: 63pt" align="left"><span style="color: teal">printf("index: %d, m_x: %d, m_y: %d\n", ++index, point.m_x, point.m_y);</span></p>
<p style="text-align: left; text-indent: 42pt" align="left"><span style="color: teal">}</span></p>
<p style="text-align: left; text-indent: 42pt" align="left"><span style="color: teal">return 0;</span></p>
<p style="text-align: left; text-indent: 21pt" align="left"><span style="color: teal">}</span></p>
<p style="text-align: left; text-indent: 21pt" align="left"><span style="color: teal">代码中，我已经给出了一些注释，我同样建议读者们，用英文在代码中注释，这样的好处实在是太多了。尤其在代码需要在不同编码的操作系统上调试的时候。</span></p>
<p style="text-align: left; text-indent: 21pt" align="left"><span style="color: teal">对于CMap这个类，我不得不着重啰嗦一下的是：遍历操作以及取下标【】操作，当然还有那个令很多人困惑不已的ARG_KEY到底应该如何选择的问题。</span></p>
<p style="text-align: left; text-indent: 21pt" align="left"><span style="color: teal">遍历，看注释#4，至于POSITION的含义，请在本空间，查看其它文章。先使用GetStartPosition()函数获得表头的位置，然后，我们可以使用GetNextAssoc函数来遍历。GetNextAssoc(POSITION&amp; rNextPosition, KEY&amp; rKey, VALUE&amp; rValue)函数的参数值得说明一下，大家看到，3个参数都是引用，而第一个是rNextPosition，顾名思义，在函数返回之后，它将会指像下一个元组，当然这是在表还未遍历完的时候，否则，它将被置为空（NULL）。</span></p>
<p style="text-align: left; text-indent: 21pt" align="left"><span style="color: teal">【】，利用下标取元素的这个操作符，在CMap中被重载，用来返回指定Key值数据的引用，不过在注释#3处，对于先取"4th"这个Point的引用然后赋值的用法，看起来，似乎有点聪明过了头，因为在这之前，我们还没有插入"4th"所对应的元组，但是，程序却能正常的运行！为什么？其实，这样的用法是十分正确的，因为CMap毕竟不是数组，它是没有边界的，当CMap在获得一个它无法查询到的Key值的时候，它会将这个Key以及一个空的数据类型追加到Hash表中去，从而保证了上面的程序可以无误的运行。</span></p>
<p style="text-align: left; text-indent: 21pt" align="left"><span style="color: teal">我们已经说过，ARG_KEY是作为类型参数传入CMap的，但并不是任何类型都可以作为ARG_KEY传入的。为什么？看样子，这次不得不简单的说说Hash表的散列函数了。每个Hash表，总会使用一些散列函数，用来查找Key所对应的Value，理想状态下，我们当然希望Hash表，就是一个数组，虽然这不可能，不过这样理解，可以帮助我们更好的理解Hash表的物理结构，就让我们暂时把它看成一个数组吧。数组总是使用下标来直接获取元素的存储地址，而下标，显然应该是个非负整数，从而Hash表，也应该具备这样的特性，至少必须存在某种算法可以使传入的Key可以直接的转化为一个非负的整数，这也就是ARG_KEY的选择标准。从而对象、引用无论如何都不应该作为ARG_KEY成为CMap的类型参数，而int、unsigned int、指针以及地址就成为了ARG_KEY的常用类型参数，其实也就是那些类似于整型的数据类型。常常看到一些人在用CMap的时候，试图使用CString作为CMap中ARG_KEY的类型参数，这是应该被纠正的方向性错误，但有些人似乎会理直气壮的反驳我，因为他们发现类型参数KEY是可以使用CString的，这很奇怪吗？我说过KEY不能使用CString吗？之所以KEY可以使用CString而ARG_KEY却用的是LPCTSTR，那是因为CString重载了operator==(const char*)这个判等操作符，当CMap从Hash表中获得KEY之后，它会将ARG_KEY与KEY直接相比较。真正存于CMap内部的是KEY，也就是CString。这也就是为什么，我们经常会看到CMap被实化成CMap&lt;CString, LPCTSTR/*相当于const char*，非Unicode情况下*/, CString，CString&amp;&gt;这样的一个四不像实化类的原因，至于CMap的效率优化问题，我们会在以后的文章中继续与大家探讨。</span></p>
<p style="text-align: left; text-indent: 21pt" align="left"><span style="color: teal">CMap</span><span style="color: teal">的确是个很不错的数据结构，尤其在你建立一个字典的时候。比如idealsoft的含义是"曳光科技"，这就是一个元组，也就是一个Pair，Key是"idealsoft"，而Value是"曳光科技"。</span></p>====================================================================<br />#include &nbsp; &lt;afxwin.h&gt; <br />#include &nbsp; &lt;afxtempl.h&gt; <br />void &nbsp; main() <br />{ <br />AfxWinInit(::GetModuleHandle(NULL), &nbsp; NULL, &nbsp; ::GetCommandLine(), &nbsp; 0); <br />CMap &lt;int, &nbsp; int, &nbsp; CString, &nbsp; CString&gt; &nbsp; m_cMap; <br />m_cMap.SetAt(9923033, &nbsp; &nbsp; "张三 "); <br />m_cMap.SetAt(9826033, &nbsp; &nbsp; "张A "); <br />m_cMap.SetAt(9923063, &nbsp; &nbsp; "张B "); <br />m_cMap.SetAt(9923093, &nbsp; &nbsp; "张C "); <br />CString &nbsp; strName; <br />m_cMap.Lookup(9923063, &nbsp; strName); <br />AfxMessageBox(strName); <br />} <br /><br /><br /><img src ="http://www.cppblog.com/wrhwww/aggbug/158802.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/wrhwww/" target="_blank">wrh</a> 2011-10-21 09:38 <a href="http://www.cppblog.com/wrhwww/archive/2011/10/21/158802.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>读取了一个bitmap，把它的一些颜色值改成另外一种颜色。这个怎么办啊？？ </title><link>http://www.cppblog.com/wrhwww/archive/2011/08/26/154422.html</link><dc:creator>wrh</dc:creator><author>wrh</author><pubDate>Fri, 26 Aug 2011 06:59:00 GMT</pubDate><guid>http://www.cppblog.com/wrhwww/archive/2011/08/26/154422.html</guid><wfw:comment>http://www.cppblog.com/wrhwww/comments/154422.html</wfw:comment><comments>http://www.cppblog.com/wrhwww/archive/2011/08/26/154422.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/wrhwww/comments/commentRss/154422.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/wrhwww/services/trackbacks/154422.html</trackback:ping><description><![CDATA[COLORMAP &nbsp; ColorMap[3] &nbsp; = &nbsp; { &nbsp; <br />{ &nbsp; RGB(128,128,128), &nbsp; ::GetSysColor(COLOR_BTNSHADOW) &nbsp; }, &nbsp; <br />{ &nbsp; RGB(192,192,192), &nbsp; ::GetSysColor(COLOR_BTNFACE) &nbsp; }, &nbsp; <br />{ &nbsp; RGB(255,255,255), &nbsp; ::GetSysColor(COLOR_BTNHILIGHT)} &nbsp; <br />}; &nbsp; <br /><br />CBitmap &nbsp; Bitmap; &nbsp; <br />Bitmap.LoadMappedBitmap(IDB_BITMAP, &nbsp; 0, &nbsp; ColorMap, &nbsp; 3);<br /><br /><br />BOOL &nbsp; LoadMappedBitmap( <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; UINT &nbsp; nIDBitmap, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //位图的标识 <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; UINT &nbsp; nFlags &nbsp; = &nbsp; 0, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //通常情况下为0，当将该位图作 <br />&nbsp; &nbsp; &nbsp; &nbsp; 为屏蔽位图使用时该参数为CMB_MASKED <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LPCOLORMAP &nbsp; lpColorMap &nbsp; = &nbsp; NULL, &nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int &nbsp; nMapSize &nbsp; = &nbsp; 0); <br /><br />【返回值】该成员函数调用成功返回一个非零值，否则返回零。 <br />【参 &nbsp; 数】 <br />&nbsp; &nbsp; &nbsp; &nbsp; nIDBitmap <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />&nbsp; &nbsp; &nbsp; nFlags <br /><br />通常情况下为0，当将该位图作为屏蔽位图使用时该参数为CMB_MASKED。 <br /><br />lpColorMap <br /><br />一个指向COLORMAP数据类型数组的指针。COLORMAP的数据结构如下： <br /><br />typedef &nbsp; struct &nbsp; _COLORMAP{ <br /><br />COLORREF &nbsp; from; &nbsp; // &nbsp; 逻辑调色板的颜色 <br /><br />COLORREF &nbsp; to; &nbsp; // &nbsp; 物理调色板的颜色 <br /><br />}COLORMAP, &nbsp; FAR* &nbsp; LPCOLORMAP; <br /><br />nMapSize <br /><br />指定数组中数组元素的个数。 <br /><br />【注 &nbsp; 释】本成员函数可以将一个设备无关位图装入CBitmap类的对象，并根据逻辑调色板与物理调色板的映射关系使系统正确地显示该位图。<br /><br /><br />_COLORMAP &nbsp; iColor[2]={{RGB(191,191,196),::GetSysColor(COLOR_3DFACE)},{RGB(192,192,192),::GetSysColor(COLOR_3DFACE)}}; <br />m_bmToolbarHi.LoadMappedBitmap( &nbsp; IDB_TOOLBARHI,0,iColor,2); <br />&nbsp; &nbsp; &nbsp; &nbsp; m_wndToolBar.SetBitmap( &nbsp; (HBITMAP)m_bmToolbarHi &nbsp; ); <br />这是我的代码，可他不工作啊:~(<br /><br />有个问题提醒一下： <br />库中的LoadMappedBitmap函数对超过256色的图像好像无效，而且会死掉。 <br />对不超过256色的图像是有效的。 <br /><br />我知道了，我的图像是256色的，这不错。但是转换的颜色好像也算一种颜色。我把我导出的图像色数改成128，结果就好了 &nbsp; :D<br /><br /><img src ="http://www.cppblog.com/wrhwww/aggbug/154422.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/wrhwww/" target="_blank">wrh</a> 2011-08-26 14:59 <a href="http://www.cppblog.com/wrhwww/archive/2011/08/26/154422.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>