﻿<?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++博客-春暖花开-随笔分类-windows学习</title><link>http://www.cppblog.com/SpringSnow/category/8492.html</link><description>雪化了，花开了，春天来了</description><language>zh-cn</language><lastBuildDate>Tue, 25 Aug 2009 10:50:12 GMT</lastBuildDate><pubDate>Tue, 25 Aug 2009 10:50:12 GMT</pubDate><ttl>60</ttl><item><title>“没有找到 MSVCR80D.dll”的解决方法</title><link>http://www.cppblog.com/SpringSnow/archive/2009/08/24/94295.html</link><dc:creator>Sandy</dc:creator><author>Sandy</author><pubDate>Mon, 24 Aug 2009 10:41:00 GMT</pubDate><guid>http://www.cppblog.com/SpringSnow/archive/2009/08/24/94295.html</guid><wfw:comment>http://www.cppblog.com/SpringSnow/comments/94295.html</wfw:comment><comments>http://www.cppblog.com/SpringSnow/archive/2009/08/24/94295.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/SpringSnow/comments/commentRss/94295.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/SpringSnow/services/trackbacks/94295.html</trackback:ping><description><![CDATA[曾记得我记录下来了，现在又找不到了，所以还是记录在博客中，作为我的备份档案。<br><br>&#8220;没有找到 MSVCR80D.dll,因此这个程序未能启动，重新安装应用程序，可能会修复此问题。&#8221;<br>在VS2005中，经常碰到这个问题，怎么办呢？是去网上下载一个dll么？我没有尝试过。但是网上提供的一种方法是这样的，我觉得挺简便的。<br><br>如图：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp; <img height=556 alt="" src="http://www.cppblog.com/images/cppblog_com/springsnow/11.jpg" width=742 border=2><br><br>将"Use FAT32 Work-around" 设为yes就可以了。<br>
<img src ="http://www.cppblog.com/SpringSnow/aggbug/94295.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/SpringSnow/" target="_blank">Sandy</a> 2009-08-24 18:41 <a href="http://www.cppblog.com/SpringSnow/archive/2009/08/24/94295.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>多线程程序中的调试</title><link>http://www.cppblog.com/SpringSnow/archive/2009/08/21/94039.html</link><dc:creator>Sandy</dc:creator><author>Sandy</author><pubDate>Fri, 21 Aug 2009 09:19:00 GMT</pubDate><guid>http://www.cppblog.com/SpringSnow/archive/2009/08/21/94039.html</guid><wfw:comment>http://www.cppblog.com/SpringSnow/comments/94039.html</wfw:comment><comments>http://www.cppblog.com/SpringSnow/archive/2009/08/21/94039.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/SpringSnow/comments/commentRss/94039.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/SpringSnow/services/trackbacks/94039.html</trackback:ping><description><![CDATA[<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">今天看的调试的这一章主要是针对多线程程序的调试。多线程程序运行的不确定性，使其调试起来就像抓蝴蝶一样，你捉摸不透它驻足的位置。</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">书中给了一些建议和方法：</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">一是有计划地对付错误。</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对应用程序展开适当的调试，应该是远在你使用调试器之前就开始了。多多使用</span><span lang=EN-US>ASSERT</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">调试措施。（</span><span lang=EN-US>ASSERT</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">背后的概念是安全和速度之间的交换。程序运行因此运行得比较慢，但是</span><span lang=EN-US>Debug Build</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的制造就是为了调试，所以可以理解）在每一个你的假设之处做检验工作。进入一个函数时，确认所有状态。不要只是检查指针是否合法；如果可能，检查一下指针所指的结构中的数据是否一致。</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">二是</span><span lang=EN-US>Bench Testing</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">其实这种方法就是先撇开多线程的环境，测试程序逻辑的正确性。如果</span><span lang=EN-US>OK</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">了，然后再考虑与线程相关的东西。</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">三是线程对话框</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这里主要讨论了对一个特定的线程如何调试，方法是挂起所有的线程——除了我们关注的那个。书中介绍的方法在</span><span lang=EN-US>vs 2005</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">我没有找到。</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">四是日志记录</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这里主要是在控制台窗口显示一些运行信息，我们可以使用</span><span lang=EN-US>printf</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">等函数在控制台输出一些信息来查看线程的运行次序。</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">五是内存记号</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">使用内存记号的好处就是降低彼此干扰的可能性。但是也要注意它不是同步操作，可能会因为两个线程的同时写入引来问题。</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">六是硬件调试寄存器</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span lang=EN-US><o:p>&nbsp;</o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">前面的这六种方法我也只用过三种，有一些还真是第一次见到。不过不怕下次搞不定问题的时候可以拿来进行尝试，来抓一抓隐藏在程序中的&#8220;臭虫们&#8221;。</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span lang=EN-US><o:p>&nbsp;</o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">成功消除多线程程序的&#8220;臭虫&#8221;，作者说需要具备三种素养：决心、耐心、创造力。同时也不要蛮干，要采用科学的方法：观察、预测、测试。</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span lang=EN-US><o:p>&nbsp;</o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">总结一下：借助方法，观察现象，大胆预测，勇敢尝试，完备测试。</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span lang=EN-US><o:p>&nbsp;</o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">项目中也碰到了多线程的使用。未来可能多线程的使用会越来越多，不能停留在完成功能和任务上，应该多思考多测试。避免多线程的不可确定性带来的一些困扰。</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span lang=EN-US><o:p>&nbsp;</o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">学习书籍：《</span><span lang=EN-US>Win32 </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">多线程程序设计》侯捷译</span></p>
<img src ="http://www.cppblog.com/SpringSnow/aggbug/94039.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/SpringSnow/" target="_blank">Sandy</a> 2009-08-21 17:19 <a href="http://www.cppblog.com/SpringSnow/archive/2009/08/21/94039.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转: Windows Mobile下创建cmwap接入点</title><link>http://www.cppblog.com/SpringSnow/archive/2009/04/21/80610.html</link><dc:creator>Sandy</dc:creator><author>Sandy</author><pubDate>Tue, 21 Apr 2009 06:54:00 GMT</pubDate><guid>http://www.cppblog.com/SpringSnow/archive/2009/04/21/80610.html</guid><wfw:comment>http://www.cppblog.com/SpringSnow/comments/80610.html</wfw:comment><comments>http://www.cppblog.com/SpringSnow/archive/2009/04/21/80610.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/SpringSnow/comments/commentRss/80610.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/SpringSnow/services/trackbacks/80610.html</trackback:ping><description><![CDATA[转: http://tech.ddvip.com/2008-09/122062103760957.html<br><br>程序中如果要<nobr oncontextmenu="return false" onmousemove=kwM(1) id=clickeyekey1 onmouseover="kwE(event,1, this)" style="COLOR: #6600ff; BORDER-BOTTOM: #6600ff 1px dotted; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" onclick='kwC(event,1,"")' onmouseout=kwL(event,this)>使用</nobr>http或socket连接服务器，需要先连接网络。ConnMgrEstablishConnectionSync函数中的CONNMGR_CONNECTIONINFO参数，不论采用IID_DestNetWAP还是IID_DestNetInternet，似乎都要依赖于<nobr oncontextmenu="return false" onmousemove=kwM(0) id=clickeyekey0 onmouseover="kwE(event,0, this)" style="COLOR: #6600ff; BORDER-BOTTOM: #6600ff 1px dotted; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" onclick='kwC(event,0,"")' onmouseout=kwL(event,this)>手机</nobr>上的接入点设置。都怪中国移动非要搞什么CMNET、CMWAP，中国特色的通信公司。</clk>
<p>　　可以自行创建一接入点。以下代码创建一个CMWAP接入点：</p>
<p><code>CString strFavoriteXml =<br>L"&lt;wap-provisioningdoc&gt;"<br>L"&lt;characteristic type="CM_Networks"&gt;"<br>L"&lt;characteristic type="Test_GPRS"&gt;"<br>L"&lt;parm name="DestId" value="{D1D06580-C364-55ec-9421-6ACF34129C58}" /&gt;"<br>L"&lt;/characteristic&gt;"<br>L"&lt;/characteristic&gt;"<br>L"&lt;characteristic type="CM_GPRSEntries"&gt;"<br>L"&lt;characteristic type="Test_GPRS"&gt;"<br>L"&lt;parm name="DestId" value="{D1D06580-C364-55ec-9421-6ACF34129C58}" /&gt;"<br>L"&lt;characteristic type="DevSpecificCellular"&gt;"<br>L"&lt;parm name="BearerInfoValid" value="1" /&gt;"<br>L"&lt;parm name="GPRSInfoValid" value="1" /&gt;"<br>L"&lt;parm name="GPRSInfoProtocolType" value="2" /&gt;"<br>L"&lt;parm name="GPRSInfoL2ProtocolType" value="PPP" /&gt;"<br>L"&lt;parm name="GPRSInfoAccessPointName" value="cmwap" /&gt;"<br>L"&lt;parm name="GPRSInfoAddress" value="" /&gt;"<br>L"&lt;parm name="GPRSInfoDataCompression" value="1" /&gt;"<br>L"&lt;parm name="GPRSInfoHeaderCompression" value="1" /&gt;"<br>L"&lt;parm name="GPRSInfoParameters" value="" /&gt;"<br>L"&lt;/characteristic&gt;"<br>L"&lt;/characteristic&gt;"<br>L"&lt;/characteristic&gt;"<br>L"&lt;characteristic type="CM_ProxyEntries"&gt;"<br>L"&lt;characteristic type="WAP"&gt;"<br>L"&lt;parm name="SrcId" value="{D1D06580-C364-55ec-9421-6ACF34129C58}" /&gt;"<br>L"&lt;parm name="DestId" value="{436EF144-B4FB-4863-A041-8F905A62C572}" /&gt;"<br>L"&lt;parm name="Proxy" value="10.0.0.172:80" /&gt;"<br>L"&lt;parm name="Enable" value="1" /&gt;"<br>L"&lt;parm name="Type" value="1" /&gt;"<br>L"&lt;/characteristic&gt;"<br>L"&lt;/characteristic&gt;"<br>L"&lt;/wap-provisioningdoc&gt;";<br>　　<br>LPWSTR pszwXMLout = NULL;<br>HRESULT hr = DMProcessConfigXML(strFavoriteXml, CFGFLAG_PROCESS, &amp;pszwXMLout);<br>　　<br>if ( pszwXMLout )<br>{<br>　delete [] pszwXMLout;<br>　pszwXMLout = NULL;<br>}</code></p>
<img src ="http://www.cppblog.com/SpringSnow/aggbug/80610.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/SpringSnow/" target="_blank">Sandy</a> 2009-04-21 14:54 <a href="http://www.cppblog.com/SpringSnow/archive/2009/04/21/80610.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转:Windows Mobile 6 SDK 中的 Cellular Emulator </title><link>http://www.cppblog.com/SpringSnow/archive/2009/04/15/79967.html</link><dc:creator>Sandy</dc:creator><author>Sandy</author><pubDate>Wed, 15 Apr 2009 01:59:00 GMT</pubDate><guid>http://www.cppblog.com/SpringSnow/archive/2009/04/15/79967.html</guid><wfw:comment>http://www.cppblog.com/SpringSnow/comments/79967.html</wfw:comment><comments>http://www.cppblog.com/SpringSnow/archive/2009/04/15/79967.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/SpringSnow/comments/commentRss/79967.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/SpringSnow/services/trackbacks/79967.html</trackback:ping><description><![CDATA[很长时间没有用Cellular Emulator ,使用上都有一些遗忘. 所以千万别相信自己什么都能记住啊.<br><br>摘自: <a href="http://www.cnblogs.com/upto/archive/2007/02/14/649769.html">http://www.cnblogs.com/upto/archive/2007/02/14/649769.html</a>&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 黎波老师的博客<br><br>
<h1 class=postTitle><a class=postTitle2 id=AjaxHolder_ctl01_TitleUrl href="http://www.cnblogs.com/upto/archive/2007/02/14/cellular-emulater-in-wm6sdk.html"><u><font color=#0000ff>Windows Mobile 6 SDK 中的 Cellular Emulator</font></u></a> </h1>
<div class=clear></div>
<div class=postBody>
<p>现在的 Windows Mobile 设备大多数都拥有电话和其他无线通信的功能。在许多情况下，你想让你的应用程序跟这些通信功能进行交互。例如，你想在电话响起的时候，将你的应用程序播放音乐的声音调小；或者需要直接对通信硬件进行各种操作。那么开发这种类型的应用程序往往比较困难，最大的难点在于测试应用程序。<br><br>为了解决测试这种应用程序的困难，Windows Mobile 6 SDK 包含了 Cellular Emulator（蜂窝仿真器）。Cellular Emulator 让你能够在 Device Emulator 中，测试你的应用程序在各种蜂窝通信的情况下的行为。<br><br><img alt="" src="http://images.cnblogs.com/cnblogs_com/upto/cellular-emulater/2007-02-13_215411.png" border=0><br><br>Cellular Emulator 是一个强大的测试工具，它可以用于测试你的应用程序在蜂窝通信状况变化时的行为。用 Cellular Emulator 可以执行一些简单的测试，如：在仿真器中拨打电话，接听来电和挂断电话，发送和接收 SMS 信息等。为了让开发人员可以测试更复杂的功能，Cellular Emulator 还支持对 SIM 配置信息的修改，还有选择2G网络还是3G网络。所有这些测试工作都不需要用到一台物理设备。</p>
<p>要让 Cellular Emulator 和 Device Emulator 可以一起配合使用，首先你需要把他们关联起来。<br>1. 记下 Cellular Emulator 左下角状态栏的 COM 端口号。如 COM5。<br>2. 在 Device Emulator 中选择&#8220;<strong>File--&gt;Configure...</strong>&#8221;菜单项，打开 <strong>Emulator Properties</strong> 对话框。<br>3. 在 <strong>Emulator Properties</strong> 对话框中选择 <strong>Peripherals</strong> 选项卡。<br>4. 把刚才记下的 COM 端口号输入到 <strong>Serial Port 0</strong> 文本框中。如果你在下拉列表中找不到你的端口号，可以自己输入进去。<br>5. 点击 OK 按钮保存设置，关闭 <strong>Emulator Properties</strong> 对话框。<br>6. 点击&#8220;<strong>File--&gt;Reset--&gt;Soft</strong>&#8221;菜单项，对仿真器进行软重置操作。<br><br><img src="http://images.cnblogs.com/cnblogs_com/upto/cellular-emulater/2007-02-13_220040.png" border=0><br><br>待仿真器完成重置过程并重新启动后，你将会看到仿真器的蜂窝网络已经可用了。如果还是不行，可能是安装了 Windows Mobile 6 SDK 之后，没有重新启动系统的原因吧。<br><br><strong style="FONT-SIZE: 12pt">给仿真器拨打电话</strong><br>打开 Cellular Emulator 的 <strong>Call Manager</strong> 选项卡，在 <strong>Phone Number</strong> 文本框中输入任意一个电话号码，点击旁边的 <strong>Dial</strong> 按钮，仿真器的电话铃声将响起，并显示来自所输入的电话号码的来电。这时在 <strong>Active Calls</strong> 列表中将出现仿真器上的活动通话，<strong>Status</strong> 显示为 Incoming。<br>用7272024这个电话号码向仿真器拨打电话：<br><img height=420 src="http://images.cnblogs.com/cnblogs_com/upto/cellular-emulater/2007-02-13_222130.png" width=450 border=0><br><br>仿真器收到电话号码为7272024的来电：<br><img height=544 alt="" src="http://images.cnblogs.com/cnblogs_com/upto/cellular-emulater/2007-02-13_221518.png" width=356 border=0><br><br><strong style="FONT-SIZE: 12pt">从仿真器拨打电话</strong><br>在 <strong>Preset Number</strong> 列表中提供了4个可供测试的电话号码。<strong>Busy</strong> 表示线路忙，<strong>Reject</strong> 表示拒绝接听，<strong>Hang Up After Connect</strong> 表示接听后再挂断，<strong>No Answer</strong> 表示没有回应。尝试在仿真器中拨打7272021，Cellular Emulator&nbsp;的 <strong>Active Calls</strong> 列表将显示仿真器当前的活动通话。电话接通后持续了10秒钟，然后挂断，也就是<strong>Hang Up After Connect</strong>。<br><img src="http://images.cnblogs.com/cnblogs_com/upto/cellular-emulater/2007-02-13_231445.png" border=0><br><br><img src="http://images.cnblogs.com/cnblogs_com/upto/cellular-emulater/2007-02-13_232140.png" border=0><br><br><strong style="FONT-SIZE: 12pt">向仿真器发送 SMS 信息<br></strong>打开 Cellular Emulator 的 <strong>SMS</strong> 选项卡，在 <strong>Send to device</strong> 的多行文本框中输入短信内容，然后点击 <strong>Send </strong>按钮将短信发送至仿真器。<br><img src="http://images.cnblogs.com/cnblogs_com/upto/cellular-emulater/2007-02-13_233620.png" border=0><br><br>仿真器将收到新短信：<br><img src="http://images.cnblogs.com/cnblogs_com/upto/cellular-emulater/2007-02-13_233658.png" border=0><br><br>还可以设置重复发送。选中 <strong>Repeatly</strong> 检查框，设定好 <strong>Interval</strong>（间隔时间）和 <strong>Max Count</strong>（最大数目），然后再点击 <strong>Send </strong>按钮即可。如果你在仿真器中回复了信息，将会在 Cellular Emulator 的 <strong>Receive from device</strong> 列表中看到你回复的短信。<br><img src="http://images.cnblogs.com/cnblogs_com/upto/cellular-emulater/2007-02-13_235313.png" border=0><br><br><strong style="FONT-SIZE: 12pt">选择网络</strong><br>打开 Cellular Emulator 的 <strong>Network</strong> 选项卡，可以选择2G或者3G网络，断开 GPRS 连接，查看数据通道等。<br><img src="http://images.cnblogs.com/cnblogs_com/upto/cellular-emulater/2007-02-13_235754.png" border=0><br><br><strong style="FONT-SIZE: 12pt">执行和查看 AT 命令</strong><br>打开 Cellular Emulator 的&nbsp;<strong>Injection</strong> 选项卡，这里可以向仿真器发送 AT 命令或事件。<br><img src="http://images.cnblogs.com/cnblogs_com/upto/cellular-emulater/2007-02-13_235826.png" border=0><br><br>打开 Cellular Emulator 的&nbsp;<strong>AT log</strong>&nbsp;选项卡，可以看到刚才所有对仿真器的操作对应的 AT 命令。<br><img src="http://images.cnblogs.com/cnblogs_com/upto/cellular-emulater/2007-02-13_235901.png" border=0><br><br><strong style="FONT-SIZE: 12pt">使用配置文件<br></strong>这里可以选择使用哪一个 SIM 配置文件，文件内容是 XML 格式。<br><img src="http://images.cnblogs.com/cnblogs_com/upto/cellular-emulater/2007-02-13_235844.png" border=0><br><br><strong style="FONT-SIZE: 12pt">总结</strong><br>有了 Cellular Emulator 的配合，Device Emulator 显得更加强大。现在 Windows Mobile 6 开发人员可以使用仿真器进行开发和测试，而不需要购买各种真实设备。遗憾的是，Cellular Emulator 并不支持 Windows Mobile 5.0 和 Windows Mobile 2003 的仿真器。不过好在 Windows Mobile 6 的 API 跟 Windows Mobile 5.0 的绝大部分一样，所以你可以在 Windows Mobile 6 的仿真器中开发和调试 Windows Mobile 5.0 的应用程序。对于 Windows Mobile 2003 可能测试效果没有那么一致，你也可以自己尝试一下。<br><br>参考：<br><a href="http://msdn2.microsoft.com/en-us/library/bb278115.aspx"><font color=#1d58d1><u>What's New for Developers in Windows Mobile 6</u></font></a><br></p>
</div>
<img src ="http://www.cppblog.com/SpringSnow/aggbug/79967.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/SpringSnow/" target="_blank">Sandy</a> 2009-04-15 09:59 <a href="http://www.cppblog.com/SpringSnow/archive/2009/04/15/79967.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>工作小总结:界面响应的问题</title><link>http://www.cppblog.com/SpringSnow/archive/2009/04/14/79851.html</link><dc:creator>Sandy</dc:creator><author>Sandy</author><pubDate>Tue, 14 Apr 2009 01:10:00 GMT</pubDate><guid>http://www.cppblog.com/SpringSnow/archive/2009/04/14/79851.html</guid><wfw:comment>http://www.cppblog.com/SpringSnow/comments/79851.html</wfw:comment><comments>http://www.cppblog.com/SpringSnow/archive/2009/04/14/79851.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/SpringSnow/comments/commentRss/79851.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/SpringSnow/services/trackbacks/79851.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 昨天一直在调一段代码，流程是这样的：我在某个界面程序里先放置了一个对话框A，用户选择是或否。选择是后，会再弹出一个对话框B，并触发一个事件，然后再启动一个对话框C。这些对话框是模态的。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;逻辑感觉很对，没有问题。但是界面的异常让我是头疼。A对话框选择是后，B对话框显示不完全，在C对户框显示的时候，文字显示又有异常。检查了一下，原来EndDialog没有执行成功。使用GetLastError获取的错误值也是正确的。<br>&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 惆怅了&#8230;&#8230;，后来利用线程，去执行那个事件，界面也正常了。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这是为什么呢？<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;我个人觉得是事件的执行影响到了界面的刷新，因为我的事件是在界面的程序里面执行的。它对界面消息进行了阻塞，导致界面不能刷新。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;这个问题，不是我第一次遇到，以前也遇到过这样的问题，没有总结。总结一下，不要再犯了。<br>&nbsp;&nbsp; <br>
<img src ="http://www.cppblog.com/SpringSnow/aggbug/79851.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/SpringSnow/" target="_blank">Sandy</a> 2009-04-14 09:10 <a href="http://www.cppblog.com/SpringSnow/archive/2009/04/14/79851.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Windows Mobile 获取SIM卡联系人信息</title><link>http://www.cppblog.com/SpringSnow/archive/2009/04/09/79344.html</link><dc:creator>Sandy</dc:creator><author>Sandy</author><pubDate>Thu, 09 Apr 2009 07:20:00 GMT</pubDate><guid>http://www.cppblog.com/SpringSnow/archive/2009/04/09/79344.html</guid><wfw:comment>http://www.cppblog.com/SpringSnow/comments/79344.html</wfw:comment><comments>http://www.cppblog.com/SpringSnow/archive/2009/04/09/79344.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/SpringSnow/comments/commentRss/79344.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/SpringSnow/services/trackbacks/79344.html</trackback:ping><description><![CDATA[<p>Windows Mobile上联系人的信息可分别存储在手机和SIM卡中。我尝试过从手机，即所谓的Outlook联系人中读取联系人的信息，但是还没有尝试过从sim卡中读取联系人的信息，心里也一直默认为难吧。今天查了一下，发现竟然这么简单，相比outlook的读取方式来说，简单很多。<br><br>我们先来定义个结构<br><br>typedef struct {<br>&nbsp; TCHAR szName[32];<br>&nbsp; TCHAR szTelNum[32];<br>}CONTACTSTRUCT;<br><br>要使用SIM的相关文件，需要包含头文件 simmgr.h<br><br>首先要初始化一下<br>HSIM lphSim;&nbsp;&nbsp; <br>&nbsp;HRESULT hr = SimInitialize(0, NULL, 0, &amp;lphSim); <br>if(FAILED(hr))&nbsp;&nbsp; <br>&nbsp;{<br>&nbsp;&nbsp;return;<br>&nbsp;}<br><br>其次获取总共使用的多少条记录与总共可以容纳的记录条数&nbsp;&nbsp; <br>&nbsp;DWORD dwUsed,dwTotal;&nbsp;&nbsp; <br>&nbsp;hr = SimGetPhonebookStatus(lphSim, SIM_PBSTORAGE_SIM, &amp;dwUsed, &amp;dwTotal);<br><br>然后我们读取联系人的信息<br>定义一个<br>std::vector&lt;CONTACTSTRUCT&gt; vContact;<br><br>&nbsp;for(int i=0; i&lt;dwTotal; i++)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;{<br>&nbsp;&nbsp;//对结构初始话以下&nbsp;&nbsp; <br>&nbsp;&nbsp;SIMPHONEBOOKENTRY phoneent;&nbsp;&nbsp; <br>&nbsp;&nbsp;memset(&amp;phoneent,0,sizeof(phoneent));&nbsp;&nbsp; <br>&nbsp;&nbsp;phoneent.cbSize = sizeof(phoneent); </p>
<p>&nbsp;&nbsp;if (SUCCEEDED(SimReadPhonebookEntry(lphSim, SIM_PBSTORAGE_SIM, i+1, &amp;phoneent)))<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;CONTACTSTRUCT tempContact&nbsp;= {0};</p>
<p>&nbsp;&nbsp;&nbsp;wcsncpy(tempContact.szName, phoneent.lpszText, 31); //&nbsp;姓名<br>&nbsp;&nbsp;&nbsp;wcsncpy(tempContact.szTelNum, phoneent.lpszAddress, 31); // 电话</p>
<p>&nbsp;&nbsp; vContact.push_back(tempContact&nbsp;);<br>&nbsp;&nbsp;}<br>&nbsp;}</p>
<p>&nbsp;//最后别忘了清理&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;SimDeinitialize(lphSim);<br>&nbsp;lphSim = NULL;<br><br>这里读取的时候用了dwTotal，是因为听有经验的人说，sim卡的存储可能不连续，如果用dwUsed的话，可能会有问题。<br><br>积累一下，有时间再好好看一下outlook联系人的。<br><br>参考文章：<br>Pocket 中获取SIM卡中联系人信息<br><a href="http://blog.csdn.net/xulg1984/archive/2008/05/30/2497712.aspx">http://blog.csdn.net/xulg1984/archive/2008/05/30/2497712.aspx</a><br><br></p>
<img src ="http://www.cppblog.com/SpringSnow/aggbug/79344.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/SpringSnow/" target="_blank">Sandy</a> 2009-04-09 15:20 <a href="http://www.cppblog.com/SpringSnow/archive/2009/04/09/79344.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>vs 后缀名总结</title><link>http://www.cppblog.com/SpringSnow/archive/2009/04/08/79257.html</link><dc:creator>Sandy</dc:creator><author>Sandy</author><pubDate>Wed, 08 Apr 2009 05:43:00 GMT</pubDate><guid>http://www.cppblog.com/SpringSnow/archive/2009/04/08/79257.html</guid><wfw:comment>http://www.cppblog.com/SpringSnow/comments/79257.html</wfw:comment><comments>http://www.cppblog.com/SpringSnow/archive/2009/04/08/79257.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/SpringSnow/comments/commentRss/79257.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/SpringSnow/services/trackbacks/79257.html</trackback:ping><description><![CDATA[<div class=postBody>
<p>转自: <a href="http://www.cnblogs.com/dotnetearthworm/archive/2009/02/02/1382488.html">http://www.cnblogs.com/dotnetearthworm/archive/2009/02/02/1382488.html</a><br><span style="COLOR: #ff0000"><br>.sln</span>：解决方案文件，为解决方案资源管理器提供显示管理文件的图形接口所需的信息。 <br><br><span style="COLOR: #ff0000">.csproj</span>:项目文件，创建应用程序所需的引用、数据连接、文件夹和文件的信息。 <br><br><span style="COLOR: #ff0000">.aspx</span>：Web 窗体页由两部分组成：视觉元素（HTML、服务器控件和静态文本）和该页的编程逻辑。Visual Studio 将这两个组成部分分别存储在一个单独的文件中。视觉元素在.aspx 文件中创建。 <br><br><span style="COLOR: #ff0000">.ascx</span>：ASP.NET的用户控件（也叫做&#8220;pagelets&#8221;），是作为一种封装了特定功能和行为（这两者要被用在Web应用程序的各种页面上）的Web页面被开发的。一个用户控件包含了HTML、代码和其他Web或者用户控件的组合，并在Web服务器上以自己的文件格式保存，其扩展名是*.ascx。ASP.NET里的缺省配置并不允许Web客户端通过URL来访问这些文件，但是这个网站的其他页面可以集成这些文件里所包含的功能。 <br><br><span style="COLOR: #ff0000">.aspx.cs</span>：Web 窗体页的编程逻辑位于一个单独的类文件中，该文件称作代码隐藏类文件（.aspx.cs）。 <br><br><span style="COLOR: #ff0000">.cs</span>： 类模块代码文件。业务逻辑处理层的代码。 <br><br><span style="COLOR: #ff0000">.asax</span>：Global.asax 文件（也叫做 ASP.NET 应用程序文件）是一个可选的文件，该文件包含响应 ASP.NET 或 HTTP 模块引发的应用程序级别事件的代码。 <br><br><span style="COLOR: #ff0000">.config</span>：Web.config 文件向它们所在的目录和所有子目录提供配置信息。 <br><br><span style="COLOR: #ff0000">.aspx.resx/.resx</span>：资源文件，资源是在逻辑上由应用程序部署的任何非可执行数据。通过在资源文件中存储数据，无需重新编译整个应用程序即可更改数据。 51aspx.com <br><br><span style="COLOR: #ff0000">.XSD</span>:XML schema的一种.从DTD,XDR发展到XSD <br><br><span style="COLOR: #ff0000">.pdb</span>:PDB（程序数据库）文件保持着调试和项目状态信息，从而可以对程序的调试配置进行增量链接。 <br><br><span style="COLOR: #ff0000">.suo</span>:解决方案用户选项,记录所有将与解决方案建立关联的选项，以便在每次打开时，它都包含您所做的自定义设置。 <br><br><span style="COLOR: #ff0000">.asmx</span>：.asmx文件包含 WebService 处理指令，并用作 XML Web services 的可寻址入口点 51aspx。 <br><br><span style="COLOR: #ff0000">.vsdisco</span>（项目发现）文件 基于 XML 的文件，它包含为 Web 服务提供发现信息的资源的链接 (URL-51aspx )。 <br><br><span style="COLOR: #ff0000">.htc</span>:一个HTML文件,包含脚本和定义组件的一系列HTC特定元素.htc提供在脚本中implement组件的机制</p>
<p>来源： .Net中文社区（<a href="http://www.aspxcs.net/"><u><font color=#0000ff>http://www.aspxcs.net/</font></u></a>)<br><br>上面是我看到的一些介绍,这里再补充一些:<br>&nbsp; .clw&nbsp;&nbsp; 支持ClassWizard&nbsp;&nbsp; <br>&nbsp; .ncb&nbsp;&nbsp; 支持ClassView&nbsp;&nbsp; <br>&nbsp; .opt&nbsp;&nbsp; 保存工作空间的配置&nbsp;&nbsp; <br>&nbsp; .aps&nbsp;&nbsp; 支持ResourceView&nbsp;&nbsp; <br>&nbsp; .bsc&nbsp;&nbsp; 浏览器信息文件&nbsp;&nbsp; <br>&nbsp; .dsp&nbsp;&nbsp; 项目文件&nbsp;&nbsp; <br>&nbsp; .dsw&nbsp;&nbsp; 工作空间文件&nbsp;&nbsp; <br>&nbsp; .mak&nbsp;&nbsp; 外部的创建文件&nbsp;&nbsp; <br>&nbsp; .plg&nbsp;&nbsp; 建立日志文件&nbsp; <br><br></p>
</div>
<img src ="http://www.cppblog.com/SpringSnow/aggbug/79257.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/SpringSnow/" target="_blank">Sandy</a> 2009-04-08 13:43 <a href="http://www.cppblog.com/SpringSnow/archive/2009/04/08/79257.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>warning C4005: 'WINVER' : macro redefinition 的解决方法</title><link>http://www.cppblog.com/SpringSnow/archive/2009/04/07/79184.html</link><dc:creator>Sandy</dc:creator><author>Sandy</author><pubDate>Tue, 07 Apr 2009 07:22:00 GMT</pubDate><guid>http://www.cppblog.com/SpringSnow/archive/2009/04/07/79184.html</guid><wfw:comment>http://www.cppblog.com/SpringSnow/comments/79184.html</wfw:comment><comments>http://www.cppblog.com/SpringSnow/archive/2009/04/07/79184.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/SpringSnow/comments/commentRss/79184.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/SpringSnow/services/trackbacks/79184.html</trackback:ping><description><![CDATA[&nbsp;对于warning C4005: 'WINVER' : macro redefinition的处理<br><br>&nbsp;在Windows.h中有如下定义： &nbsp; <br>&nbsp; #ifndef &nbsp; WINVER &nbsp; <br>&nbsp; #define &nbsp; WINVER &nbsp; 0x0400 &nbsp; <br>&nbsp; #endif &nbsp; <br>&nbsp; 如果你把#define &nbsp; WINVER &nbsp; 0x500置于#include &nbsp; &lt;windows.h&gt;之前,就不会出现警告.&nbsp;&nbsp;&nbsp;<br><br>摘自:http://topic.csdn.net/t/20020103/15/456195.html<br>
<img src ="http://www.cppblog.com/SpringSnow/aggbug/79184.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/SpringSnow/" target="_blank">Sandy</a> 2009-04-07 15:22 <a href="http://www.cppblog.com/SpringSnow/archive/2009/04/07/79184.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>如何在方框里打对勾</title><link>http://www.cppblog.com/SpringSnow/archive/2009/03/31/78463.html</link><dc:creator>Sandy</dc:creator><author>Sandy</author><pubDate>Tue, 31 Mar 2009 07:44:00 GMT</pubDate><guid>http://www.cppblog.com/SpringSnow/archive/2009/03/31/78463.html</guid><wfw:comment>http://www.cppblog.com/SpringSnow/comments/78463.html</wfw:comment><comments>http://www.cppblog.com/SpringSnow/archive/2009/03/31/78463.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/SpringSnow/comments/commentRss/78463.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/SpringSnow/services/trackbacks/78463.html</trackback:ping><description><![CDATA[这个的确还是挺头疼的。前一阶段同学告诉我，很不幸，今天又给忘了。<br>查了一下，再根据模糊记忆，还是把方框打上了对勾。<br><br>可能你也有这样的烦恼，不妨我们来看一下：<br><br>在word字体中选择Wingdings2，然后写一个大写R，这样你就看到方框打对勾了。<br><br>好记性真不如烂笔头，占此一角，记录一下。<br><br>
<img src ="http://www.cppblog.com/SpringSnow/aggbug/78463.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/SpringSnow/" target="_blank">Sandy</a> 2009-03-31 15:44 <a href="http://www.cppblog.com/SpringSnow/archive/2009/03/31/78463.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>windows mobile 中的Database 对应值</title><link>http://www.cppblog.com/SpringSnow/archive/2009/03/30/78378.html</link><dc:creator>Sandy</dc:creator><author>Sandy</author><pubDate>Mon, 30 Mar 2009 08:32:00 GMT</pubDate><guid>http://www.cppblog.com/SpringSnow/archive/2009/03/30/78378.html</guid><wfw:comment>http://www.cppblog.com/SpringSnow/comments/78378.html</wfw:comment><comments>http://www.cppblog.com/SpringSnow/archive/2009/03/30/78378.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/SpringSnow/comments/commentRss/78378.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/SpringSnow/services/trackbacks/78378.html</trackback:ping><description><![CDATA[<p>Windows mobile 中 outlook 中任务,约会,联系人,在调用时,有相应的database oid<br>对应的database oid 不是很清楚,我通过实验,发现,任务是13, 约会是9, 联系人是10.<br><br>那有没有专门的数值对应呢?查了一下,发现这么个东东:<br><br>typedef /* [v1_enum] */<br>enum OlDefaultFolders<br>&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp; olFolderCalendar&nbsp;&nbsp;&nbsp; = 9,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; olFolderContacts&nbsp;&nbsp;&nbsp; = 10,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; olFolderTasks&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = 13,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; olFolderCities&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = 101,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; olFolderInfrared&nbsp;&nbsp;&nbsp; = 102,<br>&nbsp;&nbsp;&nbsp; } OlDefaultFolders;<br><br>和我们的实验数据一样.<br><br>不错吧.</p>
<img src ="http://www.cppblog.com/SpringSnow/aggbug/78378.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/SpringSnow/" target="_blank">Sandy</a> 2009-03-30 16:32 <a href="http://www.cppblog.com/SpringSnow/archive/2009/03/30/78378.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>DATE和SYSTEMTIME的转换</title><link>http://www.cppblog.com/SpringSnow/archive/2009/03/26/77906.html</link><dc:creator>Sandy</dc:creator><author>Sandy</author><pubDate>Thu, 26 Mar 2009 01:21:00 GMT</pubDate><guid>http://www.cppblog.com/SpringSnow/archive/2009/03/26/77906.html</guid><wfw:comment>http://www.cppblog.com/SpringSnow/comments/77906.html</wfw:comment><comments>http://www.cppblog.com/SpringSnow/archive/2009/03/26/77906.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/SpringSnow/comments/commentRss/77906.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/SpringSnow/services/trackbacks/77906.html</trackback:ping><description><![CDATA[最近在搞一个小东东,<br>里面涉及到了DATE和SYSTEMTIME的转换,没有用到过,记录一下.<br><br>&nbsp;<strong> DATE 转换成SYSTEMTIME</strong><br>&nbsp; VariantTimeToSystemTime<br>&nbsp;&nbsp;其原型为:<br><strong>&nbsp; INT VariantTimeToSystemTime( <br>&nbsp; double </strong><em><a class=synParam onclick=showTip(this) href=""><font color=#006bad>vtime</font></a></em><strong>,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </strong><br><strong>&nbsp; LPSYSTEMTIME </strong><em><a class=synParam onclick=showTip(this) href=""><font color=#006bad>lpSystemTime</font></a>&nbsp; </em><br><strong>&nbsp; );</strong><br>&nbsp;&nbsp;<br><br>&nbsp;&nbsp;&nbsp;<strong>SYSTEMTIME转换成DATE <br></strong>&nbsp;&nbsp; SystemTimeToVariantTime<br>&nbsp; 其原型为:<br>&nbsp; <strong>INT SystemTimeToVariantTime(<br>&nbsp; LPSYSTEMTIME </strong><em><a class=synParam onclick=showTip(this) href=""><font color=#006bad>lpSystemTime</font></a></em>,<em>&nbsp; </em><br><strong>&nbsp; double </strong><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *<a class=synParam onclick=showTip(this) href=""><font color=#006bad>pvtime</font></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </em><br><strong>&nbsp; );</strong>
<img src ="http://www.cppblog.com/SpringSnow/aggbug/77906.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/SpringSnow/" target="_blank">Sandy</a> 2009-03-26 09:21 <a href="http://www.cppblog.com/SpringSnow/archive/2009/03/26/77906.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>对话框的属性问题</title><link>http://www.cppblog.com/SpringSnow/archive/2009/03/18/77048.html</link><dc:creator>Sandy</dc:creator><author>Sandy</author><pubDate>Wed, 18 Mar 2009 11:00:00 GMT</pubDate><guid>http://www.cppblog.com/SpringSnow/archive/2009/03/18/77048.html</guid><wfw:comment>http://www.cppblog.com/SpringSnow/comments/77048.html</wfw:comment><comments>http://www.cppblog.com/SpringSnow/archive/2009/03/18/77048.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/SpringSnow/comments/commentRss/77048.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/SpringSnow/services/trackbacks/77048.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 今天调试安装文件的对话框，横屏的时候，Edit框的显示，总会随着滚动条往上移动，下面显示出一大片的空白。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 很是郁闷啊&#8230;&#8230;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在代码中修改了很长时间，找不出原因，最后和别人代码比对的时候，发现我竟然是在资源文件中的对话框属性定义中比别人多一个WS_BORDER属性，问题迎刃而解。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 但究其原因，还不是很清楚。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WS_BORDER: Create a window that has a border.<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;似乎也看不出来什么原因。
<img src ="http://www.cppblog.com/SpringSnow/aggbug/77048.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/SpringSnow/" target="_blank">Sandy</a> 2009-03-18 19:00 <a href="http://www.cppblog.com/SpringSnow/archive/2009/03/18/77048.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Windows Mobile中Edit控件的滚动条问题</title><link>http://www.cppblog.com/SpringSnow/archive/2009/03/18/77046.html</link><dc:creator>Sandy</dc:creator><author>Sandy</author><pubDate>Wed, 18 Mar 2009 10:48:00 GMT</pubDate><guid>http://www.cppblog.com/SpringSnow/archive/2009/03/18/77046.html</guid><wfw:comment>http://www.cppblog.com/SpringSnow/comments/77046.html</wfw:comment><comments>http://www.cppblog.com/SpringSnow/archive/2009/03/18/77046.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/SpringSnow/comments/commentRss/77046.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/SpringSnow/services/trackbacks/77046.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在Windows Mobile中，Edit控件在具有WS_VSCROLL的时候，无论显示文字的多少，都会显示滚动条。如何在显示文字不到一页的情况下，让滚动条不显示呢？<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 我是这样考虑的：判断显示文字的高度，即显示文字的行数*单个文字的高度，判断其是否大于屏幕高度，如果大于，则改变Edit控件的属性，使其具有WS_VSCROLL属性；如果小于或等于，则改变Edit控件的属性，使其不具有WS_VSCROLL属性。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;代码示例：<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int&nbsp;height = GetSystemMetrics(SM_CYFULLSCREEN); //&nbsp;此处示屏幕高度，可自己设定<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HWND&nbsp;hEdit = GetDlgItem(hDlg, IDC_EDIT);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DWORD dwLineCount = (DWORD)::SendMessage(hEdit, EM_GETLINECOUNT, 0, 0L);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HDC hdc = GetDC(hDlg);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TEXTMETRIC metric;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GetTextMetrics(hdc, &amp;metric);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ReleaseDC(hDlg, hdc);&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (metric.tmHeight * dwLineCount &lt;= height))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SetWindowLong(hEdit, GWL_STYLE, WS_VISIBLE | ES_MULTILINE | ES_READONLY);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SetWindowLong(hEdit,GWL_STYLE,&nbsp;WS_VISIBLE|&nbsp;WS_VSCROLL|&nbsp;&nbsp;&nbsp;ES_MULTILINE&nbsp;&nbsp;|ES_READONLY);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;我在创建Edit控件的时候，一开始没有设置WS_VSCROLL属性，发现加上WS_VSCROLL属性后，对于按键的上下响应有些问题。后来就反其道而行之，先让其具有WS_VSCROLL属性，然后再判断其是否该显示滚动条。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;在Windows Mobile中涉及到横竖屏切换的问题，比如说，在竖屏的时候没有滚动条，到横屏的时候又需要有滚动条，此时怎么办？<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;在WM＿SIZE中进行以上的属性判断，但是有一个问题需要注意：如果需要调整Edit控件的大小，需要在属性判断置后进行。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;一点心得，大家可以试试哈！<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br><br>
<img src ="http://www.cppblog.com/SpringSnow/aggbug/77046.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/SpringSnow/" target="_blank">Sandy</a> 2009-03-18 18:48 <a href="http://www.cppblog.com/SpringSnow/archive/2009/03/18/77046.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转：Teach Yourself Programming in Ten Years </title><link>http://www.cppblog.com/SpringSnow/archive/2009/03/14/76557.html</link><dc:creator>Sandy</dc:creator><author>Sandy</author><pubDate>Sat, 14 Mar 2009 02:24:00 GMT</pubDate><guid>http://www.cppblog.com/SpringSnow/archive/2009/03/14/76557.html</guid><wfw:comment>http://www.cppblog.com/SpringSnow/comments/76557.html</wfw:comment><comments>http://www.cppblog.com/SpringSnow/archive/2009/03/14/76557.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/SpringSnow/comments/commentRss/76557.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/SpringSnow/services/trackbacks/76557.html</trackback:ping><description><![CDATA[<p style="FONT-SIZE: 14pt">Why is everyone in such a rush?<br>Walk into any bookstore, and you'll see how to Teach Yourself Java in 7 Days alongside endless variations offering to teach Visual Basic, Windows, the Internet, and so on in a few days or hours. I did the following power search at Amazon.com: <br>pubdate: after 1992 and title: days and<br>(title: learn or title: teach yourself)<br>and got back 248 hits. The first 78 were computer books (number 79 was Learn Bengali in 30 days). I replaced "days" with "hours" and got remarkably similar results: 253 more books, with 77 computer books followed by Teach Yourself Grammar and Style in 24 Hours at number 78. Out of the top 200 total, 96% were computer books. <br>The conclusion is that either people are in a big rush to learn about computers, or that computers are somehow fabulously easier to learn than anything else. There are no books on how to learn Beethoven, or Quantum Physics, or even Dog Grooming in a few days. </p>
<p style="FONT-SIZE: 14pt">Let's analyze what a title like Learn Pascal in Three Days could mean: </p>
<p style="FONT-SIZE: 14pt">Learn: In 3 days you won't have time to write several significant programs, and learn from your successes and failures with them. You won't have time to work with an experienced programmer and understand what it is like to live in that environment. In short, you won't have time to learn much. So they can only be talking about a superficial familiarity, not a deep understanding. As Alexander Pope said, a little learning is a dangerous thing.</p>
<p style="FONT-SIZE: 14pt">Pascal: In 3 days you might be able to learn the syntax of Pascal (if you already knew a similar language), but you couldn't learn much about how to use the syntax. In short, if you were, say, a Basic programmer, you could learn to write programs in the style of Basic using Pascal syntax, but you couldn't learn what Pascal is actually good (and bad) for. So what's the point? Alan Perlis once said: "A language that doesn't affect the way you think about programming, is not worth knowing". One possible point is that you have to learn a tiny bit of Pascal (or more likely, something like Visual Basic or javascript) because you need to interface with an existing tool to accomplish a specific task. But then you're not learning how to program; you're learning to accomplish that task.</p>
<p style="FONT-SIZE: 14pt">in Three Days: Unfortunately, this is not enough, as the next section shows. <br>Teach Yourself Programming in Ten Years<br>Researchers (Hayes, Bloom) have shown it takes about ten years to develop expertise in any of a wide variety of areas, including chess playing, music composition, painting, piano playing, swimming, tennis, and research in neuropsychology and topology. There appear to be no real shortcuts: even Mozart, who was a musical prodigy at age 4, took 13 more years before he began to produce world-class music. In another genre, the Beatles seemed to burst onto the scene, appearing on the Ed Sullivan show in 1964. But they had been playing since 1957, and while they had mass appeal early on, their first great critical success, Sgt. Peppers, was released in 1967. Samuel Johnson thought it took longer than ten years: "Excellence in any department can be attained only by the labor of a lifetime; it is not to be purchased at a lesser price." And Chaucer complained "the lyf so short, the craft so long to lerne." <br>Here's my recipe for programming success: </p>
<p style="FONT-SIZE: 14pt">Get interested in programming, and do some because it is fun. Make sure that it keeps being enough fun so that you will be willing to put in ten years.</p>
<p style="FONT-SIZE: 14pt"><span style="COLOR: #ff0000">Talk to other programmers; read other programs. This is more important than any book or training course.</span></p>
<p style="FONT-SIZE: 14pt">Program. <span style="COLOR: #ff0000">The best kind of learning is learning by doing.</span> To put it more technically, "the maximal level of performance for individuals in a given domain is not attained automatically as a function of extended experience, but the level of performance can be increased even by highly experienced individuals as a result of deliberate efforts to improve." (p. 366) and "the most effective learning requires a well-defined task with an appropriate difficulty level for the particular individual, informative feedback, and opportunities for repetition and corrections of errors." (p. 20-21) The book Cognition in Practice: Mind, Mathematics, and Culture in Everyday Life is an interesting reference for this viewpoint.</p>
<p style="FONT-SIZE: 14pt">If you want, put in four years at a college (or more at a graduate school). This will give you access to some jobs that require credentials, and it will give you a deeper understanding of the field, but if you don't enjoy school, you can (with some dedication) get similar experience on the job. In any case, book learning alone won't be enough. "Computer science education cannot make anybody an expert programmer any more than studying brushes and pigment can make somebody an expert painter" says Eric Raymond, author of The New Hacker's Dictionary. One of the best programmers I ever hired had only a High School degree; he's produced a lot of great software, has his own news group, and through stock options is no doubt much richer than I'll ever be.</p>
<p style="FONT-SIZE: 14pt">Work on projects with other programmers. Be the best programmer on some projects; be the worst on some others. When you're the best, you get to test your abilities to lead a project, and to inspire others with your vision. When you're the worst, you learn what the masters do, and you learn what they don't like to do (because they make you do it for them).</p>
<p style="FONT-SIZE: 14pt">Work on projects after other programmers. Be involved in understanding a program written by someone else. See what it takes to understand and fix it when the original programmers are not around. Think about how to design your programs to make it easier for those who will maintain it after you.</p>
<p style="FONT-SIZE: 14pt">Learn at least a half dozen programming languages. Include one language that supports class abstractions (like Java or C++), one that supports functional abstraction (like Lisp or ML), one that supports syntactic abstraction (like Lisp), one that supports declarative specifications (like Prolog or C++ templates), one that supports coroutines (like Icon or Scheme), and one that supports parallelism (like Sisal). </p>
<p style="FONT-SIZE: 14pt">Remember that there is a "computer" in "computer science". Know how long it takes your computer to execute an instruction, fetch a word from memory (with and without a cache miss), read consecutive words from disk, and seek to a new location on disk. (Answers here.) </p>
<p style="FONT-SIZE: 14pt">Get involved in a language standardization effort. It could be the ANSI C++ committee, or it could be deciding if your local coding style will have 2 or 4 space indentation levels. Either way, you learn about what other people like in a language, how deeply they feel so, and perhaps even a little about why they feel so.</p>
<p style="FONT-SIZE: 14pt">Have the good sense to get off the language standardization effort as quickly as possible. <br>With all that in mind, its questionable how far you can get just by book learning. Before my first child was born, I read all the How To books, and still felt like a clueless novice. 30 Months later, when my second child was due, did I go back to the books for a refresher? No. Instead, I relied on my personal experience, which turned out to be far more useful and reassuring to me than the thousands of pages written by experts. <br>Fred Brooks, in his essay No Silver Bullets identified a three-part plan for finding great software designers: </p>
<p style="FONT-SIZE: 14pt">Systematically identify top designers as early as possible.</p>
<p style="FONT-SIZE: 14pt">Assign a career mentor to be responsible for the development of the prospect and carefully keep a career file.</p>
<p style="FONT-SIZE: 14pt">Provide opportunities for growing designers to interact and stimulate each other.</p>
<p style="FONT-SIZE: 14pt">This assumes that some people already have the qualities necessary for being a great designer; the job is to properly coax them along. Alan Perlis put it more succinctly: "Everyone can be taught to sculpt: Michelangelo would have had to be taught how not to. So it is with the great programmers". <br>So go ahead and buy that Java book; you'll probably get some use out of it. But you won't change your life, or your real overall expertise as a programmer in 24 hours, days, or even months. </p>
<p style="FONT-SIZE: 14pt"><br>References<br>Bloom, Benjamin (ed.) Developing Talent in Young People, Ballantine, 1985. </p>
<p style="FONT-SIZE: 14pt">Brooks, Fred, No Silver Bullets, IEEE Computer, vol. 20, no. 4, 1987, p. 10-19. </p>
<p style="FONT-SIZE: 14pt">Hayes, John R., Complete Problem Solver Lawrence Erlbaum, 1989. </p>
<p style="FONT-SIZE: 14pt">Lave, Jean, Cognition in Practice: Mind, Mathematics, and Culture in Everyday Life, Cambridge University Press, 1988. <br><a href="http://www.norvig.com/">http://www.norvig.com/</a></p>
<img src ="http://www.cppblog.com/SpringSnow/aggbug/76557.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/SpringSnow/" target="_blank">Sandy</a> 2009-03-14 10:24 <a href="http://www.cppblog.com/SpringSnow/archive/2009/03/14/76557.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Windows Mobile获取进程路径</title><link>http://www.cppblog.com/SpringSnow/archive/2009/03/11/76250.html</link><dc:creator>Sandy</dc:creator><author>Sandy</author><pubDate>Wed, 11 Mar 2009 09:52:00 GMT</pubDate><guid>http://www.cppblog.com/SpringSnow/archive/2009/03/11/76250.html</guid><wfw:comment>http://www.cppblog.com/SpringSnow/comments/76250.html</wfw:comment><comments>http://www.cppblog.com/SpringSnow/archive/2009/03/11/76250.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/SpringSnow/comments/commentRss/76250.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/SpringSnow/services/trackbacks/76250.html</trackback:ping><description><![CDATA[今天在项目中遇到了一个问题：在smartphone上获取进程地址不成功，而在pocket pc上却可以获取成功。研究了一下，这是跟smartphone上的安全机制有关，需要对我们的应用程序进行签名。<br><br>开发的时候利用数字签名就可以解决。<br><br>开发的时候，在Project-&gt;Property-&gt;Configuration Properties-&gt;Authenticode Signing中需要加载开发安全证书。<br><br>这样我们就可以很方便的获得进程的路径<br><br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">TCHAR&nbsp;szPath[MAX_PATH];<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>HANDLE&nbsp;hProcess&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;OpenProcess(</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">,&nbsp;FALSE,&nbsp;pe.th32ProcessID);<br>&nbsp;&nbsp; GetModuleFileName((HMODULE)hProcess,&nbsp;szPath,&nbsp;</span><span style="COLOR: #0000ff">sizeof</span><span style="COLOR: #000000">(szPath));<br>&nbsp; &nbsp;CloseHandle(hProcess);</span></div>
<br>如果hProcess为NULL的话，获取的是当前进程的路径。<br><br>所以开发SmartPhone时需要注意这点。涉及特权API了，就需要签名了。
<img src ="http://www.cppblog.com/SpringSnow/aggbug/76250.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/SpringSnow/" target="_blank">Sandy</a> 2009-03-11 17:52 <a href="http://www.cppblog.com/SpringSnow/archive/2009/03/11/76250.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Windows Mobile 发送短信的问题</title><link>http://www.cppblog.com/SpringSnow/archive/2009/03/10/76107.html</link><dc:creator>Sandy</dc:creator><author>Sandy</author><pubDate>Tue, 10 Mar 2009 06:14:00 GMT</pubDate><guid>http://www.cppblog.com/SpringSnow/archive/2009/03/10/76107.html</guid><wfw:comment>http://www.cppblog.com/SpringSnow/comments/76107.html</wfw:comment><comments>http://www.cppblog.com/SpringSnow/archive/2009/03/10/76107.html#Feedback</comments><slash:comments>11</slash:comments><wfw:commentRss>http://www.cppblog.com/SpringSnow/comments/commentRss/76107.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/SpringSnow/services/trackbacks/76107.html</trackback:ping><description><![CDATA[&nbsp;
<p><span>最近在工作中遇到一个比较怪异的现象，在某些省区与</span><span>SP</span><span>的短信交互存在问题，短信发送不出去。查了一下原因：</span><span>SmsSendMessage</span><span>参数设置的问题。</span></p>
<p><span>在</span><span>Windows Mobile 5.0SDK</span><span>的</span><span>HelloSMS</span><span>例子中，发送短信的代码是这样写的</span></p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;SendSMS(BOOL&nbsp;bSendConfirmation,&nbsp;BOOL&nbsp;bUseDefaultSMSC,&nbsp;LPCTSTR&nbsp;lpszSMSC,&nbsp;LPCTSTR&nbsp;lpszRecipient,&nbsp;LPCTSTR&nbsp;lpszMessage)<br><img id=Codehighlighter1_121_1969_Open_Image onclick="this.style.display='none'; Codehighlighter1_121_1969_Open_Text.style.display='none'; Codehighlighter1_121_1969_Closed_Image.style.display='inline'; Codehighlighter1_121_1969_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_121_1969_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_121_1969_Closed_Text.style.display='none'; Codehighlighter1_121_1969_Open_Image.style.display='inline'; Codehighlighter1_121_1969_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_121_1969_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_121_1969_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;SMS_HANDLE&nbsp;smshHandle;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;SMS_ADDRESS&nbsp;smsaSource;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;SMS_ADDRESS&nbsp;smsaDestination;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;TEXT_PROVIDER_SPECIFIC_DATA&nbsp;tpsd;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;SMS_MESSAGE_ID&nbsp;smsmidMessageID;<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;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;try&nbsp;to&nbsp;open&nbsp;an&nbsp;SMS&nbsp;Handle</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(FAILED(SmsOpen(SMS_MSGTYPE_TEXT,&nbsp;SMS_MODE_SEND,&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">smshHandle,&nbsp;NULL)))<br><img id=Codehighlighter1_375_562_Open_Image onclick="this.style.display='none'; Codehighlighter1_375_562_Open_Text.style.display='none'; Codehighlighter1_375_562_Closed_Image.style.display='inline'; Codehighlighter1_375_562_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_375_562_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_375_562_Closed_Text.style.display='none'; Codehighlighter1_375_562_Open_Image.style.display='inline'; Codehighlighter1_375_562_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_375_562_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_375_562_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MessageBox(NULL,<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(LPCTSTR)LoadString(ghInstance,&nbsp;IDS_ERROR_SMSOPEN,&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">),&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(LPCTSTR)LoadString(ghInstance,&nbsp;IDS_CAPTION_ERROR,&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">),<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MB_OK&nbsp;</span><span style="COLOR: #000000">|</span><span style="COLOR: #000000">&nbsp;MB_ICONERROR);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><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;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;Create&nbsp;the&nbsp;source&nbsp;address</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">bUseDefaultSMSC)<br><img id=Codehighlighter1_618_743_Open_Image onclick="this.style.display='none'; Codehighlighter1_618_743_Open_Text.style.display='none'; Codehighlighter1_618_743_Closed_Image.style.display='inline'; Codehighlighter1_618_743_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_618_743_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_618_743_Closed_Text.style.display='none'; Codehighlighter1_618_743_Open_Image.style.display='inline'; Codehighlighter1_618_743_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_618_743_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_618_743_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;smsaSource.smsatAddressType&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;SMSAT_INTERNATIONAL;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_tcsncpy(smsaSource.ptsAddress,&nbsp;lpszSMSC,&nbsp;SMS_MAX_ADDRESS_LENGTH);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><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;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;Create&nbsp;the&nbsp;destination&nbsp;address</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;smsaDestination.smsatAddressType&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;SMSAT_INTERNATIONAL;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;_tcsncpy(smsaDestination.ptsAddress,&nbsp;lpszRecipient,&nbsp;SMS_MAX_ADDRESS_LENGTH);<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;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;Set&nbsp;up&nbsp;provider&nbsp;specific&nbsp;data</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;memset(</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">tpsd,&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #0000ff">sizeof</span><span style="COLOR: #000000">(tpsd));<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;tpsd.dwMessageOptions&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;bSendConfirmation&nbsp;</span><span style="COLOR: #000000">?</span><span style="COLOR: #000000">&nbsp;PS_MESSAGE_OPTION_STATUSREPORT&nbsp;:&nbsp;PS_MESSAGE_OPTION_NONE;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;tpsd.psMessageClass&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;PS_MESSAGE_CLASS1;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;tpsd.psReplaceOption&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;PSRO_NONE;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;tpsd.dwHeaderDataSize&nbsp;</span><span style="COLOR: #000000">=</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/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;Send&nbsp;the&nbsp;message,&nbsp;indicating&nbsp;success&nbsp;or&nbsp;failure</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(SUCCEEDED(SmsSendMessage(smshHandle,&nbsp;((bUseDefaultSMSC)&nbsp;</span><span style="COLOR: #000000">?</span><span style="COLOR: #000000">&nbsp;NULL&nbsp;:&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">smsaSource),&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&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><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">smsaDestination,&nbsp;NULL,&nbsp;(PBYTE)&nbsp;lpszMessage,&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&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;_tcslen(lpszMessage)&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">sizeof</span><span style="COLOR: #000000">(TCHAR),&nbsp;(PBYTE)&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">tpsd,&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&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><span style="COLOR: #0000ff">sizeof</span><span style="COLOR: #000000">(TEXT_PROVIDER_SPECIFIC_DATA),&nbsp;SMSDE_OPTIMAL,&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&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;SMS_OPTION_DELIVERY_NONE,&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">smsmidMessageID)))<br><img id=Codehighlighter1_1567_1725_Open_Image onclick="this.style.display='none'; Codehighlighter1_1567_1725_Open_Text.style.display='none'; Codehighlighter1_1567_1725_Closed_Image.style.display='inline'; Codehighlighter1_1567_1725_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_1567_1725_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_1567_1725_Closed_Text.style.display='none'; Codehighlighter1_1567_1725_Open_Image.style.display='inline'; Codehighlighter1_1567_1725_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_1567_1725_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_1567_1725_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MessageBox(NULL,<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(LPCTSTR)LoadString(ghInstance,&nbsp;IDS_SMSSENT,&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">),&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(LPCTSTR)LoadString(ghInstance,&nbsp;IDS_CAPTION_SUCCESS,&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">),<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MB_OK);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"><br><img id=Codehighlighter1_1734_1911_Open_Image onclick="this.style.display='none'; Codehighlighter1_1734_1911_Open_Text.style.display='none'; Codehighlighter1_1734_1911_Closed_Image.style.display='inline'; Codehighlighter1_1734_1911_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_1734_1911_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_1734_1911_Closed_Text.style.display='none'; Codehighlighter1_1734_1911_Open_Image.style.display='inline'; Codehighlighter1_1734_1911_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_1734_1911_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_1734_1911_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MessageBox(NULL,<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(LPCTSTR)LoadString(ghInstance,&nbsp;IDS_ERROR_SMSSEND,&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">),&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(LPCTSTR)LoadString(ghInstance,&nbsp;IDS_CAPTION_ERROR,&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">),<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MB_OK&nbsp;</span><span style="COLOR: #000000">|</span><span style="COLOR: #000000">&nbsp;MB_ICONERROR);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><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;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;clean&nbsp;up</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;VERIFY(SUCCEEDED(SmsClose(smshHandle)));<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></span></div>
<br>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span style="FONT-FAMILY: 新宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-no-proof: yes; mso-bidi-font-size: 10.5pt">这段代码在一般情况下是运行正确的，对于手机与手机的发送是不存在问题的，但是与<span lang=EN-US>SP</span>的交互在某些省区就存在短信发送不出去的情况。<span lang=EN-US><o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span style="FONT-FAMILY: 新宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-no-proof: yes; mso-bidi-font-size: 10.5pt">为了更好的理解这段代码，我们先来熟悉一下<span lang=EN-US style="COLOR: black">SmsSendMessage</span><span style="COLOR: black">及各个参数。<span lang=EN-US><o:p></o:p></span></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt; mso-char-indent-count: 2.0"><span lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 新宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-no-proof: yes">SmsSendMessage<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18.05pt; mso-char-indent-count: 2.0"><strong style="mso-bidi-font-weight: normal"><span style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 新宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-no-proof: yes">功能</span></strong><span style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 新宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-no-proof: yes">：</span><span lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: 新宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-no-proof: yes">Use the SmsSendMessage function to create and send an Short Message Service (SMS) message.</span><span style="FONT-SIZE: 9pt; FONT-FAMILY: 新宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-no-proof: yes">（创建和发送短信，但短信发送后并不保存到发件箱中）<span lang=EN-US style="COLOR: black"><o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18.05pt; mso-char-indent-count: 2.0"><strong style="mso-bidi-font-weight: normal"><span style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 新宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-no-proof: yes">原型</span></strong><span style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 新宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-no-proof: yes">：<span lang=EN-US><o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt; mso-char-indent-count: 2.0"><span lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: 新宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-no-proof: yes">HRESULT SmsSendMessage (<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt; mso-char-indent-count: 2.0"><span lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: 新宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-no-proof: yes">const SMS_HANDLE smshHandle, // </span><span style="FONT-SIZE: 9pt; FONT-FAMILY: 新宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-no-proof: yes">调用<span lang=EN-US>SmsOpen</span>时获得的短信句柄<span lang=EN-US><o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt; mso-char-indent-count: 2.0"><span lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: 新宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-no-proof: yes">const SMS_ADDRESS * const psmsaSMSCAddress, //</span><span style="FONT-SIZE: 9pt; FONT-FAMILY: 新宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-no-proof: yes">指向短信中心号码的地址<span lang=EN-US><o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt; mso-char-indent-count: 2.0"><span lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: 新宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-no-proof: yes">const SMS_ADDRESS * const psmsaDestinationAddress, // </span><span style="FONT-SIZE: 9pt; FONT-FAMILY: 新宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-no-proof: yes">发送的目的地址<span lang=EN-US><o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt; mso-char-indent-count: 2.0"><span lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: 新宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-no-proof: yes">const SYSTEMTIME * const pstValidityPeriod, // </span><span style="FONT-SIZE: 9pt; FONT-FAMILY: 新宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-no-proof: yes">发送时间的有效期<span lang=EN-US><o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt; mso-char-indent-count: 2.0"><span lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: 新宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-no-proof: yes">const BYTE * const pbData, // </span><span style="FONT-SIZE: 9pt; FONT-FAMILY: 新宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-no-proof: yes">信息的内容部分<span lang=EN-US><o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt; mso-char-indent-count: 2.0"><span lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: 新宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-no-proof: yes">const DWORD dwDataSize,// </span><span style="FONT-SIZE: 9pt; FONT-FAMILY: 新宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-no-proof: yes">信息内容的长度<span lang=EN-US><o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt; mso-char-indent-count: 2.0"><span lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: 新宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-no-proof: yes">const BYTE * const pbProviderSpecificData, //</span><span style="FONT-SIZE: 9pt; FONT-FAMILY: 新宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-no-proof: yes">运营商的附加数据<span lang=EN-US><o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt; mso-char-indent-count: 2.0"><span lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: 新宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-no-proof: yes">const DWORD dwProviderSpecificDataSize, // </span><span style="FONT-SIZE: 9pt; FONT-FAMILY: 新宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-no-proof: yes">附加数据的长度<span lang=EN-US><o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt; mso-char-indent-count: 2.0"><span lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: 新宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-no-proof: yes">const SMS_DATA_ENCODING smsdeDataEncoding, // </span><span style="FONT-SIZE: 9pt; FONT-FAMILY: 新宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-no-proof: yes">短信编码<span lang=EN-US><o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt; mso-char-indent-count: 2.0"><span lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: 新宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-no-proof: yes">const DWORD dwOptions, // </span><span style="FONT-SIZE: 9pt; FONT-FAMILY: 新宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-no-proof: yes">其他选项<span lang=EN-US><o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt; mso-char-indent-count: 2.0"><span lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: 新宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-no-proof: yes">SMS_MESSAGE_ID * psmsmidMessageID); // </span><span style="FONT-SIZE: 9pt; FONT-FAMILY: 新宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-no-proof: yes">用于得到系统回执的信息<span lang=EN-US><o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt; mso-char-indent-count: 2.0"><span style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 新宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-no-proof: yes">（具体介绍可查看<span lang=EN-US>http://msdn.microsoft.com/en-us/library/aa455068.aspx</span>）<span lang=EN-US><o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span style="COLOR: black; FONT-FAMILY: 新宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-no-proof: yes; mso-bidi-font-size: 10.5pt">在实际应用中短信发送不出去，但是<span lang=EN-US>SmsSendMessage</span>的返回值是<span lang=EN-US>S_OK</span>值。在一些文章中有人这样认为是短信编码的问题造成的。<span lang=EN-US><o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span style="COLOR: black; FONT-FAMILY: 新宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-no-proof: yes; mso-bidi-font-size: 10.5pt">如果编码格式不对可能造成短信中心网关把短信给吞掉的情况，程序虽然调用成功，但是就是目标号码收不到短信。函数参数中的后三个参数可以不用或设默认值都可以。<span lang=EN-US><o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span style="COLOR: black; FONT-FAMILY: 新宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-no-proof: yes; mso-bidi-font-size: 10.5pt">起初我也是认为这个地方造成的，很是兴奋。短信的回复内容恰为字母，我误以为短信内容此时是<span lang=EN-US>7-BIT</span>的短消息，短信网关把短信给吞掉了，造成目标号码收不到短信。在练习中却也阴差阳错的成功了。很高兴的把理由归到了这个地方。并这样总结：</span><span lang=EN-US style="FONT-FAMILY: 新宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-no-proof: yes; mso-bidi-font-size: 10.5pt">SmsSendMessage</span><span style="FONT-FAMILY: 新宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-no-proof: yes; mso-bidi-font-size: 10.5pt">可以支持<span lang=EN-US>7-bit</span>的<span lang=EN-US>ASCII</span>码的短消息，也支持<span lang=EN-US>16-bit</span>的<span lang=EN-US>unicode</span>的短消息。但内容为<span lang=EN-US>ASCII</span>的时候，短信编码为<span lang=EN-US style="COLOR: black"> SMSDE_GSM</span><span style="COLOR: black">或<span lang=EN-US>SMSDE_OPTIMAL</span>，当内容不全是</span><span lang=EN-US>ASCII</span>的时候，短信编码为<span lang=EN-US style="COLOR: black">SMSDE_GSM</span><span style="COLOR: black">或<span lang=EN-US>SMSDE_OPTIMAL</span>。所以回复内容改为汉字即可。<span lang=EN-US><o:p></o:p></span></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span style="COLOR: black; FONT-FAMILY: 新宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-no-proof: yes; mso-bidi-font-size: 10.5pt">但是这样对么？起初我认为我的解释很合理<span lang=EN-US>.</span>但是我却发现我的一个参数与原来的程序不一样<span lang=EN-US>.<o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span style="COLOR: black; FONT-FAMILY: 新宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-no-proof: yes; mso-bidi-font-size: 10.5pt">是我在尝试中无意修改了一个参数<span lang=EN-US>,</span>将<span lang=EN-US><o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span lang=EN-US style="COLOR: black; FONT-FAMILY: 新宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-no-proof: yes; mso-bidi-font-size: 10.5pt">tpsd</span><span lang=EN-US style="FONT-FAMILY: 新宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-no-proof: yes; mso-bidi-font-size: 10.5pt">.<span style="COLOR: black">psMessageClass</span> = <span style="COLOR: black">PS_MESSAGE_CLASS1</span>;<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span style="FONT-FAMILY: 新宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-no-proof: yes; mso-bidi-font-size: 10.5pt">修改为了<span lang=EN-US><o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span lang=EN-US style="COLOR: black; FONT-FAMILY: 新宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-no-proof: yes; mso-bidi-font-size: 10.5pt">tpsd</span><span lang=EN-US style="FONT-FAMILY: 新宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-no-proof: yes; mso-bidi-font-size: 10.5pt">.<span style="COLOR: black">psMessageClass</span> = <span style="COLOR: black">PS_MESSAGE_CLASSUNSPECIFIED;<o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span style="COLOR: black; FONT-FAMILY: 新宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-no-proof: yes; mso-bidi-font-size: 10.5pt">这是发送短信中的运营商的指定数据</span><span lang=EN-US style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 新宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-no-proof: yes">TEXT_PROVIDER_SPECIFIC_DATA</span><span lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: 新宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-no-proof: yes">,</span><span style="FONT-SIZE: 9pt; FONT-FAMILY: 新宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-no-proof: yes">它的参数</span><span lang=EN-US style="COLOR: black; FONT-FAMILY: 新宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-no-proof: yes; mso-bidi-font-size: 10.5pt">psMessageClass</span><span style="COLOR: black; FONT-FAMILY: 新宋体; mso-hansi-font-family: 'Times New Roman'; mso-font-kerning: 0pt; mso-no-proof: yes; mso-bidi-font-size: 10.5pt">是指<span lang=EN-US><o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span lang=EN-US>Text Short Message Service (SMS) messages with the appropriate flag can replace previously received notifications with a similar flag and originating address.</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">它有以下五个值</span><span lang=EN-US>:</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span lang=EN-US>PS_MESSAGE_CLASS0: The message should be displayed immediately but not stored. The MS shall send an acknowledgement to the service center when the message has successfully reached the MS. </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">（被接受后立即显示但不存储</span><span lang=EN-US>(</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">称为闪信</span><span lang=EN-US>)</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。需要向</span><span lang=EN-US>SMSC</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">发送确认信息。）</span><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span lang=EN-US>PS_MESSAGE_CLASS1</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">：</span><span lang=EN-US>The message should be stored and an acknowledgement should be sent to the <st1:place w:st="on"><st1:placename w:st="on">Service</st1:placename> <st1:placetype w:st="on">Center</st1:placetype></st1:place> when it is stored.</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">（接收后被存储，一旦存储，需要向</span><span lang=EN-US>SMSC</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">发送确认信息。）</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span lang=EN-US>PS_MESSAGE_CLASS2</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">：</span><span lang=EN-US>The message should be transferred to the SMS data field in the subscriber identity module (SIM) before an acknowledgement is sent to the <st1:place w:st="on"><st1:placename w:st="on">Service</st1:placename> <st1:placetype w:st="on">Center</st1:placetype></st1:place>. </span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span lang=EN-US>PS_MESSAGE_CLASS3</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">：</span><span lang=EN-US>When the message has successfully reached the destination and can be stored, an acknowledgement is sent to the <st1:place w:st="on"><st1:placename w:st="on">Service</st1:placename> <st1:placetype w:st="on">Center</st1:placetype></st1:place>.</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; TEXT-ALIGN: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align=left><span lang=EN-US>PS_MESSAGE_CLASSUNSPECIFIED</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">：</span><span lang=EN-US>The message Class is not set in the outgoing or incoming message. </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">（对发出或收到的短信不进行设置）</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; TEXT-ALIGN: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align=left><span lang=EN-US><o:p>&nbsp;</o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; TEXT-ALIGN: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align=left><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">分析以上五个值，前四个值有一个共同的特点，都需要向</span><span lang=EN-US>SMSC</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">发送确认。而最后一个值没有设定。</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; TEXT-ALIGN: left; mso-char-indent-count: 2.0; mso-pagination: widow-orphan" align=left><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个值的改动，解决了我所遇到的问题。但究其原因,我有些想不通为什么?<br>&nbsp;&nbsp;&nbsp; 但是在实际应用中，出现了</span><span lang=EN-US>tmail.exe</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的异常。不知道是这个值的变动带来的问题，还是实际模块中存在的问题。还需要继续研究一下。<br><br>如果大家有知道的,给些建议哈.</span></p>
<img src ="http://www.cppblog.com/SpringSnow/aggbug/76107.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/SpringSnow/" target="_blank">Sandy</a> 2009-03-10 14:14 <a href="http://www.cppblog.com/SpringSnow/archive/2009/03/10/76107.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于mobile的内存释放</title><link>http://www.cppblog.com/SpringSnow/archive/2009/03/05/75612.html</link><dc:creator>Sandy</dc:creator><author>Sandy</author><pubDate>Thu, 05 Mar 2009 05:56:00 GMT</pubDate><guid>http://www.cppblog.com/SpringSnow/archive/2009/03/05/75612.html</guid><wfw:comment>http://www.cppblog.com/SpringSnow/comments/75612.html</wfw:comment><comments>http://www.cppblog.com/SpringSnow/archive/2009/03/05/75612.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/SpringSnow/comments/commentRss/75612.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/SpringSnow/services/trackbacks/75612.html</trackback:ping><description><![CDATA[<p>前阶段在调研mobile上的内存释放问题，根据大家的建议尝试了一些，但是没有什么效果。<br>于是跑到MSDN上去问相关的问题，得到了一些解答。<br><br>As far as I know, I don't think there is other way to meet your requirement.&nbsp; Since each mobile application has 32M memory limitation, we have to do the performance manually, like deleting object which is not used and&nbsp;allocating Large Memory Blocks in Large memory Area.<br><br>For more information:<br><a href="http://msdn.microsoft.com/en-us/library/ms836325.aspx" target=_blank><font color=#0072bc>Windows CE .NET Advanced Memory Management</font></a><br><a href="http://blogs.msdn.com/windowsmobile/archive/2006/08/16/702746.aspx" target=_blank><font color=#0072bc>How the Windows Mobile 5.0 Shell Handles Low Memory Situations</font></a><br><br>我看了一部分，在<a href="http://blogs.msdn.com/windowsmobile/archive/2006/08/16/702746.aspx" target=_blank><font color=#0072bc><u>How the Windows Mobile 5.0 Shell Handles Low Memory Situations</u></font></a>中提到，<br></p>
<div>
<p>&nbsp;</p>
<p><a href="http://blogs.msdn.com/photos/wmshell/picture607242.aspx" target=_blank><img src="http://blogs.msdn.com/photos/wmshell/images/607242/original.aspx" border=0></a></p>
<p>&nbsp;</p>
<p><strong>Hibernate</strong></p>
<p>This is the amount of memory the shell tries to keep free at all times. If the amount of free memory falls below this value then the low memory check routine will try to free up memory. It will do this by first sending <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wceshellui5/html/wce50lrfwmhibernate.asp">WM_HIBERNATE</a> to all <a href="http://blogs.msdn.com/windowsmobile/archive/2006/08/16/702746.aspx#Valid_Application">valid</a> applications. When an application receives this message it should try to free as many resources as possible. When the low memory check routine runs again and the amount of free memory is still below the hibernate level then the shell will try to close the least recently used (LRU) application by sending a <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wceshellui5/html/wce50lrfwmclose.asp">WM_CLOSE</a> message. If the low memory check routine runs yet again and the amount of free memory is still below the hibernate level then the shell will call <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wcesdkr/html/wcesdkrterminateprocess.asp">TerminateProcess</a> on the LRU application that it last sent the WM_CLOSE message to.</p>
</div>
<p><br>我对这段话的理解是：当空闲内存小于Hibernate时，系统便会尝试释放内存。首先他会向所有有效的程序发送WM_HIBERNATE。应用程序收到该消息后，会尽量释放资源来释放内存。如果还低于这个值的话，将发送WM_CLOSE消息给最近很少使用的程序。如果还低于该值的，就强行关闭该程序了。<br><br>这个方法似乎有效，但是用户再起来程序的话，还是一样的效果，并不是达到了什么释放内存的效果。如何记录最近很少使用的程序，这个是不是有什么方法获得呢？<br><br>就可以像系统提示的那样，内存不足，请释放一些内存。手工做一些比较好。<br><br>也看了一些相近的程序的做法，似乎效果也没有大家说的那么好。<br><br>在<a href="http://blogs.msdn.com/windowsmobile/archive/2006/08/16/702746.aspx" target=_blank><font color=#0072bc><u>How the Windows Mobile 5.0 Shell Handles Low Memory Situations</u></font></a>的最后，这样写的<br></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt"><strong>What can my Application do?</strong></p>
<p class=MsoNormal style="MARGIN: 0in 0in 0pt">The best thing your application can do when faced with a low memory situation is to play nicely with the rest of the device.&nbsp;<br><br>1、If your application receives a <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wceshellui5/html/wce50lrfwmhibernate.asp">WM_HIBERNATE</a> message free up any resources not absolutely required.&nbsp;<br>2、If you are planning on allocating a large amount of memory (or if a large allocation fails)&nbsp;you should call <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wceshellui5/html/wce50lrfshcloseapps.asp">SHCloseApps</a>, which will invoke the shell low memory check routine and will try to ensure that enough free memory exists. See below for an example:<o:p><span style="FONT-FAMILY: 'Courier New'; mso-bidi-font-weight: bold"><font size=2></p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">#define</span><span style="COLOR: #000000">&nbsp;MIN_MEMORY_TO_RUN&nbsp;2*1024*1024</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>MEMORYSTATUS&nbsp;mst;<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>mst.dwLength&nbsp;&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">sizeof</span><span style="COLOR: #000000">(MEMORYSTATUS);<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>GlobalMemoryStatus(</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">mst);<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>If&nbsp;(mst.dwAvailPhys&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">&nbsp;MIN_MEMORY_TO_RUN)<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img id=Codehighlighter1_166_349_Open_Image onclick="this.style.display='none'; Codehighlighter1_166_349_Open_Text.style.display='none'; Codehighlighter1_166_349_Closed_Image.style.display='inline'; Codehighlighter1_166_349_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_166_349_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_166_349_Closed_Text.style.display='none'; Codehighlighter1_166_349_Open_Image.style.display='inline'; Codehighlighter1_166_349_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_166_349_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_166_349_Open_Text><span style="COLOR: #000000">{<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;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;Try&nbsp;to&nbsp;free&nbsp;memory&nbsp;by&nbsp;asking&nbsp;Shell&nbsp;to&nbsp;shutdown&nbsp;apps</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></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">if</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">SHCloseApps(MIN_MEMORY_TO_RUN))<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img id=Codehighlighter1_275_349_Open_Image onclick="this.style.display='none'; Codehighlighter1_275_349_Open_Text.style.display='none'; Codehighlighter1_275_349_Closed_Image.style.display='inline'; Codehighlighter1_275_349_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_275_349_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_275_349_Closed_Text.style.display='none'; Codehighlighter1_275_349_Open_Image.style.display='inline'; Codehighlighter1_275_349_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_275_349_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_275_349_Open_Text><span style="COLOR: #000000">{<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;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;Handle&nbsp;the&nbsp;case&nbsp;where&nbsp;memory&nbsp;could&nbsp;not&nbsp;be&nbsp;freed</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8230;<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></span></div>
<p></span></span></font></span></o:p><o:p></p>
<br>专门查了一下<a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wceshellui5/html/wce50lrfshcloseapps.asp">SHCloseApps</a>的用法<br><strong>原型：BOOL <font style="BACKGROUND-COLOR: #3399fe" color=#ffffff>SHCloseApps</font>(</strong><strong>&nbsp; DWORD </strong><em><a class=synParam onclick=showTip(this) href=""><u><font color=#0000ff>dwMemSought</font></u></a></em><strong>);<br>功能：</strong>This function tries to free up memory for an application. If necessary, the shell closes down other applications by sending <a href="http://www.cppblog.com/SpringSnow/admin/href_cetemp=" ?><u><font color=#0000ff>dwMemSought</font></u></a></em><strong>);<br>功能：</strong>This function tries to free up memory for an application. If necessary, the shell closes down other applications by sending <a href="mk:@MSITStore:F:\保存资料\Magneto%20Documentation%20September%2027,%202005.chm::/html/wce50lrfwmclose.htm">WM_CLOSE</a> messages.<br>参数：<a class=synParam onclick=showTip(this) href=""><u><font color=#0000ff><em>dwMemSought</em></font></u></a>&nbsp;Specifies, in bytes, the amount of memory to be freed.<br><br>通过了解<a href="http://www.cppblog.com/SpringSnow/admin/href_cetemp=" ?><u><font color=#0000ff><em>dwMemSought</em></font></u></a>&nbsp;Specifies, in bytes, the amount of memory to be freed.<br><br>通过了解<a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wceshellui5/html/wce50lrfshcloseapps.asp">SHCloseApps</a>，我们就明白了上面那段代码什么意思了。<br><br>看来，内存释放并不是真正意义上的内存整理，看来我有的地方误解了！</o:p> 
<img src ="http://www.cppblog.com/SpringSnow/aggbug/75612.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/SpringSnow/" target="_blank">Sandy</a> 2009-03-05 13:56 <a href="http://www.cppblog.com/SpringSnow/archive/2009/03/05/75612.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>wcsicmp 字符串比较</title><link>http://www.cppblog.com/SpringSnow/archive/2009/03/03/75443.html</link><dc:creator>Sandy</dc:creator><author>Sandy</author><pubDate>Tue, 03 Mar 2009 10:49:00 GMT</pubDate><guid>http://www.cppblog.com/SpringSnow/archive/2009/03/03/75443.html</guid><wfw:comment>http://www.cppblog.com/SpringSnow/comments/75443.html</wfw:comment><comments>http://www.cppblog.com/SpringSnow/archive/2009/03/03/75443.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/SpringSnow/comments/commentRss/75443.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/SpringSnow/services/trackbacks/75443.html</trackback:ping><description><![CDATA[今天在写的程序的时候,遇到字符串比较.<br><br>但是字符串可能会有大小写的区别,此时怎么办呢?忽略大小写进行比较.<br><br>利用wcsicmp就比较好, 它将字符串转换成小写字符串进行比较,这样就忽略了大小写的情况.
<img src ="http://www.cppblog.com/SpringSnow/aggbug/75443.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/SpringSnow/" target="_blank">Sandy</a> 2009-03-03 18:49 <a href="http://www.cppblog.com/SpringSnow/archive/2009/03/03/75443.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>疑问: 如何释放内存??</title><link>http://www.cppblog.com/SpringSnow/archive/2009/02/23/74694.html</link><dc:creator>Sandy</dc:creator><author>Sandy</author><pubDate>Mon, 23 Feb 2009 11:18:00 GMT</pubDate><guid>http://www.cppblog.com/SpringSnow/archive/2009/02/23/74694.html</guid><wfw:comment>http://www.cppblog.com/SpringSnow/comments/74694.html</wfw:comment><comments>http://www.cppblog.com/SpringSnow/archive/2009/02/23/74694.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.cppblog.com/SpringSnow/comments/commentRss/74694.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/SpringSnow/services/trackbacks/74694.html</trackback:ping><description><![CDATA[如何释放内存?<br><br>这里,我不是简单的new后要delete.是对于系统而言,我怎么做到释放内存呢?让系统的可用内存变大.从网上也看到了许多释放内存的软件,很惊异它们是如何做到的呢?<br><br>有人建议我申请一大块控件,系统不够分配了,会引起它自己去整理内存.试了一下,似乎效果不是很好.<br>还有人建议,这么用,向所有窗口发送一个WM_HIBERNAT消息.<br>PostMessage(HWND_BROADCAST, WM_HIBERNATE, 0, 0);<br>似乎效果也不是很好.<br><br>有没有很好的方法处理这个问题呢?<br><br>大家知道的话,指点一下啊!<br><br>万分感谢!
<img src ="http://www.cppblog.com/SpringSnow/aggbug/74694.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/SpringSnow/" target="_blank">Sandy</a> 2009-02-23 19:18 <a href="http://www.cppblog.com/SpringSnow/archive/2009/02/23/74694.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Windows核心编程：第一章错误处理学习笔记</title><link>http://www.cppblog.com/SpringSnow/archive/2009/02/20/74350.html</link><dc:creator>Sandy</dc:creator><author>Sandy</author><pubDate>Thu, 19 Feb 2009 16:24:00 GMT</pubDate><guid>http://www.cppblog.com/SpringSnow/archive/2009/02/20/74350.html</guid><wfw:comment>http://www.cppblog.com/SpringSnow/comments/74350.html</wfw:comment><comments>http://www.cppblog.com/SpringSnow/archive/2009/02/20/74350.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/SpringSnow/comments/commentRss/74350.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/SpringSnow/services/trackbacks/74350.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;过年前，从china-pub买的。一直也没有安下心来读。看今年找工作的境况，也不得不抓把紧了。也愿与c++博客的各位朋友分享我的学习心得。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;步入主题。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;这一章开篇介绍了windows函数的几种返回值：VOID，BOOL，HANDLE，PVOID，LONG/DWORD。让我们明白，仅仅通过返回值，我们是不能清楚函数调用为什么会失败的。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; windows内部，函数检测到错误会采用什么机制呢？它是采用&#8220;线程本地存储区&#8221;的机制来讲相应的错误代码与&#8220;主调线程&#8221;关联到一起。它可以使不同的线程能独立运行，不会出现相互干扰对方的错误代码的情况。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;函数返回的时候，其返回值会指出已发生的一个错误。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;我们查看具体是什么错误，在相应的函数执行完成后调用GetLastError()即可。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;windows中，错误有三种表示：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;一个消息ID（如ERROR_PATH_NOT_FOUND）<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;消息文本（如the system cannot find the path specified）<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;一个编号（尽量避免使用）<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;调试程序的时候，我们可以配置watch窗口，让它始终显示线程的上一个错误代码和错误的文本描述。如$err,hr。hr是要显示错误代码的消息文本。不过我在windows mobile的环境下没有成功，没有弄清楚为什么。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;那么我们怎么在自己的程序中显示消息文本呢？文章介绍了利用FormatMessage函数。这里我也介绍一下这个函数的用法：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;（下面的介绍摘自：<a href="http://www.cppblog.com/bidepan2023/archive/2008/02/03/42433.html">http://www.cppblog.com/bidepan2023/archive/2008/02/03/42433.html</a>）<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #2000ff">DWORD FormatMessage(</span><br style="COLOR: #2000ff"><span style="COLOR: #2000ff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DWORD dwFlags,</span><br style="COLOR: #2000ff"><span style="COLOR: #2000ff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LPCVOID lpSource,</span><br style="COLOR: #2000ff"><span style="COLOR: #2000ff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DWORD dwMessageId,</span><br style="COLOR: #2000ff"><span style="COLOR: #2000ff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DWORD dwLanguageId,</span><br style="COLOR: #2000ff"><span style="COLOR: #2000ff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LPTSTR lpBuffer,</span><br style="COLOR: #2000ff"><span style="COLOR: #2000ff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DWORD nSize,</span><br style="COLOR: #2000ff"><span style="COLOR: #2000ff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; va_list* Arguments</span><br style="COLOR: #2000ff"><span style="COLOR: #2000ff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;);</span><br><br><span style="FONT-WEIGHT: bold">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dwFlags:</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# FORMAT_MESSAGE_ALLOCATE_BUFFER // 此函数会分配内存以包含描述字串。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# FORMAT_MESSAGE_FROM_SYSTEM,&nbsp; // 在系统的id映射表中寻找描述字串<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# FORMAT_MESSAGE_FROM_HMODULE&nbsp; // 在其他资源模块中寻找描述字串<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# FORMAT_MESSAGE_FROM_STRING&nbsp;&nbsp; // 消息ID是个字串，不是个DWORD<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#FORMAT_MESSAGE_IGNORE_INSERTS // 允许我们获得含有%占位符的消息，不传递这个标志，就必须在Arguments参数中提供这些占位符的信息<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;通常为：FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM<br><br><span style="FONT-WEIGHT: bold">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lpSource:</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 指定了FORMAT_MESSAGE_FROM_HMODULE的话，此参数表示模块的HANDLE<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 指定了FORMAT_MESSAGE_FROM_STRING的话，此参数表示id字串<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;通常为：NULL<br><br><span style="FONT-WEIGHT: bold">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dwMessageId:</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;消息ID;如果指定FORMAT_MESSAGE_FROM_STRING，将被忽略。<br><br style="FONT-WEIGHT: bold"><span style="FONT-WEIGHT: bold">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dwLanguageId:</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;消息描述所用的语言<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;通常为：0表示自动选择<br><br><span style="FONT-WEIGHT: bold">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lpBuffer:</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#如果未指定FORMAT_MESSAGE_ALLOCATE_BUFFER，则为自己提供的缓冲区<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#否则为系统LocalAlloc分配，需要被用户LocalFree<br><br><span style="FONT-WEIGHT: bold">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nSize:</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#如果未指定FORMAT_MESSAGE_ALLOCATE_BUFFER，则为自己提供的缓冲区大小<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#否则为系统LocalAlloc分配之最小缓冲区大小<br><br><span style="FONT-WEIGHT: bold">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Arguments:</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;通常不使用 </p>
<p><br>例子：<br></p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;ShowError()<br><img id=Codehighlighter1_17_942_Open_Image onclick="this.style.display='none'; Codehighlighter1_17_942_Open_Text.style.display='none'; Codehighlighter1_17_942_Closed_Image.style.display='inline'; Codehighlighter1_17_942_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_17_942_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_17_942_Closed_Text.style.display='none'; Codehighlighter1_17_942_Open_Image.style.display='inline'; Codehighlighter1_17_942_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_17_942_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_17_942_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;dwError&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;GetLastError();<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;HLOCAL&nbsp;hlocal&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;NULL;<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;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;Use&nbsp;the&nbsp;default&nbsp;system&nbsp;locale&nbsp;since&nbsp;we&nbsp;look&nbsp;for&nbsp;Windows&nbsp;messages.<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;Note:&nbsp;this&nbsp;MAKELANGID&nbsp;combination&nbsp;has&nbsp;0&nbsp;as&nbsp;value</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;systemLocale&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;MAKELANGID(LANG_NEUTRAL,&nbsp;SUBLANG_NEUTRAL);<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;BOOL&nbsp;fOk&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;FormatMessage(<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FORMAT_MESSAGE_FROM_SYSTEM&nbsp;</span><span style="COLOR: #000000">|</span><span style="COLOR: #000000">&nbsp;FORMAT_MESSAGE_IGNORE_INSERTS&nbsp;</span><span style="COLOR: #000000">|</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FORMAT_MESSAGE_ALLOCATE_BUFFER,&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NULL,&nbsp;dwError,&nbsp;systemLocale,&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(PTSTR)&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">hlocal,&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">,&nbsp;NULL);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img id=Codehighlighter1_464_833_Open_Image onclick="this.style.display='none'; Codehighlighter1_464_833_Open_Text.style.display='none'; Codehighlighter1_464_833_Closed_Image.style.display='inline'; Codehighlighter1_464_833_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_464_833_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_464_833_Closed_Text.style.display='none'; Codehighlighter1_464_833_Open_Image.style.display='inline'; Codehighlighter1_464_833_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">fOk)&nbsp;</span><span id=Codehighlighter1_464_833_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_464_833_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;Is&nbsp;it&nbsp;a&nbsp;network-related&nbsp;error?</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HMODULE&nbsp;hDll&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;LoadLibraryEx(TEXT(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">netmsg.dll</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">),&nbsp;NULL,&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DONT_RESOLVE_DLL_REFERENCES);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img id=Codehighlighter1_614_830_Open_Image onclick="this.style.display='none'; Codehighlighter1_614_830_Open_Text.style.display='none'; Codehighlighter1_614_830_Closed_Image.style.display='inline'; Codehighlighter1_614_830_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_614_830_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_614_830_Closed_Text.style.display='none'; Codehighlighter1_614_830_Open_Image.style.display='inline'; Codehighlighter1_614_830_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;(hDll&nbsp;</span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000">&nbsp;NULL)&nbsp;</span><span id=Codehighlighter1_614_830_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_614_830_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fOk&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;FormatMessage(<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FORMAT_MESSAGE_FROM_HMODULE&nbsp;</span><span style="COLOR: #000000">|</span><span style="COLOR: #000000">&nbsp;FORMAT_MESSAGE_IGNORE_INSERTS&nbsp;</span><span style="COLOR: #000000">|</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FORMAT_MESSAGE_ALLOCATE_BUFFER,<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hDll,&nbsp;dwError,&nbsp;systemLocale,<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(PTSTR)&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">hlocal,&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">,&nbsp;NULL);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FreeLibrary(hDll);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><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;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;(fOk&nbsp;</span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000">&nbsp;(hlocal&nbsp;</span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000">&nbsp;NULL))<br><img id=Codehighlighter1_867_940_Open_Image onclick="this.style.display='none'; Codehighlighter1_867_940_Open_Text.style.display='none'; Codehighlighter1_867_940_Closed_Image.style.display='inline'; Codehighlighter1_867_940_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_867_940_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_867_940_Closed_Text.style.display='none'; Codehighlighter1_867_940_Open_Image.style.display='inline'; Codehighlighter1_867_940_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_867_940_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_867_940_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OutputDebugString((PCTSTR)&nbsp;LocalLock(hlocal));<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LocalFree(hlocal);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span></div>
<p><br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;这个是书中的例子的代码，我只是将它归结为了一个函数ErrorShow。这样我们在一个函数的后面调用，直接可以知道错误的原因。不过环境我是在smart device 的DEBUG环境下调时的，OutputDebugString会输出相应的字符串。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;这个例子中同时展示了FormatMessage的两种用法。观察一下第二个参数就明白了。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;visual studio 也提供了一个查询错误的小工具，为Error Lookup。通过以上的示例，我们就知道其相应的工作原理呢。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;这本书的源码的下载地址：<a href="http://wintellect.com/Books.aspx">http://wintellect.com/Books.aspx</a>&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;大家如果对windows 编程感兴趣的话，不妨下来看看。<br></p>
<img src ="http://www.cppblog.com/SpringSnow/aggbug/74350.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/SpringSnow/" target="_blank">Sandy</a> 2009-02-20 00:24 <a href="http://www.cppblog.com/SpringSnow/archive/2009/02/20/74350.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>文件映射的学习</title><link>http://www.cppblog.com/SpringSnow/archive/2009/02/17/74017.html</link><dc:creator>Sandy</dc:creator><author>Sandy</author><pubDate>Tue, 17 Feb 2009 03:55:00 GMT</pubDate><guid>http://www.cppblog.com/SpringSnow/archive/2009/02/17/74017.html</guid><wfw:comment>http://www.cppblog.com/SpringSnow/comments/74017.html</wfw:comment><comments>http://www.cppblog.com/SpringSnow/archive/2009/02/17/74017.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/SpringSnow/comments/commentRss/74017.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/SpringSnow/services/trackbacks/74017.html</trackback:ping><description><![CDATA[最近在调研文件相关的东西,如MD5值.但是文件有可能很大,所以我们不能一次读出文件.有人建议用文件映射.查了一下文件映射的内容.记录下来.<br>　摘自:http://www.yesky.com/405/1756405.shtml<br><br><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 摘要：</strong> 本文通过内存映射文件的使用来对大尺寸文件进行访问操作，同时也对内存映射文件的相关概念和一般编程过程作了较为详细的介绍。<br><br>　　关键词： 内存映射文件；大文件处理；分配粒度 <br><br>　　<strong>引言</strong><br><br>　　文件操作是应用<a class=bluekey href="http://dev.yesky.com/" target=_blank><font color=#204890>程序</font></a>最为基本的功能之一，Win32 API和MFC均提供有支持文件处理的函数和类，常用的有Win32 API的CreateFile()、WriteFile()、ReadFile()和MFC提供的CFile类等。一般来说，以上这些函数可以满足大多数场合的要求，但是对于某些特殊应用领域所需要的动辄几十GB、几百GB、乃至几TB的海量存储，再以通常的文件处理方法进行处理显然是行不通的。目前，对于上述这种大文件的操作一般是以内存映射文件的方式来加以处理的，本文下面将针对这种Windows核心编程技术展开讨论。<br><br>　　<strong>内存映射文件概述</strong><br><br>　　内存文件映射也是Windows的一种内存管理方法，提供了一个统一的内存管理特征，使应用程序可以通过内存指针对磁盘上的文件进行访问，其过程就如同对加载了文件的内存的访问。通过文件映射这种使磁盘文件的全部或部分内容与进程虚拟地址空间的某个区域建立映射关联的能力，可以直接对被映射的文件进行访问，而不必执行文件I/O操作也无需对文件内容进行缓冲处理。内存文件映射的这种特性是非常适合于用来管理大尺寸文件的。<br><br>　　在使用内存映射文件进行I/O处理时，系统对数据的传输按页面来进行。至于内部的所有内存页面则是由虚拟内存管理器来负责管理，由其来决定内存页面何时被分页到磁盘，哪些页面应该被释放以便为其它进程提供空闲空间，以及每个进程可以拥有超出实际分配物理内存之外的多少个页面空间等等。由于虚拟内存管理器是以一种统一的方式来处理所有磁盘I/O的（以页面为单位对内存数据进行读写），因此这种优化使其有能力以足够快的速度来处理内存操作。<br><br>　　使用内存映射文件时所进行的任何实际I/O交互都是在内存中进行并以标准的内存地址形式来访问。磁盘的周期性分页也是由<a class=bluekey href="http://os.yesky.com/" target=_blank><font color=#204890>操作系统</font></a>在后台隐蔽实现的，对应用程序而言是完全透明的。内存映射文件的这种特性在进行大文件的磁盘事务操作时将获得很高的效益。<br><br>　　需要说明的是，在系统的正常的分页操作过程中，内存映射文件并非一成不变的，它将被定期更新。如果系统要使用的页面目前正被某个内存映射文件所占用，系统将释放此页面，如果页面数据尚未保存，系统将在释放页面之前自动完成页面数据到磁盘的写入。<br><br>　　对于使用页虚拟存储管理的Windows操作系统，内存映射文件是其内部已有的内存管理组件的一个扩充。由可执行代码页面和数据页面组成的应用程序可根据需要由操作系统来将这些页面换进或换出内存。如果内存中的某个页面不再需要，操作系统将撤消此页面原拥用者对它的控制权，并释放该页面以供其它进程使用。只有在该页面再次成为需求页面时，才会从磁盘上的可执行文件重新读入内存。同样地，当一个进程初始化启动时，内存的页面将用来存储该应用程序的静态、动态数据，一旦对它们的操作被提交，这些页面也将被备份至系统的页面文件，这与可执行文件被用来备份执行代码页面的过程是很类似的。图1展示了代码页面和数据页面在磁盘存储器上的备份过程：<br><br><img onerror="this.src='http://www.yesky.com/image20010518/95741.jpg';" hspace=3 src="http://www.yesky.com/image20010518/95741.jpg" align=center vspace=1 border=1><br>图1 进程的代码页、数据页在磁盘存储器上的备份<br><br>　　显然，如果可以采取同一种方式来处理代码和数据页面，无疑将会提高程序的执行效率，而内存映射文件的使用恰恰可以满足此需求。<br><strong>对大文件的管理<br><br></strong>　　内存映射文件对象在关闭对象之前并没有必要撤销内存映射文件的所有视图。在对象被释放之前，所有的脏页面将自动写入磁盘。通过CloseHandle（）关闭内存映射文件对象，只是释放该对象，如果内存映射文件代表的是磁盘文件，那么还需要调用标准文件I/O函数来将其关闭。在处理大文件处理时，内存映射文件将表示出卓越的优势，只需要消耗极少的物理资源，对系统的影响微乎其微。下面先给出内存映射文件的一般编程流程框图：<br><br><img onerror="this.src='http://www.yesky.com/image20010518/95743.jpg';" hspace=3 src="http://www.yesky.com/image20010518/95743.jpg" align=center vspace=1 border=1><br>图2 使用内存映射文件的一般流程<br><br>　　而在某些特殊行业，经常要面对十几GB乃至几十GB容量的巨型文件，而一个32位进程所拥有的虚拟地址空间只有232 = 4GB，显然不能一次将文件映像全部映射进来。对于这种情况只能依次将大文件的各个部分映射到进程中的一个较小的地址空间。这需要对上面的一般流程进行适当的更改：<br><br>　　1）映射文件开头的映像。<br><br>　　2）对该映像进行访问。<br><br>　　3）取消此映像<br><br>　　4）映射一个从文件中的一个更深的位移开始的新映像。<br><br>　　5）重复步骤2，直到访问完全部的文件数据。<br><br>　　下面给出一段根据此描述而写出的对大于4GB的文件的处理代码：<br><br>
<table width="100%" bgColor=#ffffff>
    <tbody>
        <tr>
            <td>// 选择文件<br>CFileDialog fileDlg(TRUE, "*.txt", "*.txt", NULL, "文本文件 (*.txt)|*.txt||", this);<br>fileDlg.m_ofn.Flags |= OFN_FILEMUSTEXIST;<br>fileDlg.m_ofn.lpstrTitle = "通过内存映射文件读取数据";<br>if (fileDlg.DoModal() == IDOK)<br>{<br>　// 创建文件对象<br>　HANDLE hFile = CreateFile(fileDlg.GetPathName(), GENERIC_READ | GENERIC_WRITE,<br>　　　0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);<br>　if (hFile == INVALID_HANDLE_VALUE)<br>　{<br>　　TRACE("创建文件对象失败,错误代码:%d\r\n", GetLastError());<br>　　return;<br>　}<br>　// 创建文件映射对象<br>　HANDLE hFileMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0, NULL);<br>　if (hFileMap == NULL)<br>　{<br>　　TRACE("创建文件映射对象失败,错误代码:%d\r\n", GetLastError());<br>　　return;<br>　}<br>　// 得到系统分配粒度<br>　SYSTEM_INFO SysInfo;<br>　GetSystemInfo(&amp;SysInfo);<br>　DWORD dwGran = SysInfo.dwAllocationGranularity;<br>　// 得到文件尺寸<br>　DWORD dwFileSizeHigh;<br>　__int64 qwFileSize = GetFileSize(hFile, &amp;dwFileSizeHigh);<br>　qwFileSize |= (((__int64)dwFileSizeHigh) &lt;&lt; 32);<br>　// 关闭文件对象<br>　CloseHandle(hFile);<br>　// 偏移地址 <br>　__int64 qwFileOffset = 0;<br>　// 块大小<br>　DWORD dwBlockBytes = 1000 * dwGran;<br>　if (qwFileSize &lt; 1000 * dwGran)<br>　　dwBlockBytes = (DWORD)qwFileSize;<br>　　while (qwFileOffset &gt; 0)<br>　　{<br>　　　// 映射视图<br>　　　LPBYTE lpbMapAddress = (LPBYTE)MapViewOfFile(hFileMap,FILE_MAP_ALL_ACCESS, <br>　　　　　　(DWORD)(qwFileOffset &gt;&gt; 32), (DWORD)(qwFileOffset &amp; 0xFFFFFFFF),<br>　　　　　　dwBlockBytes);<br>　　　if (lpbMapAddress == NULL)<br>　　　{<br>　　　　TRACE("映射文件映射失败,错误代码:%d\r\n", GetLastError());<br>　　　　return;<br>　　　}<br>　　　// 对映射的视图进行访问<br>　　　for(DWORD i = 0; i &lt; dwBlockBytes; i++)<br>　　　　BYTE temp = *(lpbMapAddress + i);<br>　　　　// 撤消文件映像<br>　　　　UnmapViewOfFile(lpbMapAddress);<br>　　　　// 修正参数<br>　　　　qwFileOffset += dwBlockBytes;<br>　　　　qwFileSize -= dwBlockBytes;<br>　　}<br>　　// 关闭文件映射对象句柄<br>　　CloseHandle(hFileMap);<br>　　AfxMessageBox("成功完成对文件的访问");<br>}</td>
        </tr>
    </tbody>
</table>
<br>　　在本例中，首先通过GetFileSize（）得到被处理文件长度（64位）的高32位和低32位值。然后在映射过程中设定每次映射的块大小为1000倍的分配粒度，如果文件长度小于1000倍的分配粒度时则将块大小设置为文件的实际长度。在处理过程中由映射、访问、撤消映射构成了一个循环处理。其中，每处理完一个文件块后都通过关闭文件映射对象来对每个文件块进行整理。CreateFileMapping（）、MapViewOfFile（）等函数是专门用来进行内存文件映射处理用的。<br><br>　下面分别对这些关键函数进行说明：<br><br>　　<strong>1）CreateFile（）：</strong>CreateFile（）函数是一个用途非常广泛的函数， 在这里的用法并没有什么特殊的地方，但有几点需要注意：一是访问模式参数dwDesiredAccess。该参数设置了对文件内核对象的访问类型，其允许设置的权限可以为读权限GENERIC_READ、写权限GENERIC_WRITE、读写权限GENERIC_READ | GENERIC_WRITE和设备查询权限0。在使用映射文件时，只能打开那些具有可读访问权限的文件，即只能应用GENERIC_READ和GENERIC_READ | GENERIC_WRITE这两种组合；另一点需要注意的是共享模式参数dwShareMode。该参数定义了对文件内核对象的共享方式，其可能的设置为FILE_SHARE_READ、FILE_SHARE_WRITE和0，并可对其组合使用。其中，设置为0时不允许共享对象；FILE_SHARE_READ和FILE_SHARE_WRITE分别为在要求只读、只写访问的情况下才允许对象的共享。<br><br>　　由于通过内存映射文件可以在多个进程间共享数据，因此在进行这种应用时应当考虑dwShareMode参数设置对运行结果的影响。<br><br>　　<strong>2）CreateFileMapping（）：</strong>该函数的作用是创建一个文件映射内核对象，以告知系统文件映射对象需要多大的物理存储器。创建内存映射文件对象对系统资源几乎没有什么影响，也不会影响进程的虚拟地址空间。除了需要用来表示该对象的内部资源之外通常并不用为其分配虚拟内存，但是如果内存映射文件对象是作共享内存之用的话，就要在创建对象时由系统为内存映射文件的使用在系统页文件中保留足够的空间。<br><br>　　函数第一个参数hFile为标识要映射到进程的地址空间的文件的句柄。虽然由于内存映射文件的物理存储器是来自于磁盘上的文件，而非系统的页文件，使创建内存映射文件就像保留一个地址空间区域并将物理存储器提交给该区域一样。第二个参数为指向文件映射内核对象的SECURITY_ATTRIBUTES结构的指针，由此来决定子进程能否继承得到返回的句柄。通常为其传递NULL值，以默认的<a class=bluekey href="http://soft.yesky.com/security/" target=_blank><font color=#204890>安全</font></a>属性来禁止返回句柄的被继承。<br><br>　　接下来的参数用于文件被映射后设定文件映像的保护属性。其可能的取值为PAGE_READONLY、PAGE_READWRITE和PAGE_WRITECOPY。虽然在创建文件映射对象时，系统并不为其保留地址空间区域，也不将文件的存储器映射到该区域。但是，在系统将存储器映射到进程的地址空间中去时，系统必须确切知道应赋予物理存储器页面的保护属性。在设置保护属性时，必须与用CreateFile（）函数打开文件时所指定的访问标识相匹配，否则将导致CreateFileMapping（）的执行失败。因此这里设置PAGE_READWRITE属性。除了上述三个页面保护属性外，还有4个区（Section）保护属性也可以一起组合使用：<br><br>
<table cellSpacing=0 width="100%" border=1>
    <tbody>
        <tr>
            <td>区保护属性</td>
            <td>说明</td>
        </tr>
        <tr>
            <td>SEC_COMMIT</td>
            <td>为区中的所有页面在内存中或磁盘页面文件中分配物理存储器</td>
        </tr>
        <tr>
            <td>SEC_IMAGE</td>
            <td>告知系统，映射的文件是一个可移植的EXE文件映像</td>
        </tr>
        <tr>
            <td>SEC_NOCACHE</td>
            <td>告知系统，未将文件的任何内存映射文件放入高速缓存，多供<a class=bluekey href="http://diy.yesky.com/" target=_blank><font color=#204890>硬件</font></a>设备驱动<a class=bluekey href="http://dev.yesky.com/" target=_blank><font color=#204890>程序</font></a>开发人员使用</td>
        </tr>
        <tr>
            <td>SEC_RESERVE</td>
            <td>对一个区的所有页面进行保留而不分配物理存储器</td>
        </tr>
    </tbody>
</table>
<br>　　后面的两个参数指定了要创建的文件映射对象的最大字节数的高32位值和低32位值，实际也就设定了文件的最大字节数（最大可以处理16EB的文件）。这两个参数可以满足确保文件映射对象能够得到足够的物理存储器这一基本条件。在参数设置的大小小于文件实际大小时，系统将从文件映射指定的字节数。这里将其设置为0，将使所创建的文件映射对象将为文件的当前大小，以上两种情况均无法改变文件的大小。如果设置的参数大于文件的实际大小，系统将会在CreateFileMapping（）函数返回前扩展该文件。需要指出的是，文件映射对象的大小是静态的，一旦创建完毕后将无法更改。如果设置的文件映射对象尺寸偏小将导致无法对文件进行全面的访问。<br><br>　　在本节开始也曾提到过，创建文件映射对象是不需要花费什么系统资源的，因此遵循"宁多勿缺"的原则，一般应将文件映射对象的大小设置为文件大小的相同值。函数最后的参数将可以为映射对象命名。如果想打开一个已存在的文件映射对象，该对象必须要命名。对该名字字符串的要求仅限于未被其它对象使用过的名字即可。<br><br>　　CreateFileMapping（）在成功执行后将返回一个指向文件映射对象的句柄。如果对一个已经存在的文件映射对象调用了CreateFileMapping（）函数，进程将得到一个指向现有映射对象的句柄。通过调用GetLastError（）可以得到返回值ERROR_ALREADY_EXIST，由此可以判断当前得到的内存映射对象句柄是新创建的还是打开已经存在的。如果系统无法创建文件映射对象，将导致CreateFileMapping（）的执行失败，返回N U L L句柄值。<br><br><strong>3）MapViewOfFile（）：</strong>当创建了一个内存映射文件对象并得到其有效句柄后，该句柄即可用来在进程的虚拟地址空间中映射文件的一个映像。在内存映射文件对象已经存在的情况下，映像可被任意映射或取消映射。在文件映像被映射时，仍然必须由系统来为文件的数据保留一个地址空间区域，并将文件的数据作为映射到该区域的物理存储器进行提交。在进程的地址空间中，一个足够大的连续地址空间（通常足以覆盖整个文件映像）将被指定给此文件映像。尽管如此，内存的物理页面还是根据在实际使用中的需求而进行分配的。真正分配一个对应于内存映射文件映像页面的物理内存页面是在发生该页的缺页中断时进行的，这将在第一次读写内存页面中的任一地址时自动完成。MapViewOfFile（）即负责映射内存映射文件的一个映像，<br><br>　　函数的第一个参数为CreateFileMapping（）所返回的内存映射文件对象句柄，第二个参数指定了对文件映像的访问类型，可能取值有FILE_MAP_WRITE、FILE_MAP_READ、FILE_MAP_ALL_ACCESS和FILE_MAP_COPY等几种，具体的设置要根据文件映射对象允许的保护模式而定。根据前面代码的设置，这里应该使用FILE_MAP_ALL_ACCESS参数。这种机制为对象的创建者提供了对映射此对象的方式进行控制的能力。接下来的2个参数分别指定了内存映射文件的64位偏移地址的低32位和高32位地址，该地址是从内存映射文件头位置到映像开始位置的距离。最后的参数指定了视图的大小，如果设置为0，前面的偏移地址将被忽略，系统将会把整个文件映射为一个映像。MapViewOfFile（）如果成功执行，将返回一个指向文件映像在进程的地址空间中的起始地址的指针。如果失败，则返回NULL。在进程中，可以为同一个文件映射对象创建多个文件映像，这些映像可以在系统中共存和重叠，也可以与对应的文件映射对象大小不相一致，但不能大于文件映射对象的大小。<br><br>　　<strong>4）UnmapViewOfFile（）：</strong>当不再需要保留映射到进程地址空间区域中的文件映像数据时，可通过调用UnmapViewOfFile（）函数将其释放。该函数结构非常简单，只需要提供映像在进程中的起始地址（区域的基地址）作为参数即可。该函数的输入参数为调用MapViewOfFile（）时所返回的指向文件映像在进程的地址空间中的起始地址的指针。在调用MapViewOfFile（）后，必须确保在进程退出之前能够执行UnmapViewOfFile（）函数，否则在进程终止之后先前保留的区域将得不到释放，即使再次启动进程重复调用MapViewOfFile（）系统也总是在进程的地址空间中保留一个新的区域，而此前保留的所有区域将得不到释放。<br><br>　　一种比较特殊的情况是，对同一个内存映射文件映射了两个相同的映像的撤消。前面曾经提到过，对于同一个内存映射文件可以有多个映像，这些映像也可以重叠，因此这种情况的存在是合法的。对于这种情况，虽然从表面看上去在单进程的地址空间内是不可能存在两个基地址完全相同的映像的，这将导致无法对这它们的区分。但是事实上，由MapViewOfFile（）所返回得到的基地址只是文件映像在进程地址空间中的起始基地址，因此在映射同一内存映射文件的两个相同映像时将会产生对内存映射文件同一部分的两个不同基地址的相同映像，可以用同样的方法调用UnmapViewOfFile（）将其从进程的地址空间中予以撤消。<br><br>　　<strong>5）CloseHandle（）：</strong> 与Win32的大多数对象一样，在使用完毕之后总是要通过CloseHandle（）函数将已打开的内核对象关闭。如果忘记关闭对象，在程序继续运行时将会出现资源泄漏。虽然在程序退出运行时，操作系统会自动关闭在进程中已经打开但未关闭的任何对象。但是在进程的运行过程中，势必会积累过多的资源句柄。因此在不再需要使用对象的时候通过CloseHandle（）将其予以关闭是有意义的。<br><br>　　<strong>小结</strong><br><br>　　本文对内存映射文件在大文件处理中的应用作了较为详细的阐述。经实际测试，内存映射文件在处理大数据量文件时表现出了良好的性能，比通常使用CFile类和ReadFile()和WriteFile()等函数的文件处理方式具有明显的优势。本文所述程序代码在Windows 2000 Professional下由Microsoft Visual C++ 6.0编译通过。<br><br>
<img src ="http://www.cppblog.com/SpringSnow/aggbug/74017.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/SpringSnow/" target="_blank">Sandy</a> 2009-02-17 11:55 <a href="http://www.cppblog.com/SpringSnow/archive/2009/02/17/74017.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>文件操作：CreateFile和WriteFile的学习</title><link>http://www.cppblog.com/SpringSnow/archive/2009/02/09/73334.html</link><dc:creator>Sandy</dc:creator><author>Sandy</author><pubDate>Mon, 09 Feb 2009 14:14:00 GMT</pubDate><guid>http://www.cppblog.com/SpringSnow/archive/2009/02/09/73334.html</guid><wfw:comment>http://www.cppblog.com/SpringSnow/comments/73334.html</wfw:comment><comments>http://www.cppblog.com/SpringSnow/archive/2009/02/09/73334.html#Feedback</comments><slash:comments>9</slash:comments><wfw:commentRss>http://www.cppblog.com/SpringSnow/comments/commentRss/73334.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/SpringSnow/services/trackbacks/73334.html</trackback:ping><description><![CDATA[&nbsp;
<p align=left><span>今天的任务是要保存一个文件。平常看别人怎么写，自己还只是看，没有动手去写过，对各个<span>API</span>相应的参数不是很了解。今天在运用的时候，还真是遇见了一些问题。<span><br><br></span>我们先来说说问题：<span><br></span>第一个问题：使用<span>WriteFile</span>的时候，我直接将宽字符串写进了文件，文件显示如大家所想，掺杂了很多乱码。但是很有规则。所以我很快就明白了这需要将宽字符串转换成<span>ASCII</span>码。<span><br></span>第二个问题：就是我将文件打开后，又进行了写文件的操作，此时失败。所以对这种情况，还没有想出办法，是由于<span>CreateFile</span>的参数的某些限制么？<span><br><br></span>由于这两个问题，所以我也好好看了一下<span>SDK</span>文档。<span><br></span>我们先来看一下<span>CreateFile</span>和<span>WriteFile</span>的原型和参数介绍：<span><br><br><strong>HANDLE</strong> <strong><span>CreateFile</span>(</strong><br>&nbsp; <strong>LPCTSTR</strong> <em><span><u><span>lpFileName</span></u></span></em><strong>,&nbsp; // </strong></span><strong>文件名</strong><span><br>&nbsp; <strong>DWORD</strong> <em><span><u><span>dwDesiredAccess</span></u></span></em><strong>,&nbsp; // </strong></span><strong>访问方式</strong><span><br>&nbsp; <strong>DWORD</strong> <em><span><u><span>dwShareMode</span></u></span></em><strong>,&nbsp; // </strong></span><strong>共享模式</strong><span><br>&nbsp; <strong>LPSECURITY_ATTRIBUTES</strong> <em><span><u><span>lpSecurityAttributes</span></u></span></em><strong>,&nbsp; // </strong></span><strong>设为<span>NULL</span></strong><span><br>&nbsp; <strong>DWORD</strong> <em><span><u><span>dwCreationDisposition</span></u></span></em><strong>,&nbsp; /// </strong></span><strong>创建方式</strong><span><br>&nbsp; <strong>DWORD</strong> <em><span><u><span>dwFlagsAndAttributes</span></u></span></em><strong>,&nbsp; // </strong></span><strong>属性</strong><span><br>&nbsp; <strong>HANDLE</strong> <em><span><u><span>hTemplateFile</span></u></span></em><br><strong>);</strong> </span></span></p>
<p align=left><strong><span>BOOL</span></strong><span> <strong><span>WriteFile</span>( </strong></span></p>
<p align=left><span>&nbsp;<strong>HANDLE</strong> <em><span><u><span>hFile</span></u></span></em><strong>, // </strong></span><strong><span>文件句柄</span></strong></p>
<p align=left><span>&nbsp;<strong>LPCVOID</strong> <em><span><u><span>lpBuffer</span></u></span></em><strong>, // </strong></span><strong><span>包含写向文件的数据</span></strong></p>
<p align=left><span>&nbsp;<strong>DWORD</strong> <em><span><u><span>nNumberOfBytesToWrite</span></u></span></em><strong>,&nbsp;// </strong></span><strong><span>数据包含的字符串的个数</span></strong></p>
<p align=left><span>&nbsp;<strong>LPDWORD</strong> <em><span><u><span>lpNumberOfBytesWritten</span></u></span></em><strong>, </strong></span></p>
<p align=left><span>&nbsp;<strong>LPOVERLAPPED</strong> <em><span><u><span>lpOverlapped</span></u></span></em></span></p>
<p align=left><strong><span>);</span></strong><span> </span></p>
<p align=left><span>第一次我写的程序很简单</span></p>
<p align=left><span>BOOL WriteOwnFile(TCHAR* pFileName, TCHAR* pBuffer, DWORD dwLen)</span></p>
<p align=left><span>{</span></p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>HANDLE hFile = CreateFile(pFileName,</span></p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>GENERIC_WRITE,</span></p>
<p align=left><span><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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>FILE_SHARE_WRITE,</span></p>
<p align=left><span><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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>NULL,</span></p>
<p align=left><span><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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>CREATE_ALWAYS,</span></p>
<p align=left><span><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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>FILE_ATTRIBUTE_NORMAL,</span></p>
<p align=left><span><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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>NULL</span></p>
<p align=left><span><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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>）；</span></p>
<p align=left>&nbsp;</p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>if (INVALID_HANDLE_VALUE != hFile)</span></p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p align=left><span><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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>DWORD&nbsp;dwSize = 0;</span></p>
<p align=left><span><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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>WriteFile(hFile, pBuffer, dwLen, &amp;dwSize, NULL );</span></p>
<p align=left><span><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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>CloseHandle(hFile);</span></p>
<p align=left><span><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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>return TRUE;</span></p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>return FALSE;</span></p>
<p align=left><span>}</span></p>
<p align=left>&nbsp;</p>
<p align=left><span>这样是完成了，但是写出来的文件是乱码。所以没有进行字符的转换，我们需要将<span>pBuffer</span>进行转换。这就要用到了<span>WideCharToMultiByte.</span>如何用呢？</span></p>
<p align=left><span>首先我的方法比较笨，我是这么用的：</span></p>
<p align=left><span>char* pchBuffer = new char[dwLen+1];</span></p>
<p align=left><span>WideCharToMultiByte(</span><span>CP_ACP,&nbsp;NULL,&nbsp;pBuffer, -1, pchBuffer, dwLen+1, NULL, FALSE </span><span>);</span></p>
<p align=left><span>WriteFile(hFile, pBuffer, <span>dwLen+1</span>, &amp;dwSize, NULL );</span></p>
<p align=left><span>&nbsp;Delete[] pchBuffer;</span></p>
<p align=left>&nbsp;</p>
<p align=left><span>此时注意，我在<span>WriteFile</span>中用了<span>dwLen+1</span>。结果就是在文件的末尾出现了乱码，正好多一个乱码出来。所以<span>WriteFile</span>中<span><span>nNumberOfBytesToWrite</span></span>是写的字符串的数目，是不包括<span>&#8217;\<st1:chmetcnv w:st="on" TCSC="0" NumberType="1" Negative="False" HasSpace="False" SourceValue="0" UnitName="&#8217;">0&#8217;</st1:chmetcnv></span>的。</span></p>
<p align=left>&nbsp;</p>
<p align=left><span>这个方法笨，是因为我们的函数可以缩减为两个参数。是因为如下这么写时，<span>dwLen</span>是所要转换的字符串的个数，此时转换的字符串是包括<span>&#8217;\<st1:chmetcnv w:st="on" TCSC="0" NumberType="1" Negative="False" HasSpace="False" SourceValue="0" UnitName="&#8217;">0&#8217;</st1:chmetcnv></span>的。</span></p>
<p align=left><span>DWORD dwLen = WideCharToMultiByte(</span><span>CP_ACP,&nbsp;NULL,&nbsp;pBuffer, -1, NULL, NULL, NULL, FALSE </span><span>);</span></p>
<p align=left>&nbsp;</p>
<p align=left><span>所以我们再来看一下改写以后的代码</span></p>
<p align=left><span>BOOL WriteOwnFile(TCHAR* pFileName, TCHAR* pBuffer)</span></p>
<p align=left><span>{</span></p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>HANDLE hFile = CreateFile(pFileName,</span></p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>GENERIC_WRITE,</span></p>
<p align=left><span><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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>FILE_SHARE_WRITE,</span></p>
<p align=left><span><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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>NULL,</span></p>
<p align=left><span><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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>CREATE_ALWAYS,</span></p>
<p align=left><span><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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>FILE_ATTRIBUTE_NORMAL,</span></p>
<p align=left><span><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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>NULL</span></p>
<p align=left><span><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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>）；</span></p>
<p align=left>&nbsp;</p>
<p align=left><span><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; </span>if (INVALID_HANDLE_VALUE != hFile)</span></p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p align=left><span><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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>DWORD&nbsp;dwSize = 0;</span></p>
<p align=left><span><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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>DWORD dwLen = WideCharToMultiByte(CP_ACP,&nbsp;NULL,&nbsp;pBuffer, -1, NULL, NULL, NULL, FALSE );</span></p>
<p align=left><span><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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>char* pchBuffer = new char[dwLen];</span></p>
<p align=left><span><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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>WideCharToMultiByte(CP_ACP,&nbsp;NULL,&nbsp;pBuffer, -1, pchBuffer, dwLen, NULL, FALSE );</span></p>
<p align=left><span><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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>WriteFile(hFile, pBuffer, dwLen+1, &amp;dwSize, NULL );</span></p>
<p align=left><span><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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>&nbsp;delete[] pchBuffer;</span></p>
<p align=left><span><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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>CloseHandle(hFile);</span></p>
<p align=left><span><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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>return TRUE;</span></p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>return FALSE;</span></p>
<p align=left><span>}</span></p>
<p align=left>&nbsp;</p>
<p align=left>&nbsp;</p>
<p align=left><span>这样感觉代码好看多了。</span></p>
<p align=left>&nbsp;</p>
<p align=left><span>对于第二个问题，文件打开的时候文件创建失败，还没有想好办法解决。我在想是不是我的某些认知存在问题，文件打开的时候，是否可以用</span><span>CreateFile</span><span>来打开呢？<br></span></p>
<img src ="http://www.cppblog.com/SpringSnow/aggbug/73334.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/SpringSnow/" target="_blank">Sandy</a> 2009-02-09 22:14 <a href="http://www.cppblog.com/SpringSnow/archive/2009/02/09/73334.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>mobile上监控文件的操作</title><link>http://www.cppblog.com/SpringSnow/archive/2009/02/08/73221.html</link><dc:creator>Sandy</dc:creator><author>Sandy</author><pubDate>Sun, 08 Feb 2009 08:20:00 GMT</pubDate><guid>http://www.cppblog.com/SpringSnow/archive/2009/02/08/73221.html</guid><wfw:comment>http://www.cppblog.com/SpringSnow/comments/73221.html</wfw:comment><comments>http://www.cppblog.com/SpringSnow/archive/2009/02/08/73221.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/SpringSnow/comments/commentRss/73221.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/SpringSnow/services/trackbacks/73221.html</trackback:ping><description><![CDATA[<span>今天完成了一个任务</span><span>,</span><span>就是在</span><span>mobile</span><span>上如何监控文件的操作。这个</span><span>SDK</span><span>中有相应的例子，为</span><span>FileChangeNotif</span><span>。</span><span><br><br><strong>&nbsp;</strong></span><strong><span>如何实现文件监控？</span></strong><span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>首先要在窗口注册，这个要用到</span><strong><span>SHChangeNotifyRegister</span></strong><span>，这个函数的主要功能就是列举一个窗口来接收</span><span>change notifications.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>在这个注册的窗口中，响应</span><strong><span>WM_FILECHANGEINFO</span></strong><span>这个消息，来进行我们响应的操作。</span><span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>如何我们不想监控了，则可以使用</span><strong><span>SHChangeNotifyDeregister</span></strong><span>，来移除相应的注册窗口。</span><span><br><br></span><span>这样我们就可以实现对一个文件夹内文件的生成，删除，改名等等操作的监控。</span><span><br><br></span><span>下面我们再具体来谈谈每一步如何操作。</span><span><br><strong>1</strong></span><strong><span>、</span><span>SHChangeNotifyRegister</span></strong><strong><span>的运用</span></strong><span><br><span>&nbsp;&nbsp; </span><strong>SHChangeNotifyRegiste</strong>r</span><span>的原型为</span><span><br>&nbsp;<strong>&nbsp;BOOL WINAPI SHChangeNotifyRegister(</strong></span>
<p><strong><span>HWND <span>hwnd</span>, </span></strong></p>
<p><strong><span>SHCHANGENOTIFYENTRY * <span>pshcne</span></span></strong></p>
<p><strong><span>);</span></strong></p>
<p><strong><span>&nbsp;</span></strong><span>&nbsp;</span><span>其中</span><span>,hwnd,</span><span>为接收</span><span>change notification</span><span>的窗口</span><span>;</span></p>
<p><strong><span><span>pshcne</span></span></strong><span>是一个指向</span><span>SHCHANGENOTIFYENTRY</span><span>结构的指针</span><span>,</span><span>它用来指明窗口接收的</span><span>change notification</span><span>的类型</span><span>.</span><span>如果设为</span><span>NULL,</span><span>窗口将接收</span><span>all file system, network </span><span>和</span><span> media</span><span>类型的</span><span>notifications.</span></p>
<p><strong><span>SHCHANGENOTIFYENTRY</span></strong><span>是什么样的一个结构</span><span>,</span><span>我们看一下它的定义</span></p>
<pre><strong><span>typedef &nbsp;struct &nbsp;tagSHCHANGENOTIFYENTRY {</span></strong></pre>
<pre><strong><span> &nbsp;&nbsp;DWORD <span>dwEventMask</span>;</span></strong></pre>
<pre><strong><span> &nbsp;&nbsp;LPTSTR <span>pszWatchDir</span>;</span></strong></pre>
<pre><strong><span>&nbsp;BOOL <span>fRecursive</span>;</span></strong></pre>
<p><strong><span>} SHCHANGENOTIFYENTRY;</span></strong></p>
<p><strong><span><span>dwEventMask</span></span></strong><span> </span><span>指定发生什么时间来发送</span><span>notification </span><span>消息</span></p>
<p><strong><span><span>pszWatchDir</span></span></strong><span> </span><span>指定监控路径，该值为</span><span>NULL</span><span>的情况下，是监控所有的文件。</span></p>
<p><strong><span><span>fRecursive</span></span></strong><span>指定是否只监控指定路径还是监控指定路径及其子文件夹。</span></p>
<p>&nbsp;</p>
<p><span>知道了这些，我们不妨写一个这样的函数，来启动文件监控。</span></p>
<p><span>代码如下：</span></p>
<div>
<p align=left><span>BOOL</span><span> <span>StartFileMonitor</span>(<span>HWND</span> <span>hWnd, LPTSTR lpFilePath</span>)</span></p>
<p align=left><span>{</span></p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>SHCHANGENOTIFYENTRY</span> <span>schneNotifyEntry</span>;</span></p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>schneNotifyEntry</span>.<span>dwEventMask</span> = <span>SHCNE_ALLEVENTS</span>;</span></p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>schneNotifyEntry</span>.<span>pszWatchDir</span> = <span>lpFilePath</span>;</span></p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>schneNotifyEntry</span>.<span>fRecursive</span> = <span>TRUE</span>;</span></p>
<p align=left>&nbsp;</p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>return</span> <span>SHChangeNotifyRegister</span>(<span>hWnd</span>, &amp;<span>schneNotifyEntry</span>);</span></p>
<p align=left><span>}</span></p>
</div>
<p><strong><span>2</span></strong><strong><span>、如何处理</span><span>WM_FILECHANGEINFO</span></strong><strong><span>消息</span></strong></p>
<p><span>WM_FILECHANGEINFO </span><span>中的参数</span><span>lParam</span><span>，指向</span><span><a href="http://msdn.microsoft.com/en-us/library/aa453066.aspx"><span>FILECHANGENOTIFY</span></a></span><span>，含有相关的数据。所以我们在收到该消息后，先作的一部操作就是</span></p>
<p><span>FILECHANGENOTIFY&nbsp;*lpfcn = (FILECHANGENOTIFY*)lParam;</span></p>
<p><strong><span>FILECHANGENOTIFY</span></strong><span>的结构为：</span></p>
<p><strong><span>typedef struct tagFILECHANGENOTIFY {</span></strong></p>
<p><strong><span>&nbsp;DWORD dwRefCount; </span></strong></p>
<p><strong><span>&nbsp;FILECHANGEINFO fci;</span></strong></p>
<p><strong><span>} FILECHANGENOTIFY;</span></strong></p>
<p><span>我们主要用到了其中的</span><span>fci</span><span>参数。</span></p>
<p><strong><span>FILECHANGEINFO</span></strong><span>的结构为：</span></p>
<p><strong><span>struct _FILECHANGEINFO {</span></strong></p>
<p><strong><span>&nbsp;DWORD cbSize;</span></strong></p>
<p><strong><span>&nbsp;LONG wEventId; </span></strong></p>
<p><strong><span>&nbsp;ULONG uFlags; </span></strong></p>
<p><strong><span>&nbsp;DWORD dwItem1; </span></strong></p>
<p><strong><span>&nbsp;DWORD dwItem2;</span></strong></p>
<p><strong><span>&nbsp;DWORD dwAttributes; </span></strong></p>
<p><strong><span>&nbsp;FILETIME ftModified; </span></strong></p>
<p><strong><span>&nbsp;ULONG nFileSize; </span></strong></p>
<p><strong><span>} FILECHANGEINFO, *LPFILECHANGEINFO;</span></strong></p>
<p><strong><span>dwEventId</span></strong><span> </span><span>与</span><span>SHCHANGENOTIFYENTRY</span><span>结构中的</span><strong><span><span>dwEventMask</span></span></strong><span>对应。</span></p>
<p><strong><span>dwItem1,dwItem</span></strong><span>2</span><span>是事件依赖的值，里面包括了我们需要的文件的完整路径。如果是进行创建文件的操作，则</span><strong><span>dwItem1</span></strong><span>是创建后文件的完整路径，如果是对文件进行重新命名操作的话，则</span><strong><span>dwItem2</span></strong><span>是修改后文件的完整路径。此处对其他参数不做介绍，大家需要的话，可以查看一下。</span></p>
<p>&nbsp;</p>
<p><span>我们做完相应的操作后，要知道释放，此时要用到</span><strong><span>SHChangeNotifyFree</span></strong><span>。这个用起来就简单很多，如</span><strong><span>SHChangeNotifyFree</span></strong><span>（</span><span>lpfcn</span><span>）。</span></p>
<p>&nbsp;</p>
<p><span>下面给大家一小段示例代码，如下</span></p>
<div>
<p><span>case WM_FILECHANGEINFO:</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span>{<span>&nbsp;&nbsp; </span></span></p>
<p><span>FILECHANGENOTIFY<span>&nbsp;&nbsp;&nbsp; </span>*lpfcn;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>FILECHANGEINFO<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>*lpfci;<span>&nbsp;&nbsp;&nbsp; </span></span></p>
<p><span>lpfcn = (FILECHANGENOTIFY *)lParam;</span></p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>if (NULL == lpfcn)</span></p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>break;</span></p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>// see if the pointer to the file change info structure</span></p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>lpfci = &amp;(lpfcn-&gt;fci);</span></p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>if (NULL == lpfci)</span></p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>break;</span></p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>else</span></p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>switch (lpfci-&gt;wEventId)&nbsp;</span></p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>case<span> </span>SHCNE_RENAME:</span></p>
<p align=left><span><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; </span>{</span></p>
<p align=left><span><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; </span>//</span><span>&#8230;&#8230;</span></p>
<p align=left><span><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; </span>}</span></p>
<p align=left><span><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; </span>break;</span></p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<span>&nbsp;&nbsp;&nbsp;&nbsp; </span></span></p>
<p align=left><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>SHChangeNotifyFree(lpfcn);</span></p>
<p><span>}</span></p>
<p><span>break;</span></p>
</div>
<p>&nbsp;</p>
<p><strong><span>3</span></strong><strong><span>、如何停止文件监控</span></strong></p>
<p><span><span>&nbsp;&nbsp; </span></span><span>停止文件监控比较简单，只要使该窗口不接收</span><strong><span>WM_FILECHANGEINFO</span></strong><span>消息即可。使用</span><strong><span>SHChangeNotifyDeregister(hWnd)</span></strong><span>即可。</span></p>
<p>&nbsp;</p>
<p><span>以上是我今天学习的一些总结，此外需要注意的一个小地方，在</span><span>mobile</span><span>上，把一个文件从一个文件夹拷到另一个文件夹，此时响应的事件是</span><span>SHCNE_CREATE</span><span>，二从电脑上拷贝一个文件到</span><span>mobile</span><span>上，响应的消息为</span><span>SHCNE_RENAME</span><span>。我注意到从电脑上拷贝的话，</span><span>mobile</span><span>会先生成一个</span><span>Temp</span><span>文件夹内生成一个临时文件，然后再在我们指定的文件夹内生成一个文件。这个机制我还不是很清楚为什么。</span></p>
<img src ="http://www.cppblog.com/SpringSnow/aggbug/73221.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/SpringSnow/" target="_blank">Sandy</a> 2009-02-08 16:20 <a href="http://www.cppblog.com/SpringSnow/archive/2009/02/08/73221.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>mobile数据库遇到的问题 </title><link>http://www.cppblog.com/SpringSnow/archive/2009/02/04/72972.html</link><dc:creator>Sandy</dc:creator><author>Sandy</author><pubDate>Wed, 04 Feb 2009 05:20:00 GMT</pubDate><guid>http://www.cppblog.com/SpringSnow/archive/2009/02/04/72972.html</guid><wfw:comment>http://www.cppblog.com/SpringSnow/comments/72972.html</wfw:comment><comments>http://www.cppblog.com/SpringSnow/archive/2009/02/04/72972.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/SpringSnow/comments/commentRss/72972.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/SpringSnow/services/trackbacks/72972.html</trackback:ping><description><![CDATA[<p>今天在加数据库的相关操作时,遇到了一些问题,提示</p>
<p>error C3861: 'CeMountDBVolEx': identifier not found<br>error C3861: 'CeMountDBVolEx': identifier not found<br>error C3861: 'CeCreateDatabaseWithProp<wbr>s': identifier not found<br>error C3861: 'CeCreateSession': identifier not found<br>error C3861: 'CeOpenDatabaseInSession': identifier not found</p>
<p>我在.cpp文件的开头加入了</p>
<p><font face=Verdana>#define EDB<br>#include &lt;windows.h&gt;<br>#include &lt;windbase.h&gt;</font></p>
<p>但是错误还依然存在</p>
<p>从网上搜索了一些方法</p>
<p><font face=Verdana>在博文《mobile数据库遇到的问题》</font></p>
<p><font face=Verdana color=#800080><a href="http://blog.sina.com.cn/s/blog_4c5ad0740100cvxg.html"><u>http://blog.sina.com.cn/s/blog_4c5ad0740100cvxg.html</u></a></font></p>
<p>它里面建议使用</p>
<p>extern "C"<br>{<br>&nbsp;<wbr> #include &lt;windbase_edb.h&gt;<br>}</p>
<p>但是使用后，问题变成了lnk的错误</p>
<p>error LNK2019: unresolved external symbol </p>
<p>有人在论坛里建议</p>
<p>#include Windbase_edb.h </p>
<p>也是同样的问题</p>
<p>最后，我问了一下我的同事</p>
<p>他建议我在</p>
<p>stdafx.h 头文件中添加</p>
<p><font face=Verdana>#define EDB<br>#include &lt;windows.h&gt;<br>#include &lt;windbase.h&gt;</font></p>
<p>这样的确解决了问题。</p>
<img src ="http://www.cppblog.com/SpringSnow/aggbug/72972.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/SpringSnow/" target="_blank">Sandy</a> 2009-02-04 13:20 <a href="http://www.cppblog.com/SpringSnow/archive/2009/02/04/72972.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转:进程间通信的11种方法</title><link>http://www.cppblog.com/SpringSnow/archive/2009/02/03/72928.html</link><dc:creator>Sandy</dc:creator><author>Sandy</author><pubDate>Tue, 03 Feb 2009 10:53:00 GMT</pubDate><guid>http://www.cppblog.com/SpringSnow/archive/2009/02/03/72928.html</guid><wfw:comment>http://www.cppblog.com/SpringSnow/comments/72928.html</wfw:comment><comments>http://www.cppblog.com/SpringSnow/archive/2009/02/03/72928.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/SpringSnow/comments/commentRss/72928.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/SpringSnow/services/trackbacks/72928.html</trackback:ping><description><![CDATA[<p>先粘过来,备以后细读<br>链接地址:http://www.bsdlover.cn/index.php?action/viewnews/itemid/1611/page/1/php/1<br><br></p>
<p><a onclick="javascript:tagshow(event, '%E8%BF%9B%E7%A8%8B');" href="javascript:;" target=_self><u><strong><font color=#656d77>进程</font></strong></u></a>间<a onclick="javascript:tagshow(event, '%E9%80%9A%E4%BF%A1');" href="javascript:;" target=_self><u><strong><font color=#656d77>通信</font></strong></u></a>有以下方法<br>Using named objects<br>Waiting for multiple objects<br>Waiting in a message loop<br>Using mutex objects<br>Using semaphore objects<br>Using event objects<br>Using critical section objects<br>Using timer queues<br>Using waitable timer objects<br><strong>&nbsp;<span id=ArticleTitle1_ArticleTitle1_lblTitle>进程间的通讯<a onclick="javascript:tagshow(event, '%E5%AE%9E%E7%8E%B0');" href="javascript:;" target=_self><u><strong><font color=#656d77>实现</font></strong></u></a>（IPC）的11种方法</span></strong>&nbsp;&nbsp;&nbsp;
<p>进程通常被定义为一个正在运行的程序的实例，它由两个部分组成：<br>一个是操作系统用来管理进程的<a onclick="javascript:tagshow(event, '%E5%86%85%E6%A0%B8');" href="javascript:;" target=_self><u><strong><font color=#656d77>内核</font></strong></u></a>对象。内核对象也是系统用来存放关于进程的统计信息的地方<br>&nbsp;另一个是地址空间，它包含所有的可执行模块或DLL模块的代码和数据。它还包含动态分配的空间。如线程堆栈和堆分配空间。每个进程被赋予它自己的虚拟地址空间，当进程中的一个线程正在运行时，该线程可以访问只属于它的进程的<a onclick="javascript:tagshow(event, '%E5%86%85%E5%AD%98');" href="javascript:;" target=_self><u><strong><font color=#656d77>内存</font></strong></u></a>。属于其它进程的内存则是隐藏的，并不能被正在运行的线程访问。<br>&nbsp;&nbsp; 为了能在两个进程之间进行通讯，由以下几种方法可供参考：</p>
<p>在16位时代常使用的方式，CWnd中提供支持<br>1。窗口消息 标准的Windows消息以及专用的WM_COPYDATA消息 SENDMESSAGE()接收端必须有一个窗口</p>
<p>2。使用共享内存方式（Shared Memory)<br>a.设定一块共享内存区域&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp; HANDLE CreateFileMapping(HANDLE,LPSECURITY_ATTRIBUTES, DWORD,&nbsp;DWORD, DWORD,&nbsp; LPCSTR)<br>&nbsp;&nbsp;&nbsp;&nbsp; 产生一个file-mapping核心对象<br>&nbsp;&nbsp;&nbsp;&nbsp; LPVOID MapViewOfFile(<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HANDLE hFileMappingObject,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DWORD&nbsp; dwDesiredAcess,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp; dwFileOffsetHigh,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DWORD&nbsp; dwFileOffsetLow,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DWORD&nbsp; dwNumberOfBytesToMap<br>&nbsp;&nbsp;&nbsp;&nbsp; );<br>得到共享内存的<a onclick="javascript:tagshow(event, '%E6%8C%87%E9%92%88');" href="javascript:;" target=_self><u><strong><font color=#656d77>指针</font></strong></u></a><br>&nbsp;&nbsp; b.找出共享内存<br>&nbsp;&nbsp;&nbsp; 决定这块内存要以点对点（peer to peer)的形式呈现<br>每个进程都必须有相同的能力，产生共享内存并将它初始化。每个进程<br>都应该调用CreateFileMapping(),然后调用GetLastError().如果传回的错误代码是ERROR_ALREADY_EXISTS,那么进程就可以假设这一共享内存区 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 域已经被别的进程打开并初始化了，否则该进程就可以合理的认为自己 排在第一位，并接下来将共享内存初始化。还是要使用client/server架构中只有server进程才应该产生并初始化共享内存。所有的进程都应该使用<br>HANDLE OpenFileMapping(DWORD dwDesiredAccess,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BOOL bInheritHandle,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LPCTSTR lpName);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 再调用MapViewOfFile(),取得共享内存的指针<br>&nbsp;&nbsp; c.同步处理(Mutex)<br>&nbsp;&nbsp;&nbsp;d.清理(Cleaning up) BOOL UnmapViewOfFile(LPCVOID lpBaseAddress);<br>&nbsp;&nbsp;&nbsp; CloseHandle()</p>
<p>3。动态数据交换（DDE）通过维护全局分配内存使的应用程序间传递成为可能<br>&nbsp;&nbsp; 其方式是再一块全局内存中手工放置大量的数据，然后使用窗口消息传递内存&nbsp;&nbsp;&nbsp; 指针.这是16位WIN时代使用的方式，因为在WIN32下已经没有全局和局部内存&nbsp;&nbsp;&nbsp; 了，现在的内存只有一种就是虚存。&nbsp;&nbsp;</p>
<p>4。消息管道(Message Pipe)<br>&nbsp;&nbsp; 用于设置应用程序间的一条永久通讯通道，通过该通道可以象自己的应用程序<br>&nbsp;&nbsp;&nbsp;访问一个平面<a onclick="javascript:tagshow(event, '%E6%96%87%E4%BB%B6');" href="javascript:;" target=_self><u><strong><font color=#656d77>文件</font></strong></u></a>一样读写数据。<br>&nbsp;&nbsp;&nbsp;名管道(Anonymous Pipes)<br>&nbsp;&nbsp;&nbsp;&nbsp;单向流动，并且只能够在同一电脑上的各个进程之间流动。<br>&nbsp;&nbsp;&nbsp;命名管道(Named Pipes)<br>&nbsp;&nbsp;&nbsp;双向，跨网络，任何进程都可以轻易的抓住，放进管道的数据有固定的格式，而使用ReadFile()只能读取该大小的倍数。可以被使用于I/O Completion Ports</p>
<p>5邮件槽(Mailslots)<br>&nbsp;&nbsp;&nbsp; 广播式通信,在32系统中提供的新方法，可以在不同主机间交换数据，在&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WIN9X下只支持邮件槽客户</p>
<p>6Windows套接字(Windows Socket)<br>&nbsp;&nbsp; 它具备消息管道所有的功能，但遵守一套通信标准使的不同操作系统之上的应&nbsp;&nbsp;&nbsp; 用程序之间可以互相通信。</p>
<p>7Internet通信 它让应用程序从Internet地址上载或<a onclick="javascript:tagshow(event, '%E4%B8%8B%E8%BD%BD');" href="javascript:;" target=_self><u><strong><font color=#656d77>下载</font></strong></u></a>文件</p>
<p>8。RPC：远程过程调用，很少使用，因其与UNIX的RPC不兼容。</p>
<p>9。串行/并行通信(Serial/Parallel Communication)<br>&nbsp;&nbsp; 它允许应用程序通过串行或并行端口与其他的应用程序通信</p>
<p>10。COM/DCOM<br>&nbsp;&nbsp;&nbsp;&nbsp; 通过COM系统的代理存根方式进行进程间数据交换，但只能够表现在对接口&nbsp;&nbsp;&nbsp;&nbsp; <a onclick="javascript:tagshow(event, '%E5%87%BD%E6%95%B0');" href="javascript:;" target=_self><u><strong><font color=#656d77>函数</font></strong></u></a>的调用时传送数据，通过DCOM可以在不同主机间传送数据。</p>
<img src ="http://www.cppblog.com/SpringSnow/aggbug/72928.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/SpringSnow/" target="_blank">Sandy</a> 2009-02-03 18:53 <a href="http://www.cppblog.com/SpringSnow/archive/2009/02/03/72928.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>系统出现乱码了</title><link>http://www.cppblog.com/SpringSnow/archive/2009/01/13/71905.html</link><dc:creator>Sandy</dc:creator><author>Sandy</author><pubDate>Tue, 13 Jan 2009 08:10:00 GMT</pubDate><guid>http://www.cppblog.com/SpringSnow/archive/2009/01/13/71905.html</guid><wfw:comment>http://www.cppblog.com/SpringSnow/comments/71905.html</wfw:comment><comments>http://www.cppblog.com/SpringSnow/archive/2009/01/13/71905.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/SpringSnow/comments/commentRss/71905.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/SpringSnow/services/trackbacks/71905.html</trackback:ping><description><![CDATA[<p>昨天还在感叹落后了好几年,装了一个MSN,一下子就装了一个9.0的,可以跟上时代了吧,美美的加了一番好友.今天打开电脑,发现我的开始就显示为我不认识的文字了?<br><br>中毒了?这是我的第一个反应?不会吧,看来这个还是问题啊.想想昨天就装了一个msn,似乎也安安分分的写写程序,那肯定是我的msn程序出问题了.于是折腾了半天,把msn都卸掉了,发现原来系统还是坏的.<br><br>莫非因为我是盗版,就不让我用么?<br><br>先不管那么多了,上网搜搜,有人说是注册表中涉及font的一些值有所改变,认认真真的对比了一下和同事的区别,好像没有什么差别.这是怎么回事呢?<br><br>杀毒,扫木马,似乎都进行了,好像没有什么反映.此时,我试着更换了一些主题,恩,好了.<br><br>问题是解决了,但是不明白是什么原因造成的.呵呵,就默认了吧.<br><br>症状还是比较轻的,只是对话框的标题什么的,一些快捷提示是乱码,文件还是好好的.否则我估计要哭残了.</p>
<img src ="http://www.cppblog.com/SpringSnow/aggbug/71905.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/SpringSnow/" target="_blank">Sandy</a> 2009-01-13 16:10 <a href="http://www.cppblog.com/SpringSnow/archive/2009/01/13/71905.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>windows mobile中如何调用无线发送界面</title><link>http://www.cppblog.com/SpringSnow/archive/2009/01/06/71367.html</link><dc:creator>Sandy</dc:creator><author>Sandy</author><pubDate>Tue, 06 Jan 2009 11:04:00 GMT</pubDate><guid>http://www.cppblog.com/SpringSnow/archive/2009/01/06/71367.html</guid><wfw:comment>http://www.cppblog.com/SpringSnow/comments/71367.html</wfw:comment><comments>http://www.cppblog.com/SpringSnow/archive/2009/01/06/71367.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/SpringSnow/comments/commentRss/71367.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/SpringSnow/services/trackbacks/71367.html</trackback:ping><description><![CDATA[<br>如何调用无线发送界面?<br>系统有,我为什么要自己写呢?抱着这样一种态度,查找调用无线发送界面的方式,在一遍遍苦苦搜寻中,没有找到答案.放弃,自己写了.但是今天再调试的时候,效果达不到系统那么好.不清楚系统怎么去做的.<br><br>但突然想看看英文系统中无线发送是怎么写的,查了一下"Beam File",为什么我没有尝试一下用这个来查查呢?<br><br>果然有了新发现.<br><br>通过下面一个简单的语句,我们就可以在PPC上调用系统的无线发送界面了.<br>&nbsp;&nbsp;&nbsp; CreateProcess(_T("<a href="file://Windows//Beam.exe">\\Windows\\Beam.exe</a>"), _T("<a href="file://My/">\\My</a> Documents\\Birthday_gift.gif"),&nbsp; NULL, NULL, FALSE, 0,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;NULL, NULL, NULL, NULL);<br><br>很是不错吧.<br><br>但是这个只是在PPC上适用.在smartphone上是怎样的.在windows目录下,我发现了这样一个执行文件BeamSP.exe,但是如何执行我还没有想出来,用上面的方法是行不通的. 如果你要知道的话,告诉我一声啊.<br><br><br>好东西一起分享!
<img src ="http://www.cppblog.com/SpringSnow/aggbug/71367.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/SpringSnow/" target="_blank">Sandy</a> 2009-01-06 19:04 <a href="http://www.cppblog.com/SpringSnow/archive/2009/01/06/71367.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于debug和release的一点疑惑</title><link>http://www.cppblog.com/SpringSnow/archive/2009/01/05/71244.html</link><dc:creator>Sandy</dc:creator><author>Sandy</author><pubDate>Mon, 05 Jan 2009 11:16:00 GMT</pubDate><guid>http://www.cppblog.com/SpringSnow/archive/2009/01/05/71244.html</guid><wfw:comment>http://www.cppblog.com/SpringSnow/comments/71244.html</wfw:comment><comments>http://www.cppblog.com/SpringSnow/archive/2009/01/05/71244.html#Feedback</comments><slash:comments>7</slash:comments><wfw:commentRss>http://www.cppblog.com/SpringSnow/comments/commentRss/71244.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/SpringSnow/services/trackbacks/71244.html</trackback:ping><description><![CDATA[<p>疑惑，很是疑惑的一个问题。<br><br>下午我遇到这么一个问题，我在程序里静态加载一个dll，这个dll是我自己写的。我把dll在release环境下编译，简称为A吧，另一个程序是在debug环境下进行编译的，简称为B吧。B会调用A，但是在调用中就出错了。<br><br>A&nbsp;中调用B的代码如下：<br></p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">std::vector</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">ITEMDATA</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;vcData;<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>GetValue(vcData);</span></div>
<p><br><br>B&nbsp;中的代码为<br>&nbsp;&nbsp;&nbsp; </p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;GetValue(std::vector</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">ITEMDATA</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">vcData)<br><img id=Codehighlighter1_45_113_Open_Image onclick="this.style.display='none'; Codehighlighter1_45_113_Open_Text.style.display='none'; Codehighlighter1_45_113_Closed_Image.style.display='inline'; Codehighlighter1_45_113_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_45_113_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_45_113_Closed_Text.style.display='none'; Codehighlighter1_45_113_Open_Image.style.display='inline'; Codehighlighter1_45_113_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_45_113_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_45_113_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&#8230;&#8230;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;ITEMDATA&nbsp;item;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&#8230;&#8230;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;vcData.push_back(item);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&#8230;&#8230;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span></div>
<br>但是程序每走完GetValue后就抛异常了。<br><br>但是如果两个环境都为debug，或都为release的话，都正常，但是如果不同的话，就会出错。<br><br>比较郁闷了。
<img src ="http://www.cppblog.com/SpringSnow/aggbug/71244.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/SpringSnow/" target="_blank">Sandy</a> 2009-01-05 19:16 <a href="http://www.cppblog.com/SpringSnow/archive/2009/01/05/71244.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>为什么Microsoft code sample倾向使用ZeroMemory而不是{0}? </title><link>http://www.cppblog.com/SpringSnow/archive/2008/12/20/69905.html</link><dc:creator>Sandy</dc:creator><author>Sandy</author><pubDate>Sat, 20 Dec 2008 07:04:00 GMT</pubDate><guid>http://www.cppblog.com/SpringSnow/archive/2008/12/20/69905.html</guid><wfw:comment>http://www.cppblog.com/SpringSnow/comments/69905.html</wfw:comment><comments>http://www.cppblog.com/SpringSnow/archive/2008/12/20/69905.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/SpringSnow/comments/commentRss/69905.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/SpringSnow/services/trackbacks/69905.html</trackback:ping><description><![CDATA[<h2><a id=viewpost1_TitleUrl href="http://blog.vckbase.com/michael/archive/2005/06/29/8974.html"><u><font color=#0000ff>为什么Microsoft code sample倾向使用ZeroMemory而不是{0}?</font></u></a> </h2>
<p>这是最近看的一片短文的title，当时就很好奇。<br>经常查阅MSDN的程序员都会有这个印象，微软code sample中常见的是ZeroMemory，而不是语言提供的&#8220;{0}&#8221;清零功能（不过，我一直也没有问个why）。c++语法中声明对数组或纯结构（struct），可以使用例如SPerson sTest = {0}; 来将所有成员置0.</p>
<p>那篇文章的解释是，Microsoft使用ZeroMemory会更clear，因为&#8220;= {0}&#8221; 这样的语法有些生僻，不是所有人都可以一下子明白。</p>
<p>实际上，两者还是有一些区别。<br>其一，ZeroMemory会将结构所有字节置0，而={0}只会将成员置0，其中padding字节不变。</p>
<p>其二，但一个struct有构造函数或虚函数时，ZeroMemory可以，而={0}会编译不过。显然，后者起到了一些保护作用，因为对一个有虚函数的对象使用ZeroMemory时，会将其虚函数的指针置0，这是非常危险的，因为调用虚函数时，程序显然会crash。参看如下代码：</p>
<div style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<div><img src="http://blog.vckbase.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">struct</span><span style="COLOR: #000000">&nbsp;SPerson<br><img id=Codehighlighter1_15_52_Open_Image onclick="this.style.display='none'; Codehighlighter1_15_52_Open_Text.style.display='none'; Codehighlighter1_15_52_Closed_Image.style.display='inline'; Codehighlighter1_15_52_Closed_Text.style.display='inline';" src="http://blog.vckbase.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_15_52_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_15_52_Closed_Text.style.display='none'; Codehighlighter1_15_52_Open_Image.style.display='inline'; Codehighlighter1_15_52_Open_Text.style.display='inline';" src="http://blog.vckbase.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_15_52_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://blog.vckbase.com/Images/dot.gif"></span><span id=Codehighlighter1_15_52_Open_Text><span style="COLOR: #000000">{<br><img src="http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">SPerson(){&nbsp;&nbsp;&nbsp;&nbsp;}</span><span style="COLOR: #008000"><br><img src="http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">&nbsp;c;<br><img src="http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000">&nbsp;s;<br><img src="http://blog.vckbase.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000">;<br><img src="http://blog.vckbase.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://blog.vckbase.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;CTestVirtual<br><img id=Codehighlighter1_75_156_Open_Image onclick="this.style.display='none'; Codehighlighter1_75_156_Open_Text.style.display='none'; Codehighlighter1_75_156_Closed_Image.style.display='inline'; Codehighlighter1_75_156_Closed_Text.style.display='inline';" src="http://blog.vckbase.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_75_156_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_75_156_Closed_Text.style.display='none'; Codehighlighter1_75_156_Open_Image.style.display='inline'; Codehighlighter1_75_156_Open_Text.style.display='inline';" src="http://blog.vckbase.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_75_156_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://blog.vckbase.com/Images/dot.gif"></span><span id=Codehighlighter1_75_156_Open_Text><span style="COLOR: #000000">{<br><img src="http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br><img src="http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;CTestVirtual()<br><img id=Codehighlighter1_102_105_Open_Image onclick="this.style.display='none'; Codehighlighter1_102_105_Open_Text.style.display='none'; Codehighlighter1_102_105_Closed_Image.style.display='inline'; Codehighlighter1_102_105_Closed_Text.style.display='inline';" src="http://blog.vckbase.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_102_105_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_102_105_Closed_Text.style.display='none'; Codehighlighter1_102_105_Open_Image.style.display='inline'; Codehighlighter1_102_105_Open_Text.style.display='inline';" src="http://blog.vckbase.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_102_105_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://blog.vckbase.com/Images/dot.gif"></span><span id=Codehighlighter1_102_105_Open_Text><span style="COLOR: #000000">{<br><img src="http://blog.vckbase.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">virtual</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;Draw()<br><img id=Codehighlighter1_129_145_Open_Image onclick="this.style.display='none'; Codehighlighter1_129_145_Open_Text.style.display='none'; Codehighlighter1_129_145_Closed_Image.style.display='inline'; Codehighlighter1_129_145_Closed_Text.style.display='inline';" src="http://blog.vckbase.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_129_145_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_129_145_Closed_Text.style.display='none'; Codehighlighter1_129_145_Open_Image.style.display='inline'; Codehighlighter1_129_145_Open_Text.style.display='inline';" src="http://blog.vckbase.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_129_145_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://blog.vckbase.com/Images/dot.gif"></span><span id=Codehighlighter1_129_145_Open_Text><span style="COLOR: #000000">{<br><img src="http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">10</span><span style="COLOR: #000000">;<br><img src="http://blog.vckbase.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;a;<br><img src="http://blog.vckbase.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000">;<br><img src="http://blog.vckbase.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://blog.vckbase.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;Test()&nbsp;<br><img id=Codehighlighter1_173_510_Open_Image onclick="this.style.display='none'; Codehighlighter1_173_510_Open_Text.style.display='none'; Codehighlighter1_173_510_Closed_Image.style.display='inline'; Codehighlighter1_173_510_Closed_Text.style.display='inline';" src="http://blog.vckbase.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_173_510_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_173_510_Closed_Text.style.display='none'; Codehighlighter1_173_510_Open_Image.style.display='inline'; Codehighlighter1_173_510_Open_Text.style.display='inline';" src="http://blog.vckbase.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_173_510_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://blog.vckbase.com/Images/dot.gif"></span><span id=Codehighlighter1_173_510_Open_Text><span style="COLOR: #000000">{<br><img src="http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">&nbsp;sztmp[</span><span style="COLOR: #000000">20</span><span style="COLOR: #000000">];<br><img src="http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;ZeroMemory(sztmp,&nbsp;</span><span style="COLOR: #0000ff">sizeof</span><span style="COLOR: #000000">(sztmp));<br><img src="http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img id=Codehighlighter1_245_247_Open_Image onclick="this.style.display='none'; Codehighlighter1_245_247_Open_Text.style.display='none'; Codehighlighter1_245_247_Closed_Image.style.display='inline'; Codehighlighter1_245_247_Closed_Text.style.display='inline';" src="http://blog.vckbase.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_245_247_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_245_247_Closed_Text.style.display='none'; Codehighlighter1_245_247_Open_Image.style.display='inline'; Codehighlighter1_245_247_Open_Text.style.display='inline';" src="http://blog.vckbase.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;SPerson&nbsp;sTest&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span id=Codehighlighter1_245_247_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://blog.vckbase.com/Images/dot.gif"></span><span id=Codehighlighter1_245_247_Open_Text><span style="COLOR: #000000">{</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">}</span></span><span style="COLOR: #000000">;<br><img src="http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;i&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">sizeof</span><span style="COLOR: #000000">(SPerson);<br><img src="http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">CTestVirtual&nbsp;otv&nbsp;=&nbsp;{0};&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">Compire&nbsp;error</span><span style="COLOR: #008000"><br><img src="http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;CTestVirtual&nbsp;tv;<br><img src="http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;ZeroMemory(</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">tv,&nbsp;</span><span style="COLOR: #0000ff">sizeof</span><span style="COLOR: #000000">(tv));<br><img src="http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;tv.Draw();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">As&nbsp;it&nbsp;is&nbsp;an&nbsp;object,&nbsp;don't&nbsp;use&nbsp;the&nbsp;virtual&nbsp;function&nbsp;pointer,&nbsp;so&nbsp;don't&nbsp;crash.</span><span style="COLOR: #008000"><br><img src="http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;CTestVirtual&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">pTv&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">tv;<br><img src="http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;pTv</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">Draw();&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">Crash!!!</span><span style="COLOR: #008000"><br><img src="http://blog.vckbase.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top></span><span style="COLOR: #000000">}</span></span></div>
</div>
<br>因此，在windows平台下，对于数组或纯结构使用ZeroMemory是安全的，对于class，则使用构造函数，不要调用ZeroMemory。如果有跨平台要求，使用＝{0}则可以减少一些工作。 
<img src ="http://www.cppblog.com/SpringSnow/aggbug/69905.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/SpringSnow/" target="_blank">Sandy</a> 2008-12-20 15:04 <a href="http://www.cppblog.com/SpringSnow/archive/2008/12/20/69905.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>LPTSTR的认识</title><link>http://www.cppblog.com/SpringSnow/archive/2008/12/19/69865.html</link><dc:creator>Sandy</dc:creator><author>Sandy</author><pubDate>Fri, 19 Dec 2008 13:10:00 GMT</pubDate><guid>http://www.cppblog.com/SpringSnow/archive/2008/12/19/69865.html</guid><wfw:comment>http://www.cppblog.com/SpringSnow/comments/69865.html</wfw:comment><comments>http://www.cppblog.com/SpringSnow/archive/2008/12/19/69865.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/SpringSnow/comments/commentRss/69865.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/SpringSnow/services/trackbacks/69865.html</trackback:ping><description><![CDATA[原谅我无知,对LPTSTR不是很熟悉,尽管用了半年的WIN32,今天才想起思考LPTSTR这个变量.<br><br>例如:<br>LPTSTR lpStr = _T("Hello");<br>int len1 = wcslen(lpStr); // 值为5<br>int len2 = sizeof(lpStr); // 值为4<br><br>原来是这样的啊,今天我终于弄明白了!<br><br>lpStr 是一个指针,它的用法应该与指针同.<br><br>犯了一个很低级的错误.记录下来.<br>
<img src ="http://www.cppblog.com/SpringSnow/aggbug/69865.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/SpringSnow/" target="_blank">Sandy</a> 2008-12-19 21:10 <a href="http://www.cppblog.com/SpringSnow/archive/2008/12/19/69865.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>