﻿<?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++博客-拼命流血-文章分类-技术类</title><link>http://www.cppblog.com/phenix_jiang/category/830.html</link><description>拼命流血</description><language>zh-cn</language><lastBuildDate>Wed, 28 May 2008 18:52:49 GMT</lastBuildDate><pubDate>Wed, 28 May 2008 18:52:49 GMT</pubDate><ttl>60</ttl><item><title>boost库</title><link>http://www.cppblog.com/phenix_jiang/articles/4541.html</link><dc:creator>拼命流血</dc:creator><author>拼命流血</author><pubDate>Fri, 24 Mar 2006 08:16:00 GMT</pubDate><guid>http://www.cppblog.com/phenix_jiang/articles/4541.html</guid><wfw:comment>http://www.cppblog.com/phenix_jiang/comments/4541.html</wfw:comment><comments>http://www.cppblog.com/phenix_jiang/articles/4541.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/phenix_jiang/comments/commentRss/4541.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/phenix_jiang/services/trackbacks/4541.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: .boost::any				boost::any是一种通用的数据类型，可以将各种类型包装后统一放入容器内最重要的它是类型安全的。有点象COM里面的variant.		使用方法：any::type() 返回包装的类型any_cast可用于any到其他类型的转化												 																#include 				&lt;...&nbsp;&nbsp;<a href='http://www.cppblog.com/phenix_jiang/articles/4541.html'>阅读全文</a><img src ="http://www.cppblog.com/phenix_jiang/aggbug/4541.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/phenix_jiang/" target="_blank">拼命流血</a> 2006-03-24 16:16 <a href="http://www.cppblog.com/phenix_jiang/articles/4541.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>生成 ContentRotator ASP.NET 服务器控件</title><link>http://www.cppblog.com/phenix_jiang/articles/4539.html</link><dc:creator>拼命流血</dc:creator><author>拼命流血</author><pubDate>Fri, 24 Mar 2006 07:16:00 GMT</pubDate><guid>http://www.cppblog.com/phenix_jiang/articles/4539.html</guid><wfw:comment>http://www.cppblog.com/phenix_jiang/comments/4539.html</wfw:comment><comments>http://www.cppblog.com/phenix_jiang/articles/4539.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/phenix_jiang/comments/commentRss/4539.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/phenix_jiang/services/trackbacks/4539.html</trackback:ping><description><![CDATA[
		<!--NOINDEX_START-->
		<a name="top">
		</a> 
<div id="MNP_showtoc" style="DISPLAY: none; PADDING-LEFT: 15px; PADDING-BOTTOM: 15px; FONT: 11px Verdana; PADDING-TOP: 10px; HEIGHT: 23px"><span style="CURSOR: hand" onclick="top.MNPSearchFrame.showtoc()"><img style="MARGIN-RIGHT: 3px" height="16" alt="show toc" src="http://www.microsoft.com/library/mnp/2/gif/showtoc.gif" width="16" align="absMiddle" border="0" />show toc</span></div><!--NOINDEX_STOP--><table><tbody><tr><td><div style="PADDING-RIGHT: 15px; PADDING-LEFT: 20px; PADDING-BOTTOM: 0px; PADDING-TOP: 0px"><div class="ancestorLinks"><nobr><a href="http://www.microsoft.com/china/MSDN/library/default.mspx">欢迎来到 MSDN</a> &gt; </nobr><nobr><a href="http://www.microsoft.com/china/MSDN/library/WebServices/default.mspx">Web/服务</a></nobr></div><h1>生成 ContentRotator ASP.NET 服务器控件</h1><h2 class="subtitle"></h2><div class="date">发布日期： 2006-3-7<span class="datePipe"> | </span>更新日期： 2006-3-7</div><div class="overview"><p>Scott Mitchell<br />4GuysFromRolla.com</p><p>适用于：<br />ASP.NET 1.1</p><p><b>摘要：</b>介绍创建自定义、编译的 ASP.NET 服务器控件涉及的步骤，这种控件对所有的特定内容进行随机滚动，就像内置的 <a href="http://www.w3schools.com/asp/asp_adrotator.asp">AdRotator 控件</a>随机滚动一系列预定义的标语广告一样。在介绍 ContentRotator 控件的核心内容时，本文涉及到自定义 ASP.NET 控件开发的几个方面。</p><p><a href="http://download.microsoft.com/download/7/2/0/7201DDC0-4D9B-4721-9B9C-7C9AE1E2601B/ContentRotator.msi">下载 ContentRotator.msi</a>。</p></div><center><img title="" height="6" alt="*" src="http://img.microsoft.com/library/gallery/templates/MNP2.Common/images/3squares.gif" width="30" border="0" /></center><div style="HEIGHT: 18px"></div><h5 style="PADDING-TOP: 2px">本页内容</h5><table style="MARGIN-TOP: 7px; MARGIN-BOTTOM: 12px" cellspacing="0" cellpadding="0" border="0"><tbody><tr valign="top"><td><a href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/dnasppcontentrotator.mspx#EYB"><img height="9" alt="简介" hspace="4" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_down.gif" width="7" vspace="2" border="0" /></a></td><td class="onThisPage"><a href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/dnasppcontentrotator.mspx#EYB">简介</a></td></tr><tr valign="top"><td><a href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/dnasppcontentrotator.mspx#EYD"><img height="9" alt="考虑内容滚动" hspace="4" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_down.gif" width="7" vspace="2" border="0" /></a></td><td class="onThisPage"><a href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/dnasppcontentrotator.mspx#EYD">考虑内容滚动</a></td></tr><tr valign="top"><td><a href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/dnasppcontentrotator.mspx#EAG"><img height="9" alt="指定内容项" hspace="4" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_down.gif" width="7" vspace="2" border="0" /></a></td><td class="onThisPage"><a href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/dnasppcontentrotator.mspx#EAG">指定内容项</a></td></tr><tr valign="top"><td><a href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/dnasppcontentrotator.mspx#EOAAC"><img height="9" alt="确定要显示的内容项" hspace="4" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_down.gif" width="7" vspace="2" border="0" /></a></td><td class="onThisPage"><a href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/dnasppcontentrotator.mspx#EOAAC">确定要显示的内容项</a></td></tr><tr valign="top"><td><a href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/dnasppcontentrotator.mspx#E5DAC"><img height="9" alt="提供动态内容" hspace="4" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_down.gif" width="7" vspace="2" border="0" /></a></td><td class="onThisPage"><a href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/dnasppcontentrotator.mspx#E5DAC">提供动态内容</a></td></tr><tr valign="top"><td><a href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/dnasppcontentrotator.mspx#ECFAC"><img height="9" alt="自定义所选的内容项" hspace="4" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_down.gif" width="7" vspace="2" border="0" /></a></td><td class="onThisPage"><a href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/dnasppcontentrotator.mspx#ECFAC">自定义所选的内容项</a></td></tr><tr valign="top"><td><a href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/dnasppcontentrotator.mspx#EZFAC"><img height="9" alt="小结" hspace="4" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_down.gif" width="7" vspace="2" border="0" /></a></td><td class="onThisPage"><a href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/dnasppcontentrotator.mspx#EZFAC">小结</a></td></tr><tr valign="top"><td><a href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/dnasppcontentrotator.mspx#E6FAC"><img height="9" alt="特别鸣谢。 . . " hspace="4" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_down.gif" width="7" vspace="2" border="0" /></a></td><td class="onThisPage"><a href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/dnasppcontentrotator.mspx#E6FAC">特别鸣谢。 . . </a></td></tr><tr valign="top"><td><a href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/dnasppcontentrotator.mspx#E5GAC"><img height="9" alt="关于作者" hspace="4" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_down.gif" width="7" vspace="2" border="0" /></a></td><td class="onThisPage"><a href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/dnasppcontentrotator.mspx#E5GAC">关于作者</a></td></tr></tbody></table><a name="EYB"></a><h2>简介</h2><p>早在九十年代末期，似乎没有什么事情是不可能发生的。World Wide Web 及其对商业的影响急剧增加 — 孩子们退学建立 Web 站点而一夜暴富，企业也斥资数百万美元在黄金电视时段播放广告，吸引人们上网为宠物购买食物。没错，这就是新经济时代，相比于在令人乏味的建筑物中销售单调的旧产品而言，将数百万的 Web 网民吸引到 Web 站点来的确更有经济价值。</p><p>在这个浮华的时代，Microsoft 引入了 <a href="http://www.w3schools.com/asp/asp_adrotator.asp"><em>传统</em><em> ASP </em><em>的</em><em> AdRotator COM </em><em>组件</em></a>，它使崭露头角的 Web 企业家能够将标语广告轻松添加到他们的站点中。显示标语广告的第一步是具有一个列出可以显示的标语的 advertisements 文件。该文本文件包含有关每个标语的四类信息： </p><table cellspacing="0" cellpadding="0" border="0"><tbody><tr><td class="listBullet" valign="top">•</td><td class="listItem"><p>指向该标语图像的 URL </p></td></tr><tr><td class="listBullet" valign="top">•</td><td class="listItem"><p>该图像链接到的 URL </p></td></tr><tr><td class="listBullet" valign="top">•</td><td class="listItem"><p>该图像的替换文本 </p></td></tr><tr><td class="listBullet" valign="top">•</td><td class="listItem"><p>该标语相对于文件中其他标语的显示频率 </p></td></tr></tbody></table><p>使用该文本文件时，ASP 开发人员必需调用 AdRotator 的 GetAdvertisement(advertisementFile) 方法，从而传入到 advertisements 文件的路径，而 AdRotator 将返回 HTML 标记，用于显示从指定文件随机选择的标语广告。我想，这时候已经财源滚滚了。</p><p>2002 年交付 ASP.NET 时，新经济时代已经成为过去。NASDAQ 指数在 2000 年曾经攀升至 5,000 点左右，而现在已跌到 2,000 点以下。尽管 .com 彻底垮台，但 Microsoft 依旧对在线广告持乐观态度，缘由是他们已修整了 <a href="http://samples.gotdotnet.com/quickstart/aspplus/samples/webforms/ctrlref/webctrl/adrotator/doc_adrot.aspx"><em>传统</em><em> ASP </em><em>的</em><em> AdRotator </em><em>控件并进行了发布</em></a> — 作为一个标准 Web 控件与 ASP.NET 一起提供。AdRotator 的 ASP.NET 版本较之传统的 ASP 版本有以下几个优势： </p><table cellspacing="0" cellpadding="0" border="0"><tbody><tr><td class="listBullet" valign="top">•</td><td class="listItem"><p>advertisements 文件现已是 XML 格式化的，从而使页面开发人员可以更轻松地创建和编辑该文件的内容。 </p></td></tr><tr><td class="listBullet" valign="top">•</td><td class="listItem"><p>每个广告可以包含一个指示其所属类别的关键字。除了 AdRotator 的新 KeywordFilter 属性之外，这可用来限制针对具体 AdRotator 控件实例显示的标语集。 </p></td></tr><tr><td class="listBullet" valign="top">•</td><td class="listItem"><p>除了标准的广告属性集之外，页面开发人员可以将他们自己的附加设置添加到 advertisements 文件中。然后，添加的这些设置可由页面开发人员通过 AdRotator 的 AdCreated 事件以编程方式访问。 </p></td></tr></tbody></table><p>虽然 AdRotator 能更容易地随机显示来自预定义列表的标语，但是它存在很多缺点，在我看来，其中有两个主要的缺点： </p><table class="numberedList" cellspacing="0" cellpadding="0" border="0"><tbody><tr valign="top"><td class="listNumber" nowrap="" align="right"><p>1.</p></td><td><p>AdRotator 的内容只可以通过 XML 格式化的 advertisements 文件进行指定。这虽然不是一个主要限制，但是如果能够通过 AdRotator 的标记以声明方式指定内容，或者通过源代码以编程方式进行指定，则是比较理想的，这非常类似于针对 DropDownList Web 控件以声明方式或编程方式指定 ListItem。 </p></td></tr><tr valign="top"><td class="listNumber" nowrap="" align="right"><p>2.</p></td><td><p>AdRotator 在它可以生成的标记方面受到一些限制。顾名思义，它旨在显示广告，这些广告是文本或链接到某个 URL 的图像。只需进行少量工作，就可以将 AdRotator 创建为显示<i>任何</i> 类型的内容，而不仅仅是标语或文本广告。 </p></td></tr></tbody></table><p>第二个缺点特别让我感到烦恼，因为只需再进行少量工作就可以使 AdRotator 成为一个非常通用的内容滚动器，而不仅仅设计为只显示广告。在本文中，我们将通过创建一个全功能的 ContentRotator 服务器控件来克服该缺点以及其他缺点。</p><div style="MARGIN-TOP: 3px; MARGIN-BOTTOM: 10px"><a href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/dnasppcontentrotator.mspx#top"><img height="9" alt="返回页首" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_up.gif" width="7" border="0" /></a><a class="topOfPage" href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/dnasppcontentrotator.mspx#top">返回页首</a></div><a name="EYD"></a><h2>考虑内容滚动</h2><p>在深入研究任何编码项目之前，重要的是用充足的时间回答以下三个问题。 </p><table class="numberedList" cellspacing="0" cellpadding="0" border="0"><tbody><tr valign="top"><td class="listNumber" nowrap="" align="right"><p>1.</p></td><td><p><b>有满足我需要的现有控件吗？</b>如果您的工作和我类似，就是说每天有很多会议和电子邮件，还要花费更多时间进行其他繁忙的工作，则编写代码通常是一天中最有趣的活动。如果对问题产生了兴趣并通过代码找到该问题的解决方案，那么没有什么比这让令人兴奋了。 </p><p>但是，“有趣”与“具有经济价值”可完全是两码事。创建具体控件可能是有趣的，但如果已经存在能够提供所需功能的控件，那么花费时间生成、测试和调整此类控件就毫无经济意义可言。 </p><p>当我想创建新的服务器控件时，我首先会进入 <a href="http://asp.net/ControlGallery/Default.aspx?tabindex=0&amp;tabid=1"><em>ASP.NET Control Gallery</em></a>，看看我是不是在做无用功。快速查看 Control Gallery，显示<a href="http://asp.net/ControlGallery/default.aspx?Category=17&amp;tabindex=2"><em>用于</em><em> Content Rotators </em><em>的一个完整类别</em></a>。但是，这些内容滚动器（例如，新闻或股票自动接收器）的大多数都在单个页面滚动所有的内容。 </p><p>我发现有一个控件可以滚动完整的诸如 AdRotator 控件（<a href="http://blogs.duncanmackenzie.net/duncanma/"><em>Duncan Mackenzie </em><em>的</em><em></em></a>ContentRotator 用户控件，详述于文章 <a href="file:///C:/library/en-us/dncodefun/html/code4fun09072004.asp"><em>Rotating Is Fun</em></a>）的任意静态 HTML 内容。虽然 Duncan 的用户控件提供了 AdRotator 的基本功能且支持任意 HTML 内容，但我决定不使用他的解决方案，因为它并不提供我需要的功能。（例如，Duncan 的控件不允许为内容标记关键字。） </p><p>在搜索过程中，我没有找到满足需要的内容滚动器。因此我决定自己创建。（哈哈！老板，会议请先等一下吧，我现在要马上完成一个编程项目！） </p></td></tr><tr valign="top"><td class="listNumber" nowrap="" align="right"><p>2.</p></td><td><p><b>我的控件需要提供什么功能？</b>如果您决定创建自己的控件，请不要立即深入到最有趣的部分 — 编码；相反，您需要在开始编码之前清楚地了解该控件需要具有哪些功能。确定控件要求的一个好方法是设计常规用例，这些用例描述最终用户（在本例中是页面开发人员）将如何使用您的控件。在生成服务器控件时，我首先要自问的几个问题是： </p><table cellspacing="0" cellpadding="0" border="0"><tbody><tr><td class="listBullet" valign="top">•</td><td class="listItem"><p>页面开发人员将如何使用该控件？ </p></td></tr><tr><td class="listBullet" valign="top">•</td><td class="listItem"><p>他们需要该控件做什么？ </p></td></tr><tr><td class="listBullet" valign="top">•</td><td class="listItem"><p>语法应该如何？ </p></td></tr></tbody></table><p>在经过一番深思熟虑之后，我设计了以下四个用例： </p><p>Harry（一个很有前途的 ASP.NET 开发人员）想增强其公司的 Intranet，以便主页可以随机显示一个公司雇员的简历和照片。由于 Harry 的公司只有十多个雇员，因此他目前喜欢在一个文件中硬编码简历和照片，但希望日后可以对其进行升级，以便随着公司的发展从数据库检索这些项。他的目标是让 ContentRotator 从该文件随机选择一个雇员，每次访问时在主页上显示有关该雇员的信息。 </p><p>Jisun 是 BuyPetFoodOnline.com 的一位开发人员，这个网站是新启动的，关于它的风险投资能否取得回报都寄希望于 John Q 身上。大家对在线购买 Alpo 很感兴趣。BuyPetFoodOnline.com 上销售的所有宠物食物品牌都在一个 Microsoft SQL Server 数据库中维护。在该站点的主页上，Jisun 想显示最畅销的 10 种宠物食物品牌列表，或者各类狗食列表或猫食列表。此外，她希望每当狗食或猫食的内容组合时，最畅销的十个销售品牌内容平均显示两次。 </p><p>Todd 运行一个有关健身的 Web 站点，目前已有数千名会员在该站点上注册，注册信息包括姓名、出生日期、体重以及其他和健康相关的数据。在每页的底部，Jim 想针对访问者的个人信息显示随机健康统计信息。例如，他想显示以下消息：[[username]]、您已经活了 [[numberOfDaysSinceBirth]] 天、您的平均脉搏是 [[averageHeartRateTimesDaysAlive]]，其中每一个占位符均用特定于登录用户的值进行填充。 </p><p>成长中的 ASP.NET 开发人员 Darren 是一个 XML 的新手，他很担心在 XML 格式化的内容文件中指定内容项时会犯错误。Darren 非常熟悉 DropDownList Web 控件，经常使用 DropDownList 的描述性语法指定 ListItem。Darren 也希望能够以相同的方式为 ContentRotator 指定内容项。同样，他将能够以编程方式操作 ContentRotator 的内容项，使用的语法类似于以编程方式使用 DropDownList 的 ListItem 所需的语法。 </p><p>ContentRotator 的功能就是从这些用例中产生的，这些用例在 ContentRotator 的实现中提供指导。 </p></td></tr><tr valign="top"><td class="listNumber" nowrap="" align="right"><p>3.</p></td><td><p><b>有代码重用的可能性吗？</b>面向对象编程的一大好处是，可以轻松合并和扩展现有功能。在创建新服务器控件时，很可能已经存在提供类似功能的 ASP.NET 服务器控件。只扩展该现有服务器控件而不重新生成服务器控件可能吗？在现有控件基础上进行构建将节省大量的编码和测试时间。 </p><p>在开始创建用于 ContentRotator 的代码时，我实验了使 ContentRotator 扩展现有 ASP.NET AdRotator 控件的可能性。AdRotator 类包含了从广告文件读取项并随机选择一个适当项所需的方法和属性。我能够重用该类并重写发送标语或文本广告的特定方法，从而将其更改为返回更多一般内容的方法吗？ </p><p>我考虑了该方法，但由于以下原因决定不使用它。首先，AdRotator 的许多方法都没有标记为 virtual，这意味着它们不能重写。特别是，由于解析 advertisements 文件的方法不是虚拟的，因此我的派生类将必须使用 AdRotator 的现有 XML 格式。这不一定会限制 ContentRotator 的功能（由于 AdRotator 可以添加任意 XML 元素），但它仍然会产生一些限制，因为它将使用 advertisement 文件的 和 元素。此外，AdRotator 需要一个 元素，它对于一般内容滚动器来说是一个无法接受的要求。 </p></td></tr></tbody></table><p>在经过谨慎考虑之后，我最终准备开始编写代码 — 这是一个有趣的环节。在下文中，我将介绍 ContentRotator 控件的一些更有趣的代码，这些代码不仅可以揭示该特定控件的内部工作，还提供一个示例，用于在创建的服务器控件中实现相似的功能。</p><div style="MARGIN-TOP: 3px; MARGIN-BOTTOM: 10px"><a href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/dnasppcontentrotator.mspx#top"><img height="9" alt="返回页首" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_up.gif" width="7" border="0" /></a><a class="topOfPage" href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/dnasppcontentrotator.mspx#top">返回页首</a></div><a name="EAG"></a><h2>指定内容项</h2><p>ContentRotator 控件提供三种用于指定内容项的方式： </p><table class="numberedList" cellspacing="0" cellpadding="0" border="0"><tbody><tr valign="top"><td class="listNumber" nowrap="" align="right"><p>1.</p></td><td><p>通过 XML 格式的一个单独内容文件。 </p></td></tr><tr valign="top"><td class="listNumber" nowrap="" align="right"><p>2.</p></td><td><p>通过 ContentRotator 的声明性语法。 </p></td></tr><tr valign="top"><td class="listNumber" nowrap="" align="right"><p>3.</p></td><td><p>通过服务器端编程方法。 </p></td></tr></tbody></table><p>第一个选项使用一个外部文件提供对内容项更好的重用，因为单个内容文件可以通过单个 Web 站点中不同页上的许多内容滚动器使用。但是，有时您可能想快速创建简单的 ContentRotator 控件，而不必烦恼于创建单独的内容文件。在这些情况下，您可以使用第二个选项，并提供内容项来迭代通过该控件的声明性语法。最后一个选项允许您以编程方式指定内容项。如果需要动态选择可能的内容项，或者这些内容项存在于一个数据库或其他某个非静态存储中，则该选项是有用的。</p><p><b>通过内容文件指定内容</b></p><p>当在 XML 格式化内容文件中指定内容项时，必须针对具体的 XML 架构提供内容项。特别是，内容文件必须以 元素开头，该元素包含每个内容项的 元素。每个 项有三个可选属性： </p><table cellspacing="0" cellpadding="0" border="0"><tbody><tr><td class="listBullet" valign="top">•</td><td class="listItem"><p>impressions — 指定内容项的重要性，用来确定项显示的概率。 </p></td></tr><tr><td class="listBullet" valign="top">•</td><td class="listItem"><p>keyword — 指定内容项的<em>关键字</em>。ContentRotator 控件包含一个 KeywordFilter 属性，如果设置该属性，则将所显示的内容项限制为具有匹配的<em>关键字</em> 参数的内容项。 </p></td></tr><tr><td class="listBullet" valign="top">•</td><td class="listItem"><p>contentPath — 内容项可以包含静态 HTML 标记或代码驱动的动态内容。如果您想使用动态内容，可以通过该属性指定到 User Control 的路径。如果设置所选内容项的 contentPath 属性，则该内容通过指定的 User Control 生成。 </p></td></tr></tbody></table><p>元素也可以包含提供要显示的静态标记的文本。如果未提供 contentPath 属性，则显示该静态标记。</p><p>以下示例显示一个带有四个内容项的、正确进行格式化的内容文件。第一个内容项缺少任何可选属性，只由要显示的文本内容组成。第二个内容项提供 impressions 和 keyword 属性，而第三个内容项只设置 keyword 属性。请注意，如果您想在内容项的文本部分显示 HTML 标记，则需要像在第二个示例中一样转义 XML 标记，方法是使用 &lt; 和 &gt; 而不是 &lt; 和 &gt;，或者需要将整个内容包装在一个 部分中。第四个（最后一个）内容项引用一个 User Control (RichContent.ascx)，该控件通过 contentPath 属性指定。此外，impressions 属性设置为 5。</p><pre class="codeSample">&lt;?xml version="1.0" encoding="utf-8" ?&gt; 
&lt;contents&gt;
   &lt;content&gt;
      Things are just average... neither positive nor negative...
   &lt;/content&gt;
   &lt;content impressions="3" keyword="positiveComments"&gt;
      &lt;b&gt;You will soon see a workplace promotion.&lt;/b&gt;
   &lt;/content&gt;
   &lt;content keyword="positiveComments"&gt;
      &lt;![CDATA[
      Happiness is &lt;i&gt;just around the corner!&lt;/i&gt;
      ]]&gt;
   &lt;/content&gt;
   &lt;content contentPath="~/RichContent.ascx" impressions="5" /&gt;
&lt;/contents&gt;
</pre><p>该内容文件需要保存在 Web 服务器的文件系统中。要显示特定文件的内容，只需将 ContentRotator 添加到 ASP.NET 页，并将它的 ContentFile 属性设置为内容文件的虚拟路径。</p><p><b>注</b><b></b>要记住，XML 是区分大小写的，因此 XML 元素的大小写是重要的。如果您没有使用正确的大小写（例如，使用 而非 ），则不会从内容文件检索这些内容项，从而得到一个不发出任何内容项的 ContentRotator 控件。</p><p><b>声明性地指定内容项</b></p><p>许多 ASP.NET Web 内置控件允许其大多数属性用 Web 控件的声明性语法来指定。例如，您可以指定通过 声明性语法创建 DataGrid 的特定 DataGridColumn。ContentRotator 提供类似的声明性语法来指定它的内容项。对于 ContentRotator 要随机显示的每个项，请在 标记中添加一个 元素。每个 元素可以包含以下属性： </p><table cellspacing="0" cellpadding="0" border="0"><tbody><tr><td class="listBullet" valign="top">•</td><td class="listItem"><p>Content </p></td></tr><tr><td class="listBullet" valign="top">•</td><td class="listItem"><p>Impressions </p></td></tr><tr><td class="listBullet" valign="top">•</td><td class="listItem"><p>Keyword </p></td></tr><tr><td class="listBullet" valign="top">•</td><td class="listItem"><p>ContentPath </p></td></tr></tbody></table><p>这些属性分别映射到 元素的文本部分，以及 XML 内容文件架构的 impressions、keyword 和 contentPath 属性。（您可以选择将 Content 属性指定为该内部标记的文本内容，如下面的前两个 实例所示。）下面显示用于 ContentRotator 的声明性语法，其中带有前面使用的四个内容项。</p><pre class="codeSample">&lt;skm:ContentRotator id="ContentRotator1" runat="server"&gt;
   &lt;skm:ContentItem&gt;Things are just average... neither positive nor 
negative...&lt;/skm:ContentItem&gt;
   &lt;skm:ContentItem Impressions="3" Keyword="positiveComments"&gt;&lt;b&gt;You will soon see a workplace promotion 
&lt;/b&gt;&lt;/skm:ContentItem&gt;
   &lt;skm:ContentItem Content="Happiness is &lt;i&gt;just around the 
corner!&lt;/i&gt;" Keyword="positiveComments"&gt;&lt;/skm:ContentItem&gt;
   &lt;skm:ContentItem ContentPath="~/RichContent.ascx" Impressions="5"&gt;&lt;/skm:ContentItem&gt;
&lt;/skm:ContentRotator&gt; 
</pre><p>请注意，使用该声明性语法时，您无需使用 Content 属性来转义 HTML 字符。</p><p><b>以编程方式指定内容</b></p><p>为了协助内容和内容项的概念，ContentRotator 包含两个类： </p><table cellspacing="0" cellpadding="0" border="0"><tbody><tr><td class="listBullet" valign="top">•</td><td class="listItem"><p>ContentItem—抽象地表示带有诸如 Content、ContentPath、Keyword、Impressions 等属性的内容项。 </p></td></tr><tr><td class="listBullet" valign="top">•</td><td class="listItem"><p>ContentItemCollection—强类型化的 ContentItem 实例集合。 </p></td></tr></tbody></table><p>ContentRotator 控件包含类型 ContentItemCollection 的一个 Items 属性。您可以通过将 ContentItem 实例添加到 Items Items 属性，以编程方式指定，当随机选择项时 ContentRotator 应该考虑的内容项。和其他 ASP.NET 服务器控件一样，添加到 Items 属性的内容存储在该控件的视图状态中，因此，您只需在第一次页访问时添加这些项，而不是在随后的回调中进行添加。下面的代码片段显示了如何以编程方式添加前面两个示例中使用的内容项集合：</p><pre class="codeSample">private void Page_Load(object sender, System.EventArgs e)
{
   if (!Page.IsPostBack)
   {
      // only need to load content items on first page visit – 
they are persisted across
      // postbacks in the ViewState...

      ContentRotator1.Items.Add(new ContentItem("Things are just 
average... neither positive nor negative..."));

      ContentRotator1.Items.Add(new ContentItem(" You will 
soon see a workplace promotion ", string.Empty, "positiveComments", 3));

      ContentItem thirdCI = new ContentItem();
      thirdCI.Content = "Happiness is just around the 
corner!";
      thirdCI.Keyword = "positiveComments";
      ContentRotator1.Items.Add(thirdCI);
      
      // Add dynamic content
      ContentRotator1.Items.Add(new ContentItem(string.Empty, 
"~/RichContent1.ascx", string.Empty, 5));
   }
}
</pre><p>如您所见，ContentItem 类有大量构造函数重载，它们可以将创建新 ContentItem 实例并设置其属性的代码减至一行。</p><p>如果您不想阅读代码详细信息，而直接开始在 ASP.NET 应用程序中使用 ContentRotator，则您可以跳过下文并从本文顶部的链接下载控件。该下载包括 ContentRotator 控件（以 C# 编写）的完整源代码，以及一个示例 ASP.NET Web 应用程序（也以 C# 编写），该程序显示针对上面所讨论用例的解决方案。此外，该下载还包括一个外观漂亮、经编译的帮助文件，用来帮助决定使用 ContentRotator 控件的页面开发人员。</p><div style="MARGIN-TOP: 3px; MARGIN-BOTTOM: 10px"><a href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/dnasppcontentrotator.mspx#top"><img height="9" alt="返回页首" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_up.gif" width="7" border="0" /></a><a class="topOfPage" href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/dnasppcontentrotator.mspx#top">返回页首</a></div><a name="EOAAC"></a><h2>确定要显示的内容项</h2><p>每次访问带有 ContentRotator 控件的页时，ContentRotator 必须决定要随机显示什么内容。每个内容项有一个相关的 <i>impressions</i> 值，该值影响到该内容项相对于其他内容项被选中的可能性。该 impressions 参数是一个正整数值，在不指定的情况下，默认值为 1。此外，每个内容项可以有一个可选的<i>关键字</i> 参数。如果指定 ContentRotator 控件的 KeywordFilter 属性，则将用于显示的内容项集合限制为那些具有匹配<em>关键字</em> 值的内容项。</p><p>用于随机选择内容项的算法的工作方式为：将每个可应用的内容项以端对端方式进行布局，从而形成一行。每个内容项的长度是它的 impressions 值，这意味着该行的整体长度是可应用的内容项 impressions 的总和。接下来，选择一个小于总长度的随机数，而要显示的内容项是位于随机数位置的内容项。图 1 以图形方式阐释该算法。</p><div style="WIDTH: 450px"><img height="74" alt="" src="http://www.microsoft.com/china/msdn/library/webservices/asp.net/art/ContentRotator1S.gif" width="450" border="0" /><br /><p class="figureCaption"><b>图</b><b> 1.</b></p><div class="figureRule"></div></div><p>为了应用此算法，ContentRotator 控件首先需要检索要考虑的内容项列表。想必您还记得，该列表可能作为 XML 文件驻留在磁盘上，它可以用 ContentRotator 的声明性语法指定，或者以编程方式提供。让我们看看如何使用这三种技术访问该内容项列表。 </p><p><b>从内容文件读取内容数据</b></p><p>ContentRotator 有一个 ContentItemCollection 类型的 Items 属性，它包含由 ContentRotator 控件考虑的可应用内容项集。（相信您还记得，该可应用内容项集依赖于是否设置了该控件的 KeywordFilter 属性，如果设置了该属性，还取决于内容项的<em>关键字</em><em></em>参数。）Items 属性通过调用 GetFileData(virtualFilePath) 方法，在 Load 事件中进行填充。该方法返回一个 ContentItemCollection 实例，它包含由 <i>virtualFilePath</i> 参数指定的内容文件中的<em>所有</em> 内容项。</p><p>在每次访问页面时打开、读取并解析整个内容文件将是无效和不必要的，特别是在考虑到该文件可能很少进行更改的情况下。要提高性能，需要使用一个文件依赖项缓存该内容文件中的项。这意味着该内容文件中的项将驻留在用于提高性能的缓存中，但是当基础内容文件修改时，该缓存项将自动失效。以下 GetFileData(filePath) 方法的代码阐释该缓存行为：</p><pre class="codeSample">// See if the item exists in the cache
string cacheKey = string.Concat("ContentRotateCacheKey:", 
physicalFilePath);

ContentItemCollection cachedContent = (ContentItemCollection) 
HttpContext.Current.Cache[cacheKey];
if (cachedContent == null)
{
   // it's *not* in the cache, must manually get the file data and cache it
   cachedContent = LoadFile(physicalFilePath);
   if (cachedContent == null)
      return null;
   else
      // Add the content to the cache
      HttpContext.Current.Cache.Insert(cacheKey, cachedContent, 
new CacheDependency(physicalFilePath));
}

// return the cached content
return cachedContent;
</pre><p>变量 physicalFilePath 包含到该内容文件的物理路径，并用于形成缓存键。这确保了每个不同的内容文件都将有其自己的缓存项。接下来，访问 Cache 对象，从而检索名为 cacheKey 的缓存项的值。如果该项是 null（由于该缓存中没有插入此类项，或者缓存项已失效），则来自内容文件的内容和基于内容文件的缓存依赖项一起加载并插入到该缓存中。</p><p>LoadFile(physicalFilePath) 方法使用 XPathNodeIterator 迭代通过内容文件，从而清除多种属性和文本内容，并为该内容文件中的每一项生成一个 ContentItem 实例。每个 ContentItem 实例添加到 ContentItemCollection，它在该方法的结果中返回。以下代码显示了迭代通过内容文件中每一项的过程；fStream 是该内容文件的一个打开的文件流。</p><pre class="codeSample">// Use an XPathNavigator to iterate through the XML elements in the ContentFile
reader = new XmlTextReader(fStream);
XPathDocument xpDoc = new XPathDocument(reader);
XPathNavigator xpNav = xpDoc.CreateNavigator();

XPathNodeIterator xmlItems = xpNav.Select("/contents/content");

XPathExpression contentExpr = xpNav.Compile("string(text())");
XPathExpression contentPathExpr = xpNav.Compile("string(@contentPath)");
XPathExpression keywordExpr = xpNav.Compile("string(@keyword)");
XPathExpression impressionsExpr = xpNav.Compile("string(@impressions)");

if (xmlItems == null)
   throw new FormatException("ContentFile in invalid format.");
else
{
   while (xmlItems.MoveNext())
   {
      string content = (string) xmlItems.Current.Evaluate(contentExpr);
      string contentPath = (string) xmlItems.Current.Evaluate(contentPathExpr);
      string keyword = (string) xmlItems.Current.Evaluate(keywordExpr);
      string impressionsStr = (string) xmlItems.Current.Evaluate(impressionsExpr);

      int impressions = 1;      // default impressions value is 1
      if (impressionsStr != null &amp;&amp; impressionsStr.Length &gt; 0)
         impressions = Convert.ToInt32(impressionsStr, 
CultureInfo.InvariantCulture);

      contentItems.Add(new ContentItem(content.Trim(), 
contentPath, keyword, impressions));
   }
}
</pre><p>XPathNodeIterator 逐行通过每个 元素，从而应用一个 XPathExpression 来挑选每个属性和文本内容。当迭代每个 项之后，创建 ContentItem 实例，并为它的属性分配来自 XPathExpression 的值。每个 ContentItem 实例添加到 ContentItemCollection 实例，该实例稍后从 LoadFile(physicalFilePath) 方法返回。</p><p><b>以编程方式读取内容数据</b></p><p>为了以编程方式将项添加到任何类型的 Web 控件，您需要执行以下三个步骤： </p><table class="numberedList" cellspacing="0" cellpadding="0" border="0"><tbody><tr valign="top"><td class="listNumber" nowrap="" align="right"><p>1.</p></td><td><p>创建一个表示要添加项的类。</p></td></tr><tr valign="top"><td class="listNumber" nowrap="" align="right"><p>2.</p></td><td><p>创建一个表示项集合的类。 </p></td></tr><tr valign="top"><td class="listNumber" nowrap="" align="right"><p>3.</p></td><td><p>为该 Web 控件添加一个属性，其类型为在步骤 2 中定义的类。该属性保留用于该控件的项集。 </p></td></tr></tbody></table><p>要实际查看这些步骤，请考虑内置的 ASP.NET DropDownList Web 控件，该控件包含组成 DropDownList 的可用选择的项集合。每一项都由 ListItem 类的实例表示（步骤 1）。ListItemCollection 类提供强类型的 ListItem 实例集合（步骤 2），而且 DropDownList 类具有类型 ListItemCollection 的一个 Items 属性（步骤 3）。利用 ASP.NET 页的源代码片段，DropDownList 可以通过以下语法使 ListItem 实例以编程方式添加到其中：</p><p><b>DropDownList1.Items.Add(new ListItem(</b><b><i>text</i></b><b>, </b><b><i>value</i></b><b>));</b></p><p>为了使用 ContentRotator 实现类似的功能，我创建了 ContentItem 类来表示一个特定的内容项。如前所述，该类具有特定于内容项的属性，例如，Content 和 Impressions，等等。接下来，我创建了一个 ContentItemCollection 类，它提供 ContentItem 实例的强类型集合。最后，我在 ContentRotator 类中创建了一个 ContentitemCollection 类型的 Items 属性。</p><p>当创建了这些类和属性之后，页面开发人员能够以编程方式将内容添加到 ContentRotator 中，其语法与 DropDownList 的语法不同：</p><pre class="codeSample">ContentRotator1.Items.Add(new ContentItem(content));
ContentRotator1.Items.Add(new ContentItem(content, contentPath, 
keyword, impressions));
...
</pre><p><b>从该控件的声明性语法读取内容</b></p><p>除了能够以编程方式指定项之外，很多 Web 控件也可以使页面开发人员能够通过该控件的声明性语法指定项集。例如，通过 DropDownList，能够以声明方式说明 ListItem，如下所示：</p><pre class="codeSample">&lt;asp:DropDownList runat="server" ...&gt;
  &lt;asp:ListItem Value="value1"&gt;text1&lt;/asp:ListItem&gt;
  &lt;asp:ListItem Value="value2" Text="text2"&gt;&lt;/asp:ListItem&gt;
  ...
  &lt;asp:ListItem Value="valueN"&gt;textN&lt;/asp:ListItem&gt;
&lt;/asp:DropDownList&gt;
</pre><p>将该功能添加到 ContentRotator 非常简单，这是因为我们已经定义了 ContentItem 类，而且还具有用于 ContentRotator 控件的 Items 属性。我们只需使用两个属性，以便指示用声明性语法指定的项映射到该 ContentRotator 的 Items 属性。 </p><p>首先，在类级别添加 ParseChildren() 属性，从而指示应该解析该子标记，而且它映射到 Items 属性：</p><pre class="codeSample">[ParseChildren(true, "Items")]
public class ContentRotator : Control
{
   ...
}
</pre><p>最后，将 <span class="codeSample">PersistenceMode()</span> 属性添加到 <span class="codeSample">Items</span> 属性声明，从而指示该 <span class="codeSample">Items</span> 属性将作为内部默认属性保留。</p><pre class="codeSample">[PersistenceMode(PersistenceMode.InnerDefaultProperty]
public ContentItemCollection Items
{
   get { ... }
}
</pre><p>这就是所有的步骤。通过这两个属性，页面开发人员能够用该控件的声明性语法指定内容项，如下所示：</p><pre class="codeSample">&lt;skm:ContentRotator runat="server" ...&gt;
  &lt;skm:ContentItem Content="content" ContentPath="contentPath" 
Keyword="keyword" Impressions="impressions"&gt;&lt;/skm:ContentItem&gt;
  ...
&lt;/skm:ContentRotator&gt;
</pre><p>需要注意的是，对于我们当前的代码，ContentItem 实例的所有属性必须作为 元素的属性指定。理想情况下，页面开发人员将能够指定静态内容，方法是利用 Content 属性或 和 标记之间的文本内容。为此，我们需要将一小段代码添加到 ContentItem 类，从而指示该类应该解析内部文本内容。</p><p>特别是，ContentItem 类需要实现 IParserAccessor 接口，该接口定义一个简单的方法 AddParsedSubObject(object)。AddParsedSubObject(object) 方法以声明性语法传入 元素的内容。如果内部内容是纯文本，则传入 LiteralControl 实例。在本例中，我们想将 LiteralControl 的 Text 属性分配给 ContentItem 实例的 Content 属性。这是通过以下代码实现的：</p><pre class="codeSample">public class ContentItem : IParserAccessor
{
   ...

   public void AddParsedSubObject(object obj)
   {
      if (obj is LiteralControl)
         Content = ((LiteralControl) obj).Text;
      else
         throw new HttpException(...);
   }
   #endregion
}
</pre><p><b>选择一个随机内容项</b></p><p>当在 Load 事件中检索 ContentRotator 的 Items 属性之后，调用 SelectContentFromItems() 方法。该方法返回从 Items 集合随机选择的 ContentItem 实例。如果设置了 ContentRotator 的 KeywordFilter 属性，它将从集合中移除不可用的项。然后，它为剩余的项确定 impressions 参数的总数，并在 0 和 impressions 总数减去 1 所得的数之间随机选择一个数。基于该随机数选择并返回适当的内容项。</p><p>以下代码显示如何移除不可用项以及如何计算 impressions 的总数（在设置了 KeywordFilter 属性的情况下）。接下来，选择一个随机 impressions，并返回适当的 ContentItem 实例。</p><pre class="codeSample">// Determine the sum of the Impressions
int totalWeight = 0, i = 0;
string controlsKeywordFilter = this.KeywordFilter;
ContentItemCollection filteredArray = new ContentItemCollection();

for (i = 0; i &lt; Items.Count; i++)
   // only add the content item to the list of filtered content 
// items if the KeywordFilter property hasn't been set or,
   // if it has, if the KeywordFilter matches the content item's
// keyword attribute.
   if (controlsKeywordFilter.Length == 0 || 
      CultureInfo.InvariantCulture.CompareInfo.Compare(Items[i].Keyword, controlsKeywordFilter, 
CompareOptions.IgnoreCase) == 0)
   {
      totalWeight += Items[i].Impressions;   // increment the totalWeight
      filteredArray.Add(Items[i]);
   }
      

// Randomly choose a number between 0 and totalWeight - 1
int randomWeight = random.Next(totalWeight);

totalWeight = 0;

// Now grab the appropriate ContentItem based on randomWeight
i = 0; 
while (i &lt; filteredArray.Count &amp;&amp; (totalWeight + 
filteredArray[i].Impressions) &lt;= randomWeight)
   totalWeight += filteredArray[i++].Impressions;

return filteredArray[i];
</pre><div style="MARGIN-TOP: 3px; MARGIN-BOTTOM: 10px"><a href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/dnasppcontentrotator.mspx#top"><img height="9" alt="返回页首" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_up.gif" width="7" border="0" /></a><a class="topOfPage" href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/dnasppcontentrotator.mspx#top">返回页首</a></div><a name="E5DAC"></a><h2>提供动态内容</h2><p>确定了显示哪个内容项就成功了一半。我们也需要能够实际显示所选的内容项。这是在 SelectContentFromItems() 方法指定显示什么内容项之后，在 Load 事件中实现的。如果该项包含静态内容（即，如果它没有设置它的 ContentPath 属性），则会创建一个新 LiteralControl 实例，并将它添加到 ContentRotator 的控件层次结构，将其 Text 属性设置为要显示的静态内容的值。</p><p>但是，如果要显示的内容是动态的（即，设置了它的 ContentPath 属性，从而指定将提供动态内容的 User Control），则调用 Page 的 LoadControl(path) 方法加载特定 User Control 的控件层次结构。该控件层次结构的根通过 LoadControl() 方法返回，而且该控件添加到 ContentRotator 的控件层次结构。图 2 以图形方式阐释该过程。</p><div style="WIDTH: 450px"><img height="534" alt="" src="http://www.microsoft.com/china/msdn/library/webservices/asp.net/art/ContentRotator2S.gif" width="450" border="0" /><br /><p class="figureCaption"><b>图</b><b> 2.</b></p><div class="figureRule"></div></div><p>默认情况下，ContentRotator 将随机选择要在<i>每次</i> 访问页时显示的内容项，包括针对相同页的回调。如果您需要跨回调来显示相同的随机检索内容项，则只需简单地将 ContentRotator 的 NewContentOnPostbacks 设置为 false。如果您要使用需要回调的动态内容（例如，一个提示用户进行某些输入，并利用回调显示关于该输入的详细信息用户控件），然后您需要将 NewContentOnPostbacks 设置为 false。如果您使 NewContentOnPostbacks 保留其默认值 true，则当该用户从随机选择的 User Control 回调时，ContentRotator 可能选择一个不同的内容项，而这样会丢失回调数据。</p><p>实际上，无论加载的内容是静态的还是动态的，如果 NewContentOnPostbacks 属性设置为 true，ContentRotator 的控件层次结构都会禁用它的视图状态。这是因为回调时，ContentRotator 可能选择与上次访问页面时不同的内容项。如果本例中 ContentRotator 不禁用视图状态，则如果已经随机选择了一个不同的内容项，将在加载视图状态阶段引发一个异常。但是，如果 NewContentOnPostbacks 属性设置为 false，则维持 ContentRotator 控件层次结构的视图状态。</p><p><b>注</b><b></b>有关使用 LoadControl() 方法以编程方式加载用户控件的更多信息，请一定要阅读我以前撰写的文章 <a href="http://msdn.microsoft.com/asp.net/default.aspx?pull=/library/en-us/dnaspp/html/usercontrols.asp" target="_blank">An Extensive Examination of User Controls</a>。关于视图状态和相关问题的信息位于 <a href="http://msdn.microsoft.com/asp.net/default.aspx?pull=/library/en-us/dnaspp/html/viewstate.asp" target="_blank">Understanding ASP.NET View State</a>。</p><div style="MARGIN-TOP: 3px; MARGIN-BOTTOM: 10px"><a href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/dnasppcontentrotator.mspx#top"><img height="9" alt="返回页首" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_up.gif" width="7" border="0" /></a><a class="topOfPage" href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/dnasppcontentrotator.mspx#top">返回页首</a></div><a name="ECFAC"></a><h2>自定义所选的内容项</h2><p>ContentRotator 的功能要求之一是，允许页面开发人员在内容项中指定动态占位符。例如，页面开发人员应该能够创建带有内容文本“The current time is [[time]]”的内容项，并用当前系统时间动态取代 [[time]] 占位符。我得出两个方法来解决这个问题： </p><table class="numberedList" cellspacing="0" cellpadding="0" border="0"><tbody><tr valign="top"><td class="listNumber" nowrap="" align="right"><p>1.</p></td><td><p>提供一个预定义的占位符集，用于进行动态替换。 </p></td></tr><tr valign="top"><td class="listNumber" nowrap="" align="right"><p>2.</p></td><td><p>允许页面开发人员决定使用什么占位符以及用什么值替换它们。 </p></td></tr></tbody></table><p>第一个选项是这两个中较容易实现的一个：我可以在 ContentRotator 控件的 Load 事件中进行检查，该事件可以使用相应的动态值系统地替换所选内容项中的所有预定义占位符。虽然该方法易于实现，但我想它不会提供页面开发人员所需的自定义级别。</p><p>因此，我将定义占位符并填充动态值的工作完全留给页面开发人员。页面开发人员可以制作他需要的任何占位符，从而在该内容文件中或通过声明性语法将它们添加到这些内容项的文本内容。我只需为页面开发人员提供映射到所选内容项的机制。为此，我使用 ContentRotator 公开一个 ContentCreated 事件。每次访问页面时，只要选择要显示的内容项，就会激发该事件。 </p><p>页面开发人员可以创建一个用于该事件的事件处理程序。在该事件处理程序中，页面开发人员将接收所选的用于显示的 ContentItem 实例。此时，可以搜索该内容项的文本来获取要用其动态值替换的占位符。下面的示例阐明这一行为。ContentRotator 有三个通过声明性语法定义的内容项，其中两个带有动态占位符。</p><pre class="codeSample">&lt;skm:ContentRotator id="ContentRotator1" runat="server"&gt;
   &lt;skm:ContentItem Content="The current time is 
[[time]]."&gt;&lt;/skm:ContentItem&gt;
   &lt;skm:ContentItem Content="Hello, World! Nothing dynamic 
here!"&gt;&lt;/skm:ContentItem&gt;
   &lt;skm:ContentItem Content="Welcome to page 
[[url]]."&gt;&lt;/skm:ContentItem&gt;
&lt;/skm:ContentRotator&gt; 
</pre><p>在 ASP.NET 页的代码隐藏类中，创建事件处理程序并将其绑定到 ContentRotator 的 ContentCreated 事件。该事件处理程序的第二个参数是类型 ContentCreatedEventArgs，该参数在其 ContentItem 属性中包含所选的 ContentItem 实例。如以下代码所示，该事件处理程序使用当前系统时间替换 [[time]] 的任何实例，并使用当前页的 URL 替换 [[url]] 的任何实例。</p><pre class="codeSample">private void ContentRotator1_ContentCreated(object sender, 
skmContentRotator.ContentCreatedEventArgs e)
{
   // Replace [[time]] with DateTime.Now.TimeOfDay
   e.ContentItem.Content = e.ContentItem.Content.Replace("[[time]]", 
DateTime.Now.TimeOfDay.ToString());

   // Replace [[url]] with Request.RawUrl
   e.ContentItem.Content = e.ContentItem.Content.Replace("[[url]]", 
Request.RawUrl);
}
</pre><p><b>注</b><b></b>占位符（在本例中是 [[time]] 和 [[url]]）由页面开发人员决定。即页面开发人员可以使用他选择作为占位符的任何名称和标记。例如，我们可以使用 *currentTime*（而不是 [[time]]）作为占位符，从而将 [[time]] 的所有实例替换为内容文件和事件处理程序中的 *currentTime*。</p><div style="MARGIN-TOP: 3px; MARGIN-BOTTOM: 10px"><a href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/dnasppcontentrotator.mspx#top"><img height="9" alt="返回页首" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_up.gif" width="7" border="0" /></a><a class="topOfPage" href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/dnasppcontentrotator.mspx#top">返回页首</a></div><a name="EZFAC"></a><h2>小结</h2><p>随着 .com 泡沫的衰退，诸如 Microsoft 的 Ad Rotator 一类的控件正逐渐过时。但是，Ad Rotator 的概念是很好的，而且在很多方案中，一般内容滚动控件证明是无价的。本文展示的 ContentRotator 控件应该适合这些情况中的大多数。ContentRotator 提供的语义和语法与 Ad Rotator 控件的相似，包括用于内容项的一个 impressions 值，关键字筛选，以及一个允许页面开发人员映射所选内容项的事件。此外，ContentRotator 允许以声明方式指定它的内容项，并允许静态和动态内容。</p><p>祝大家编程愉快！</p><div style="MARGIN-TOP: 3px; MARGIN-BOTTOM: 10px"><a href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/dnasppcontentrotator.mspx#top"><img height="9" alt="返回页首" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_up.gif" width="7" border="0" /></a><a class="topOfPage" href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/dnasppcontentrotator.mspx#top">返回页首</a></div><a name="E6FAC"></a><h2>特别鸣谢。 . . </h2><p>在我将文章提交给 MSDN 编辑之前，很多志愿者帮助校对了本文并针对本文的内容、语法和说明提供了反馈。在本文的校对过程中作出过主要贡献的人主要有 <a href="mailto:jabe@lxdassociates.com"><em>Julius Estrada</em></a>、<a href="http://hilton.giesenow.com/"><em>Hilton Giesenow</em></a>、<a href="http://www.aspnetresources.com/"><em>Milan Negovan</em></a>、Carl Lambrecht 和 <a href="mailto:%20Jeffrey_Palermo@Dell.com"><em>Jeffrey Palermo</em></a>。校对人员这个团体正在不断扩增加，如果您想成为其中的一员，请通过 <a href="mailto:mitchell@4guysfromrolla.com"><em>mitchell@4guysfromrolla.com</em></a> 与我联系。 </p><div style="MARGIN-TOP: 3px; MARGIN-BOTTOM: 10px"><a href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/dnasppcontentrotator.mspx#top"><img height="9" alt="返回页首" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_up.gif" width="7" border="0" /></a><a class="topOfPage" href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/dnasppcontentrotator.mspx#top">返回页首</a></div><a name="E5GAC"></a><h2>关于作者</h2><p>Scott Mitchell（出版过有关 Web 开发的六本书籍，并且是 4GuysFromRolla.com 的创立者）在过去七年中一直研究 Microsoft Web 技术。Scott 是一名独立的顾问、讲师和作家。您可以通过 <a href="mailto:mitchell@4guysfromrolla.com"><em>mitchell@4guysfromrolla.com</em></a> 或他的网络日记 <a href="http://scottonwriting.net/"><em>http://ScottOnWriting.NET</em></a> 与他联系。</p><p><a href="http://msdn.microsoft.com/asp.net/default.aspx?pull=/library/en-us/dnaspp/html/contentrotator.asp" target="_blank">转到原英文页面</a></p><br style="FONT-SIZE: 0pt" clear="all" /><div style="MARGIN-TOP: 16px; MARGIN-BOTTOM: 20px; WIDTH: 100%"><table cellspacing="0" cellpadding="0" width="100%" border="0"><tbody><tr><td><a href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/dnasppcontentrotator.mspx#top"><img height="9" alt="返回页首" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_up.gif" width="7" border="0" /></a><a class="topOfPage" href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/dnasppcontentrotator.mspx#top">返回页首</a></td></tr></tbody></table></div></div></td></tr></tbody></table><!--NOINDEX_START--><script language="javascript"><![CDATA[
              var framesValid = false;
              if (window.name == "MNPMainFrame")
              { var menuFrame = parent.frames["MNPMenuFrame"]; if (menuFrame) { framesValid = true; } }
              if (!framesValid) location.replace("/china/msdn/library/webservices/asp.net/dnasppcontentrotator.mspx?mfr=true");
              
                else document.write('<layer visibility="hide"><div style="display:none"><img alt="" width="0" height="0" border="0" hspace="0" vspace="0" src="http://c.microsoft.com/trans_pixel.asp?source=www&amp;TYPE=PV&amp;p=china_msdn_library_webservices_asp.net&amp;URI=%2fchina%2fmsdn%2flibrary%2fwebservices%2fasp.net%2fdnasppcontentrotator.mspx&amp;GUID=1F4FC18C-F71E-47FB-8FC9-612F8EE59C61&amp;r=http%3a%2f%2fwww.microsoft.com%2fCHINA%2fmnp_utility.mspx%2fframesmenu%3furl%3d%2fchina%2fmsdn%2flibrary%2fwebservices%2fWebApp%2fBlogging.mspx&amp;lc=zh-chs"></div>/layer>');
              
              top.document.title = self.document.title;
            ]]&gt;</script><layer visibility="hide"><div style="DISPLAY: none"><img height="0" alt="" hspace="0" src="http://c.microsoft.com/trans_pixel.asp?source=www&amp;TYPE=PV&amp;p=china_msdn_library_webservices_asp.net&amp;URI=%2fchina%2fmsdn%2flibrary%2fwebservices%2fasp.net%2fdnasppcontentrotator.mspx&amp;GUID=1F4FC18C-F71E-47FB-8FC9-612F8EE59C61&amp;r=http%3a%2f%2fwww.microsoft.com%2fCHINA%2fmnp_utility.mspx%2fframesmenu%3furl%3d%2fchina%2fmsdn%2flibrary%2fwebservices%2fWebApp%2fBlogging.mspx&amp;lc=zh-chs" width="0" border="0" /></div></layer><table cellspacing="0" cellpadding="0" width="100%" border="0"><tbody><tr valign="bottom"><td><iframe id="footerId" style="HEIGHT: 260px" name="footerId" marginwidth="0" marginheight="0" src="/library/gallery/components/ratingControl/ratings.aspx?rurl=http%3a%2f%2fwww.microsoft.com%2fchina%2fmsdn%2flibrary%2fwebservices%2fasp.net%2fdnasppcontentrotator.mspx&amp;l=zh-chs&amp;f=True&amp;d=LTR&amp;t=%e7%94%9f%e6%88%90+ContentRotator+ASP.NET+%e6%9c%8d%e5%8a%a1%e5%99%a8%e6%8e%a7%e4%bb%b6" frameborder="0" width="100%" scrolling="no"></iframe></td></tr></tbody></table><br style="OVERFLOW: hidden; LINE-HEIGHT: 1px" clear="all" /><table id="msviFooter" cellspacing="0" cellpadding="0" width="100%"><tbody><tr valign="bottom"><td id="msviFooter2" style="FILTER: "><div id="msviLocalFooter"><nobr><a href="https://profile.microsoft.com/RegSysProfileCenter/Infodefault.aspx?LCID=2052" target="_top">个人信息中心</a> |</nobr><wbr></wbr><nobr><a href="http://www.microsoft.com/china/newsletter/case/MSDN.asp" target="_parent">MSDN中文速递邮件</a> |</nobr><wbr></wbr><nobr><a href="http://www.microsoft.com/china/MSDN/feedback/" target="_parent">联系我们</a></nobr></div><div id="msviGlobalFooter"><span dir="ltr">©2006 Microsoft Corporation. 版权所有.  </span><nobr><a href="http://www.microsoft.com/china/misc/cpyright.htm" target="_parent">保留所有权利</a> |</nobr><wbr></wbr><nobr><a href="http://www.microsoft.com/library/toolbar/3.0/trademarks/zh-cn.mspx" target="_top">商标</a> |</nobr><wbr></wbr><nobr><a href="http://www.microsoft.com/info/cn/privacy.mspx" target="_top">隐私权声明</a></nobr></div></td><td width="105" bgcolor="#669aff"><img title="" height="29" alt="Microsoft" src="http://www.microsoft.com/library/toolbar/3.0/text.aspx?t=TQ%3d%3d&amp;f=FFFFFF&amp;b=669AFF&amp;font=Microsoft+Logo+95%2c+13pt&amp;w=105&amp;h=29&amp;a=0&amp;l=0&amp;v=0&amp;c=eAdQAhJgwJihw2DKZGDGx4FnKIM%3d" width="105" border="0" /></td></tr></tbody></table><script language="javascript"><![CDATA[       var msviFooter2;        if (document.getElementById)        {        msviFooter2 = document.getElementById("msviFooter2");        msviFooter2.style.filter = "";        }      ]]&gt;</script><table style="WIDTH: 397px; ; WIDTH: expression(msviFooter2.offsetWidth); HEIGHT: 86px; ; HEIGHT: expression(msviFooter2.offsetHeight+1)" height="58" cellspacing="0" cellpadding="0" width="100%"><tbody><tr valign="top"><td><div style="WIDTH: 200px"></div></td><td style="FILTER: progid:DXImageTransform.Microsoft.Gradient(startColorStr='#FFFFFF', endColorStr='#669AFF', gradientType='1')" width="100%"></td></tr></tbody></table><img src ="http://www.cppblog.com/phenix_jiang/aggbug/4539.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/phenix_jiang/" target="_blank">拼命流血</a> 2006-03-24 15:16 <a href="http://www.cppblog.com/phenix_jiang/articles/4539.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>实际使用“DXML”：在站点上实现 DHTML 菜单和目录</title><link>http://www.cppblog.com/phenix_jiang/articles/4536.html</link><dc:creator>拼命流血</dc:creator><author>拼命流血</author><pubDate>Fri, 24 Mar 2006 07:00:00 GMT</pubDate><guid>http://www.cppblog.com/phenix_jiang/articles/4536.html</guid><wfw:comment>http://www.cppblog.com/phenix_jiang/comments/4536.html</wfw:comment><comments>http://www.cppblog.com/phenix_jiang/articles/4536.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/phenix_jiang/comments/commentRss/4536.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/phenix_jiang/services/trackbacks/4536.html</trackback:ping><description><![CDATA[
		<!-- Begin Content --> 
<h1><a name="top" idx_concept="stopindex; DXML, 实施菜单和 TOC">实际使用“DXML”：在站点上实现 DHTML 菜单和目录</a></h1><hr size="1" /><p>George Young <br />Microsoft Corporation</p><p><a href="http://download.microsoft.com/download/e/1/2/e12f643e-d286-4129-b2cb-1d4bef3d915d/corner9906.zip"><img height="16" alt="下载示例代码" src="http://www.microsoft.com/china/MSDN/library/archives/technic/images/icodownl.gif" width="16" border="0" /></a><a title="下载范例代码" href="http://download.microsoft.com/download/e/1/2/e12f643e-d286-4129-b2cb-1d4bef3d915d/corner9906.zip">请下载本文的源代码（压缩文件，6.88K）</a></p><p>这是有关在 Web 站点上使用可扩展的标记语言 (XML) 和可扩展的样式表语言 (XSL) 的系列文章中的第三篇。在<a title="阅读 DXML 系列文章中的第一篇文章" href="http://www.microsoft.com/china/MSDN/library/archives/technic/dhtml/corner042699.asp">第一篇文章</a>中，我们谈到了使用 XML 文件存储站点的目录 (TOC) 信息，使用 XSL、层叠样式表 (CSS) 和脚本输出 DHTML TOC。在<a title="阅读 DXML 系列文章中的第二篇文章" href="http://www.microsoft.com/china/MSDN/library/archives/technic/dhtml/corner052499.asp">第二篇文章</a>中，我们使用同一 XML 数据生成 DHTML 菜单，而在 microsoft.com 等 Web 站点中就用到了这些菜单。如果您还没有阅读这些文章，我们建议您在阅读这一篇文章之前，先阅读前两篇。</p><p>本月，我们将讨论在站点上实现菜单和 TOC 的几种不同方式。我们将解决有关实现过程和架构的几个问题，同时看一看几个案例：</p><ol><li>在框架中直接引入 XML 
</li><li>在动态生成的 HTML 中使用 ASP #include 
</li><li>在预先创建的 HTML 中使用 ASP #include </li></ol><p>有一点很重要，必须注意：尽管我们能够用任一浏览器查看输出的 DHTML，但是只要进行 XSL 转换，就必须安装 Internet Explorer 5。如果像在第一个案例中，需要将 XML 发送到客户机，则客户机必须是 Internet Explorer 5。如果像在第二个和第三个案例中，要在服务器上转换 XML，则服务器上必须安装 Internet Explorer 5。（注意：在服务器上可以只安装<a title="阅读有关可重分发的 Microsoft XML 分析程序" href="http://msdn.microsoft.com/downloads/tools/xmlparser/xmlparser.asp">可重分发的 Microsoft XML 分析程序(英文)</a>）。</p><h2>案例 1：在框架中直接引入 XML</h2><p>如果您处于完全的 Internet Explorer 5 环境中（如 intranet），将输出发送给用户的最简单的方式可能是借助于 Internet Explorer 5 直接<a title="阅读有关直接浏览 XML 文档的信息" href="http://msdn.microsoft.com/xml/xslguide/browsing-overview.asp">浏览 XML(英文)</a> 的功能。Internet Explorer 5 可以使用相关的样式表提交 XML；您不需要进行显式转换。您只需要指定带有<a title="查看处理指南的参考主题" href="http://msdn.microsoft.com/xml/reference/scriptref/XMLDOMProcessingInstruction_object.asp">处理指南(英文)</a>的 XSL 样式表。 </p><p>在第一个案例中，我们使用自己的 TOC 作为例子，TOC 框架中将包含一个文件，其 webdev.xml 文件将引用 TOC 样式表，如下所示：</p><pre class="clsCode">&lt;?xml version="1.0"?&gt;
&lt;?xml-stylesheet type="text/xsl" href="toc.xsl"?&gt;

&lt;TOPICLIST TYPE="Web Dev References"&gt;
  .
  .
  .
&lt;/TOPICLIST&gt;
</pre><p>TOC 框架自身将包含在框架集中，如下所示：</p><pre class="clsCode">&lt;FRAMESET COLS="150,*"&gt;
  &lt;FRAME NAME="fraToc" SRC="webdev.xml"&gt;
  &lt;FRAME NAME="fraContent" SRC="home.htm"&gt;
&lt;FRAMESET&gt;
</pre><p>如果您用 Internet Explorer 5 查看这些代码，您可以查看 <a title="查看 XML 浏览 TOC 演示" href="javascript:ShowDemo(5,'corner9906_1.htm')">XML 浏览 TOC 演示</a>。</p><p>浏览 XML 除了是一种向用户发送带样式的 XML 的简便方式，它还是一种非常好的<a title="阅读有关调试样式表" href="http://msdn.microsoft.com/xml/xslguide/browsing-sspi.asp">调试 XSL 样式表</a>的方式，即使您要在服务器上进行转换，也可以使用这种方式。Internet Explorer 可以在出现错误时为您提供即时的反馈，包括行号和错误类型。</p><h2>案例 2：在动态生成的 HTML 中使用 ASP #includes</h2><p>在许多情况下，除了 Internet Explorer 5 之外，您还需要顾及其他浏览器，或者希望只用 XML 构成 HTML 文档的一部分（如顶端的菜单），而不是整篇文档。ASP <a title="查看 #include 指令的参考主题" href="http://msdn.microsoft.com/library/tools/aspdoc/iiwainc.htm">#include 命令</a>为在较大型文档中插入几个字符的 HTML 和跨多页共享公用代码提供了一个非常好的方式。通过在 #include 文件中进行 XSL 转换，可以非常方便地对 ASP #includes 进行扩展，以便利用 XML。</p><p>#include 文件将加载 XML 和 XSL 文件，将其转换为 HTML，然后将 HTML 写入 ASP 文档。如下所示是包含菜单的 ASP 文档：</p><h3>列表 1：使用“动态” #includes 的通用 HTML 文档模板</h3><pre class="clsCode">&lt;HTML&gt;
&lt;HEAD&gt;
&lt;TITLE&gt;Dynamic ASP #include demo&lt;/TITLE&gt;
&lt;/HEAD&gt;
&lt;BODY&gt;
&lt;!-- #include file="menus_dyn.inc" --&gt;
&lt;P&gt;此处为常规文档内容...&lt;/P&gt;
&lt;/BODY&gt;
&lt;/HTML&gt;
</pre><p>Include 文件将完成所有繁琐的工作。</p><h3>列表 2：menus_dyn.inc</h3><pre class="clsCode">&lt;% @LANGUAGE="JScript" %&gt;
&lt;%
  var sXml = "webdev.xml";
  var sXsl = "menus.xsl";
  
  var oXmlDoc = Server.CreateObject("Microsoft.XMLDOM");
  oXmlDoc.async = false;
  oXmlDoc.load(Server.MapPath(sXml));
  
  if (false != oXmlDoc.parseError) 
  {
    Response.Write('XML parseError on line ' + oXmlDoc.parseError.line);
    Response.End();
  }

  var oXslDoc = Server.CreateObject("Microsoft.XMLDOM");
  oXslDoc.async = false;
  oXslDoc.load(Server.MapPath(sXsl));

  if (false != oXslDoc.parseError) 
  {
    Response.Write('XSL parseError on line ' + oXslDoc.parseError.line);
    Response.End();
  }

  Response.Write(oXmlDoc.transformNode(oXslDoc));
%&gt;
</pre><p>从上一篇文章开始，我已经将菜单升级为可跨浏览器使用，所以您能够应用任一浏览器查看<a title="查看动态 #include 演示" href="javascript:ShowDemo('all','corner9906_2.asp')">动态 #include 演示</a>。 </p><h2>案例 3：在预先创建的 HTML 中使用 ASP #include</h2><p>在服务器负荷较重的情况下，或您无论因何种原因，不希望在每次加载菜单时调用 XML 对象，您可以选择第三种方案：脱机进行转换。在这一情况下所使用的代码与“真正的”include 几乎完全相同。</p><p>唯一的区别是：有别于使用 Response.Write 输出所需要的 HMTL，我们可以使用 Scripting.FileSystemObject 对象将已转换的 HTML 保存到一个文件中。</p><h3>列表 3：makemenus.asp</h3><pre class="clsCode">&lt;% @LANGUAGE="JScript" %&gt;
&lt;%
  var sXml = "webdev.xml";
  var sXsl = "menus.xsl";
  
  var oXmlDoc = Server.CreateObject("Microsoft.XMLDOM");
  oXmlDoc.async = false;
  oXmlDoc.load(Server.MapPath(sXml));
  
  if (false != oXmlDoc.parseError) 
  {
    Response.Write('XML parseError on line ' + oXmlDoc.parseError.line);
    Response.End();
  }

  var oXslDoc = Server.CreateObject("Microsoft.XMLDOM");
  oXslDoc.async = false;
  oXslDoc.load(Server.MapPath(sXsl));

  if (false != oXslDoc.parseError) 
  {
    Response.Write('XSL parseError on line ' + oXslDoc.parseError.line);
    Response.End();
  }

  var sOutput = oXmlDoc.transformNode(oXslDoc);
  var sIncFileName = "menus_pre.inc";
  
  var oFS = Server.CreateObject("Scripting.FileSystemObject");
  var oIncFile = oFS.CreateTextFile(Server.MapPath(sIncFileName));
  oIncFile.Write(sOutput);
  oIncFile.Close();
  
  Response.Write('The include file &lt;A HREF="' + sIncFileName + '"&gt;' 
    + sIncFileName + '&lt;/A&gt; was successfully created.');
%&gt;
</pre><p>我们不是写入到 ASP 响应流，而是在服务器上创建了一个“静态”文件，其中包含已转换的 HTML。换句话说，与将 XML 转换代码直接置于 #include 文件不同，所有的转换代码都将位于 “实用程序”ASP 页中，该 ASP 页将生成 include 文件。 </p><p>如果您需要对 Web 应用程序使用编译过程，您可能会喜欢这种方式。无论任何时候更新 menus.xml 文件，我们只需加载 makemenus.asp ，输出一个更新的 #include 文件。将这一算法用在 Visual Basic 应用程序中能够实现同一目的。</p><p>像在案例 2 中一样，我们在所有使用这些菜单的文档中添加这一 #include 文件。</p><h3>列表 4：使用“预先创建”的 #include 的通用 HTML 文档模板</h3><pre class="clsCode">&lt;HTML&gt;
&lt;HEAD&gt;
&lt;TITLE&gt;Dynamic ASP #include demo&lt;/TITLE&gt;
&lt;/HEAD&gt;
&lt;BODY&gt;
&lt;!-- #include file="menus_pre.inc" --&gt;
&lt;P&gt;此处为常规文档内容...&lt;/P&gt;
&lt;/BODY&gt;
&lt;/HTML&gt;
</pre><p>当然，对于用户来说输出结果与案例 2 是一样的，但您可以查看各种情况下的<a title="查看静态 #include 演示" href="javascript:ShowDemo('all','corner9906_3.asp')">静态 #include 演示</a>。</p><p>三个案例的代码位于压缩的<a title="下载范例代码" href="http://download.microsoft.com/download/e/1/2/e12f643e-d286-4129-b2cb-1d4bef3d915d/corner9906.zip">源代码</a>存档文件中。</p><p><i><b>George Young</b> 是 Microsoft 的 Windows 站点的开发负责人，以前曾在 Site Builder Network 站点从事开发工作。在他有空时，喜欢用 Windows 媒体播放器收听墨西哥广播电台的节目，也常开着他的宝贝卡迪车往返于新奥尔良和华盛顿之间的 Redmond。<i></i></i></p><h4>已存档的代码角专栏</h4><table class="clsCatItems" cellspacing="0" cellpadding="0" border="0"><tbody><tr><th colspan="2"></th><th class="clsStoryTD" align="left">1999 年</th></tr><tr valign="top"><td class="clsPubdate" align="right" width="100">5 月 24 日</td><td width="10">  </td><td class="clsStoryTD"><a href="http://www.microsoft.com/china/MSDN/library/archives/technic/dhtml/corner052499.asp">“DXML”Redux：从 XML 创建动态的 HTML 菜单</a></td></tr><tr valign="top"><td class="clsPubdate" align="right" width="100">4 月 26 日</td><td width="10">  </td><td class="clsStoryTD"><a href="http://www.microsoft.com/china/MSDN/library/archives/technic/dhtml/corner042699.asp">“DXML”：将 TOC 从 XML 带到 DHTML</a></td></tr><tr valign="top"><td class="clsPubdate" align="right" width="100">3 月 30 日</td><td width="10">  </td><td class="clsStoryTD"><a href="http://msdn.microsoft.com/workshop/server/iis/corner033099.asp">Redirecting Traffic: A Smart Custom 404 Message for IIS 4.0</a>（英文版）</td></tr></tbody></table><!-- ARTICLE FOOTER END --><div></div><!-- END TOTAL PAGE CONTENT --><img src ="http://www.cppblog.com/phenix_jiang/aggbug/4536.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/phenix_jiang/" target="_blank">拼命流血</a> 2006-03-24 15:00 <a href="http://www.cppblog.com/phenix_jiang/articles/4536.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一些奇特的 JavaScript 功能</title><link>http://www.cppblog.com/phenix_jiang/articles/4532.html</link><dc:creator>拼命流血</dc:creator><author>拼命流血</author><pubDate>Fri, 24 Mar 2006 06:28:00 GMT</pubDate><guid>http://www.cppblog.com/phenix_jiang/articles/4532.html</guid><wfw:comment>http://www.cppblog.com/phenix_jiang/comments/4532.html</wfw:comment><comments>http://www.cppblog.com/phenix_jiang/articles/4532.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/phenix_jiang/comments/commentRss/4532.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/phenix_jiang/services/trackbacks/4532.html</trackback:ping><description><![CDATA[
		<!--NOINDEX_START-->
		<a name="top">
		</a> 
<div id="MNP_showtoc" style="DISPLAY: none; PADDING-LEFT: 15px; PADDING-BOTTOM: 15px; FONT: 11px Verdana; PADDING-TOP: 10px; HEIGHT: 23px"><span style="CURSOR: hand" onclick="top.MNPSearchFrame.showtoc()"><img style="MARGIN-RIGHT: 3px" height="16" alt="show toc" src="http://www.microsoft.com/library/mnp/2/gif/showtoc.gif" width="16" align="absMiddle" border="0" />show toc</span></div><!--NOINDEX_STOP--><table><tbody><tr><td><div style="PADDING-RIGHT: 15px; PADDING-LEFT: 20px; PADDING-BOTTOM: 0px; PADDING-TOP: 0px"><div class="ancestorLinks"><nobr><a href="http://www.microsoft.com/china/MSDN/library/default.mspx">欢迎来到 MSDN</a> &gt; </nobr><nobr><a href="http://www.microsoft.com/china/MSDN/library/WebServices/default.mspx">Web/服务</a></nobr></div><h1>一些奇特的 JavaScript 功能</h1><h2 class="subtitle"></h2><div class="date">发布日期： 1/4/2005<span class="datePipe"> | </span>更新日期： 1/4/2005</div><div class="overview"><p>Jay Allen、Mark Davis、Heidi Housten 和 Dan Mohr<br />Microsoft Corporation</p></div><center><img title="" height="6" alt="*" src="http://img.microsoft.com/library/gallery/templates/MNP2.Common/images/3squares.gif" width="30" border="0" /></center><div style="HEIGHT: 18px"></div><p>在北半球这里，夏天已经过去了。孩子们回到了学校。秋天临近的迹象使小组的成员感染到了这种新入学的情绪。我们什么时候会长大呢？！我们采访了 Jay，还有他的女儿，因此他们要伴随 Web Team Talking 走进秋天。您可以期待更多的精彩内容。</p><p>除了扔湿纸团、理新发型之外，本月我们研究了 MSN® Messenger、一些奇特的 JavaScript 功能、如何更新服务器上的 XML 数据，以及多得让您看不完的短篇集。</p><p>如果您愿意学习，请将有关 Web 的问题发送给<a href="mailto:webtalk@microsoft.com" target="_blank">我们</a>，我们会立即对您的问题作答。</p><h5 style="PADDING-TOP: 2px">本页内容</h5><table style="MARGIN-TOP: 7px; MARGIN-BOTTOM: 12px" cellspacing="0" cellpadding="0" border="0"><tbody><tr valign="top"><td><a href="http://www.microsoft.com/china/MSDN/library/WebServices/WebServices/nacwebteam09032001.mspx#ERB"><img height="9" alt="Instant Gratification" hspace="4" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_down.gif" width="7" vspace="2" border="0" /></a></td><td class="onThisPage"><a href="http://www.microsoft.com/china/MSDN/library/WebServices/WebServices/nacwebteam09032001.mspx#ERB">Instant Gratification</a></td></tr><tr valign="top"><td><a href="http://www.microsoft.com/china/MSDN/library/WebServices/WebServices/nacwebteam09032001.mspx#EWD"><img height="9" alt="将 XML 发送回服务器" hspace="4" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_down.gif" width="7" vspace="2" border="0" /></a></td><td class="onThisPage"><a href="http://www.microsoft.com/china/MSDN/library/WebServices/WebServices/nacwebteam09032001.mspx#EWD">将 XML 发送回服务器</a></td></tr><tr valign="top"><td><a href="http://www.microsoft.com/china/MSDN/library/WebServices/WebServices/nacwebteam09032001.mspx#EJAAC"><img height="9" alt="对日期进行排序" hspace="4" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_down.gif" width="7" vspace="2" border="0" /></a></td><td class="onThisPage"><a href="http://www.microsoft.com/china/MSDN/library/WebServices/WebServices/nacwebteam09032001.mspx#EJAAC">对日期进行排序</a></td></tr><tr valign="top"><td><a href="http://www.microsoft.com/china/MSDN/library/WebServices/WebServices/nacwebteam09032001.mspx#EPCAC"><img height="9" alt="Web Team 简介" hspace="4" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_down.gif" width="7" vspace="2" border="0" /></a></td><td class="onThisPage"><a href="http://www.microsoft.com/china/MSDN/library/WebServices/WebServices/nacwebteam09032001.mspx#EPCAC">Web Team 简介</a></td></tr></tbody></table><a name="ERB"></a><h2>Instant Gratification</h2><p><b>亲爱的</b><b> Web Team</b><b>：</b></p><p>我可以将 MSN Instant Messenger 嵌入在诸如 msn.com 这样的网站上吗？</p><p>谢谢，<br /><i>Joshua Carroll</i></p><p><b>Web Team </b><b>的答复：</b></p><p>我们越来越需要一种比 Instant Gratification 更好的功能，在这一方面，MSN Messenger 最有说服力。<a href="http://www.msn.com/" target="_blank">http://www.msn.com</a> 中的 IM 功能是使用提供 Messenger 功能的两个 Microsoft ActiveX ® 控件以及提供 DHTML 用户界面的一些脚本来实现的。为简短起见，假定我要在 Intranet 主页中添加一个小的提要栏，以便在用户登录后列出该用户的联系人（及其连接状态），并在用户未登录时提供登录按钮。下面提供了一个示例，但是为了表明我们不是得到了神（请注意小写字母“o”）的暗示才领悟到这一信息，我们先概述一下所涉及的技术。</p><p>由于没有关于这些控件的文档，因此我们需要做一些研究工作来实现我们的目标。首先，我们可以查看 msn.com 使用的代码以获得一些提示。这不是因为缺乏勇气，而是通过艰苦地研究这些代码，我们可以从大体上了解这两个控件的功能，以及我们可以怎样编写自己的代码。我们可以使用的第二个工具（并且是有用得多的工具）是 OLE View。OLE View 是 Microsoft Visual Studio_ 附带的一个实用工具，它的功能很强大，可以分析并显示 COM 对象的类型信息。</p><p>因此，我们启动 OLE View，找到前面提到的两个控件（其友好名称分别为 MSN Messenger Application 和 MSN Messenger Object），右键单击这两个控件，然后选择 <b>View type information</b>。该视图将显示对象使用的各个接口和枚举。标记为调度接口的任何接口都应该可用于基于脚本的调用方，因此我们开始着手编码了！</p><p>在确保控件正确实例化以后，代码需要做的第一件事情是确定用户是否联机。这是通过检查 <b>Messenger</b> Object 的 <b>LocalState</b> 属性来完成的。该属性从 MSTATE 枚举（其定义已部分包含在我们的代码中）返回一个值。如果用户未联机，我们将启用调用 Messenger Application 的 <b>LaunchLogonUI</b> 方法的登录按钮。如果用户已联机，则我们需要使用用户的所有联系人来填充 DIV。为此，我们循环访问默认列表 (List(0)) 中的每个联系人，并检索其 FriendlyName 以及描述其当前状态的 MSTATE 值，然后新建一个包含此信息的 DIV。 </p><p>由于我们要允许用户通过单击列表中的任何联系人来向该联系人发送消息，因此需要以编程方式将 onclick 事件处理程序附加到新 DIV。该事件处理程序函数 (<b>sendMessage</b>) 基本上是 Messenger Application 的 <b>LaunchIMUI</b> 方法的包装。由于 LaunchIMUI 将目标联系人作为一个参数，因此我们需要能够确定 Messenger Object 的默认列表中的哪个联系人与被单击的 DIV 对应。这时最理想的是使用 <b>expando</b> 属性。我们将联系人在默认列表中的索引附加到新建的、表示该联系人的 DIV 元素。这样，onclick 处理程序就能够检索到此索引，然后从 Messenger Object 的列表中抽取正确的联系人并将其传递给 <b>LaunchIMUI</b>。 </p><p>本示例包含的一项额外功能是在该页加载后处理注销和登录。这是通过处理由 Messenger Object 激发的 OnLocalStateChangeResult 事件来完成的。此事件在 <b>LocalState</b> 属性更改时激发（并不太意外）。因此，相应地，我们仅仅查看我们已脱机还是已联机。如果已脱机，需要清空联系人 UI 列表；如果已联机，需要在短暂的 setTimeout（确保一切都正确同步）之后调用 <b>populateContacts</b>。而且由于 ActiveX 控件依赖于独立 Messenger 的运行实例，因此我们的页面还将更新以响应它触发的事件。</p><p>至此，您可能已对我们的喋喋不休感到厌烦，那么，请看下面的代码。</p><pre class="codeSample">&lt;HTML&gt;
&lt;HEAD&gt;
   &lt;TITLE&gt;Embedding MSN Messenger Test&lt;/TITLE&gt;

   &lt;OBJECT CLASSID="clsid:F3A614DC-ABE0-11d2-A441-00C04F795683" 
   CODEBASE="#Version=2,0,0,83"
      CODETYPE="application/x-oleobject" ID="oMsgrObj" WIDTH="0" 
      HEIGHT="0" OnUserStateChanged="alert();"&gt;
   &lt;/OBJECT&gt;
   &lt;OBJECT CLASSID="clsid:FB7199AB-79BF-11d2-8D94-0000F875C541" 
   CODETYPE="application/x-oleobject"
      ID="oMsgrApp" WIDTH="0" HEIGHT="0"&gt;
   &lt;/OBJECT&gt;

   &lt;STYLE&gt;
   BODY
   {
      FONT-FAMILY: Verdana, Arial, Helvetica;
      FONT-SIZE: 8pt;
   }
   INPUT
   {
      FONT-FAMILY: Verdana, Arial, Helvetica;
      FONT-SIZE: 8pt;
   }
   .clsHeading
   {
      FONT-WEIGHT: bolder;
      FONT-SIZE: 10pt;
   }
   .clsContact
   {
      PADDING: 2px;
      CURSOR: hand;
   }
   &lt;/STYLE&gt;
&lt;/HEAD&gt;

&lt;BODY onLoad="body_onLoad();"&gt;

&lt;SCRIPT LANGUAGE="JScript"&gt;

// Here are the definitions for the Messenger enumerated values we use

var MSTATE_OFFLINE = 1;
var MSTATE_ONLINE = 2;
var MSTATE_BUSY = 10;
var MSTATE_BE_RIGHT_BACK = 14;
var MSTATE_IDLE = 18;
var MSTATE_AWAY = 34;

function body_onLoad()
{
   // First, we need to make sure that the Messenger controls got instantiated correctly

   if ("undefined" != typeof(oMsgrObj) &amp;&amp; null != oMsgrObj.object &amp;&amp; "undefined" 
   != typeof(oMsgrApp) &amp;&amp; null != oMsgrApp.object)
   {
      // If so, let's check to see if we're online and (if so) populate our contacts UI

      if (oMsgrObj.LocalState == MSTATE_ONLINE)
      {
         populateContacts();
      }
      else if (oMsgrObj.LocalState == MSTATE_OFFLINE)
      {
         btnLogon.disabled = false;
      }
   }
   else
   {
      // Uh, oh - the controls didn't get instantiated correctly; 
      // the user probably needs to install Messenger

      alert("You need to install the latest version of MSN Messenger!
      \nGo to http://messenger.msn.com right now!");
   }
}

function populateContacts()
{
   var oList = oMsgrObj.List(0);
   var oContact;
   var i;

   // To populate our contact list, we're going to iterate throught the 
   // default list collection, check the state of each contact,
   // and add a DIV with the approppriate appearance to our UI

   for (i = 0; i &lt; oList.Count; i++)
   {
      oContact = oList.Item(i);

      oNewElement = document.createElement("DIV");
      oNewElement.innerText = oContact.FriendlyName;

      switch (oContact.State)
      {
      case MSTATE_ONLINE:
         // Don't need to do anything
         break;
      case MSTATE_OFFLINE:
         oNewElement.innerText += " (Offline)";
         oNewElement.style.color = "graytext";
         break;
      case MSTATE_BUSY:
         oNewElement.innerText += " (Busy)";
         break;
      case MSTATE_BE_RIGHT_BACK:
         oNewElement.innerText += " (Be Right Back)";
         break;
      case MSTATE_IDLE:
         oNewElement.innerText += " (Idle)";
         break;
      case MSTATE_AWAY:
         oNewElement.innerText += " (Away)";
         break;
      default:
         oNewElement.innerText += "(Just plain not around!)";
         oNewElement.style.color = "graytext";
         break;
      }
      oNewElement.className = "clsContact";

      // To enable us to respond to the onclick event, 
      // we're programmatically setting the event
      // handler AND we're defining an expando property
      // on the contact DIV whose value is set to
      // the index of the contact in the default list (so we can find them later)

      oNewElement.onclick = sendMessage;
      oNewElement.setAttribute("CONTACTID", i.toString());

      divContacts.appendChild(oNewElement);
   }
}
function doLogon()
{
   // To logon, we just ask Messenger to display its logon UI

   if (oMsgrObj.LocalState == MSTATE_OFFLINE)
   {
      btnLogon.disabled = true;
      oMsgrApp.LaunchLogonUI();
   }
}

function sendMessage()
{
   // To send a message, we likewise just ask Messenger to do the heavy
   // lifting (we just have to
   // pass it a contact from the default list)

   var nContactID = parseInt(window.event.srcElement.getAttribute("CONTACTID"));
   if (!isNaN(nContactID))
   {
      var oContact = oMsgrObj.List(0).Item(nContactID);
      oMsgrApp.LaunchIMUI(oContact);
   }
}

&lt;/SCRIPT&gt;

&lt;SCRIPT LANGUAGE="JScript" EVENT="onLocalStateChangeResult(hr)" FOR="oMsgrObj"&gt;

if (hr == 0)
{
   if (oMsgrObj.LocalState == MSTATE_ONLINE)
   {
      // Now we're online

      window.setTimeout("populateContacts();", 3000);
   }
   else if (oMsgrObj.LocalState == MSTATE_OFFLINE)
   {
      // Now we're offline

      divContacts.innerHTML = "";
      btnLogon.disabled = false;
   }
}

&lt;/SCRIPT&gt;

&lt;DIV CLASS="clsHeading"&gt;Contacts (click on a contact to send a message!)&lt;/DIV&gt;
&lt;DIV ID="divContacts" STYLE="MARGIN-TOP: 8px; 
 MARGIN-BOTTOM: 8px; BORDER: 1px solid steelblue"&gt;&lt;/DIV&gt;
&lt;INPUT TYPE="BUTTON" ID="btnLogon" VALUE="Logon" onClick="doLogon();" DISABLED="yes"&gt;

&lt;/BODY&gt;
&lt;/HTML&gt;
</pre><div style="MARGIN-TOP: 3px; MARGIN-BOTTOM: 10px"><a href="http://www.microsoft.com/china/MSDN/library/WebServices/WebServices/nacwebteam09032001.mspx#top"><img height="9" alt="返回页首" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_up.gif" width="7" border="0" /></a><a class="topOfPage" href="http://www.microsoft.com/china/MSDN/library/WebServices/WebServices/nacwebteam09032001.mspx#top">返回页首</a></div><a name="EWD"></a><h2>将 XML 发送回服务器</h2><p><b>亲爱的</b><b> Web Team</b><b>：</b></p><p>你们怎样修改客户端 Web 浏览器上的 XML 并将最后的 XML 发送到 Web 服务器呢？</p><p><b>Web Team </b><b>的答复：</b></p><p>我们假定您的 Web 服务器运行的是 Microsoft Internet Information Server (IIS) 4.0（或更高版本）或支持 Active Server Page (ASP) 技术的产品。</p><p>我们来简要地回顾一下 Web 浏览器是如何提供丰富的交互式 Internet 体验的。考虑最简单的形式：Web 浏览器从 Web 服务器请求一个页面，处理返回的信息（通常是超文本标记语言 (HTML) 格式），并显示结果。超文本传输协议 (HTTP) 定义了 Web 服务器和浏览器用来相互通讯的语言。Web 浏览器还执行大量的幕后工作，以便用户能够导航 Web 并显示各种媒体类型。</p><p>因此，您需要一个交互式 Web 站点。那么，用户怎样将信息发送到 Web 服务器呢？</p><p>Web 浏览器或 Web 应用程序有许多种用来将 XML 发送到 Web 服务器的方法，我们将介绍其中的两种。Web 浏览器通常使用 <b>HTTP GET</b> 方法来请求 Web 页，并使用 <b>HTTP POST</b> 方法来发送信息。要实现用户与 Web 服务器之间的通讯，最简单的方法是使用 HTML <b>FORM</b> 元素。</p><p><b>FORM</b> 元素提供了一种使用 <b>GET</b> 或 <b>POST</b> 方法将数据发送到服务器的途径。将哪些控件置于窗体内由您决定，并且您还决定只有具有 NAME 属性的那些控件才能够提交其数据。例如，当用户单击 <b>Submit</b> 按钮时，每个控件的数据都发送到 Web 服务器。</p><p>在下面的示例中，存储在 XML 数据岛中的 XML 将作为窗体的一部分提交到服务器。可以通过多种方法获取此 XML：硬编码、通过设置 <b>SRC</b> 属性从外部文件中加载、从 ADO 记录集中检索、从 SQL Server 2000 中检索或者使用 XML DOM 脚本对象模型来创建/修改。可以通过将 XML 绑定到 HTML 元素来将 XML 呈现给用户（请参阅 <a href="http://msdn.microsoft.com/workshop/author/databind/dataconsumer.asp" target="_blank">Binding HTML Elements to Data</a>）。将 XML 数据包含在表单中提交就像在 <b>onsubmit</b> 事件处理程序中将 XML 分配给隐藏的 <b>INPUT</b> 元素一样简单，如下所示：</p><pre class="codeSample">&lt;FORM ACTION="http://yourserver/form.asp" METHOD="post" NAME="myform" 
ONSUBMIT=" myform.mytext.value = myxml.XMLDocument.xml;"&gt;
 &lt;INPUT TYPE="HIDDEN" NAME="Text" ID="mytext"&gt;
 &lt;INPUT TYPE="Submit"&gt;
&lt;/FORM&gt;

&lt;XML ID="myxml"&gt;
 &lt;root&gt;
  &lt;item id="1" name="Item 1"/&gt;
  &lt;item id="2" name="Item 2"/&gt;
 &lt;/root&gt;
&lt;/XML&gt;
</pre><p>下面是 FORM.ASP 页的内容：</p><pre class="codeSample">&lt;%@ language=JScript %&gt;
&lt;% 
  var xmldom = Server.CreateObject( "Microsoft.XMLDOM" );
  var xml = Request.Form( "Text" );
  Response.Write( "&lt;XMP&gt;" + xml + "&lt;/XMP&gt;" );
%&gt;
</pre><p><b>注</b><b></b>为方便起见，本例中服务器返回 <b>XMP</b> 元素内的 XML。尽管此 HTML 元素是否决的，但是它具有将 HTML 和 XML 元素作为文本显示的好处。</p><p><b>XMLHttpRequest</b> 对象是 Microsoft Internet Explorer 5.0 或更高版本附带的 MSXML 组件的一部分。该对象是在 Web 页上创建的，用于将 XML 发送到 Web 服务器。该对象是通过将 <b>Microsoft.XMLHTTP</b> 指定为应用程序名称来创建的。您通常调用 <b>Open</b> 方法、设置头信息（可选）、调用 <b>Send</b>，然后选中 <b>responseXML</b> 或 <b>responseText</b> 属性。使用此对象的一个好处是无需刷新页面即可执行 <b>POST</b>，从而实现了服务器与浏览器之间的无缝数据传输。Internet Explorer <a href="http://msdn.microsoft.com/workshop/author/webservice/overview.asp" target="_blank">Web 服务行为</a>使用 <b>XMLHttpRequest</b> 对象来提供对 .NET XML Web 服务的调用（使用 SOAP 请求）。</p><p>下面的示例展示了如何将 XML 文档发送到 Web 服务器。请注意，该示例使用同步调用。要进行异步调用，应该为 <b>Open</b> 方法的第三个参数提供 true 值，并使用 <b>onreadystatechange</b> 事件处理程序，以便在 <b>Send</b> 方法完成时得到通知。</p><pre class="codeSample">&lt;HEAD&gt;
&lt;script language="JScript"&gt;
function PostXml(xmldoc)
{    
  var xmlhttp = new ActiveXObject( "Microsoft.XMLHTTP" );
  xmlhttp.Open( "POST", "http://yourserver/xmlhttp.asp", false );
  xmlhttp.Send( xmldoc );
  return xmlhttp.responseXML;
}
function ShowResults()
{
  var resp = PostXml( myxml.XMLDocument );
  mydiv.innerHTML = "&lt;XMP&gt;" + resp.xml + "&lt;/XMP&gt;";
}
&lt;/script&gt;&lt;/HEAD&gt;
&lt;BODY&gt;
&lt;BUTTON ONCLICK="ShowResults()"&gt;Post XML&lt;/BUTTON&gt;
&lt;DIV ID="mydiv"&gt;&lt;/DIV&gt;

&lt;XML ID="myxml"&gt;
 &lt;root&gt;
  &lt;item id="1" name="Item 1"/&gt;
  &lt;item id="2" name="Item 2"/&gt;
 &lt;/root&gt;
&lt;/XML&gt;
</pre><p>下面是 XMLHTTP.ASP 文件的内容：</p><pre class="codeSample">&lt;%@ language=JScript %&gt;
&lt;% 
  // Load XML
  var doc = Server.CreateObject( "Microsoft.XMLDOM" );
  doc.load( Request );

  // Process the XML ...

  // Return result
  Response.ContentType = "text/xml";
  doc.save( Response );
%&gt;
</pre><p>在许多情况下，将 XML 存储在客户端上能够为 Web 站点提供创新的功能，例如，缓存常用数据、用户个性化或内联数据编辑。我们已讨论了两种将 XML 数据发送到 Web 服务器的机制。使用 ASP 技术来处理服务器上的 XML 数据很简单，而使用 ASP.NET 中的新功能进行处理则更简单。服务器可以选择以多种方式处理 XML，例如，将信息保存到文件或数据库中，或者根据 XML 内容执行操作。</p><p>下面介绍了另外几种将数据发送到 Web 服务器的方法，这些方法超出了本文的讨论范畴。 </p><table cellspacing="0" cellpadding="0" border="0"><tbody><tr><td class="listBullet" valign="top">•</td><td class="listItem"><p><b>HTTP GET</b> 方法 — 使用所请求的 URL 的查询字符串（“?”后面的文本）来发送信息，但限定 URL 的大小不得超过 2K。 </p></td></tr><tr><td class="listBullet" valign="top">•</td><td class="listItem"><p><b>HTTP PUT</b> 方法 — 采用此方法存在安全隐患。 </p></td></tr><tr><td class="listBullet" valign="top">•</td><td class="listItem"><p>HTML <b>INPUT TYPE=FILE</b> 元素可以用于上载用户选定的文件。 </p></td></tr><tr><td class="listBullet" valign="top">•</td><td class="listItem"><p>直接从 ActiveX 控件或应用程序调用低级别的 <b>WinInet</b> 函数，以便可以更好地控制与 Web 服务器的通讯。 </p></td></tr><tr><td class="listBullet" valign="top">•</td><td class="listItem"><p>使用 Internet Explorer <a href="http://msdn.microsoft.com/workshop/author/webservice/overview.asp" target="_blank">Web 服务行为</a>来调用对 .NET XML Web 服务的调用。 </p></td></tr></tbody></table><div style="MARGIN-TOP: 3px; MARGIN-BOTTOM: 10px"><a href="http://www.microsoft.com/china/MSDN/library/WebServices/WebServices/nacwebteam09032001.mspx#top"><img height="9" alt="返回页首" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_up.gif" width="7" border="0" /></a><a class="topOfPage" href="http://www.microsoft.com/china/MSDN/library/WebServices/WebServices/nacwebteam09032001.mspx#top">返回页首</a></div><a name="EJAAC"></a><h2>对日期进行排序</h2><p><b>亲爱的</b><b> Web Team</b><b>：</b></p><p>我尝试着显示特定文件夹的内容，但显示的文件是按照创建日期来排序的（而不是像我现在所希望的那样按字母顺序来排序）。是否存在一种方法，可以通过使用 ASP 和 FileSystemObject 来实现我的愿望呢？对于你们提供的任何帮助，我将不胜感激。</p><p><i>Matt Pierce</i></p><p><b>Web Team </b><b>的答复：</b></p><p>Matt，非常感谢您的提问！下面是一个示例 ASP 页（感谢 Eric 的工作！），该页使用 <b>FileSystemObject</b><b>scripting</b> 对象来获取文件名集合，然后按创建日期对其进行排序。有关 <b>FileSystemObject scripting</b> 对象的文档，可以在 <a href="http://msdn.microsoft.com/library/default.asp?url=/nhp/Default.asp?contentid=28001169" target="_blank">Microsoft Windows Script Technologies 站点</a>找到。 </p><p>调用 <b>GetFolder()</b> 方法以检索文件夹对象的指定的路径。该文件夹对象包含可以使用 <a href="http://msdn.microsoft.com/library/en-us/script56/html/js56jsobjEnumerator.asp" target="_blank">Enumerator</a> 对象访问的 <b>files</b> 集合。每个文件项都是按照文件名的顺序检索的，因此将它们分配给一个数组以便在稍后对其进行排序。 </p><pre class="codeSample">    arr[i++] = {path : fc.item().Path, date : fc.item().DateCreated};
</pre><p>上面显示的是一种不很常见的分配语法，这种语法称为对象文字，它包含用逗号分隔的属性规范列表。每个属性规范都由属性名及其后面的属性值组成。此对象文字语法用于创建具有 <b>path</b> 和 <b>date</b> 这两个属性的对象。 </p><p>使用 <b>Array</b> 对象的 <b>sort()</b> 方法可以指定我们自己的比较函数 <b>sortByDate</b>，以便确定排序顺序。在本例中，<b>comparison</b> 函数返回一个指示两个项在创建日期上的相对顺序的值，但可以轻松地针对其他文件属性对该函数进行改写。</p><pre class="codeSample">&lt;%@ language=JScript %&gt;
&lt;%
function sortByDate(f1, f2)
{
  if (f1.date &lt; f2.date)
    return -1;
  else if (f1.date &gt; f2.date)
    return 1;
  else 
    return 0;
}
function showfiles(path)
{
  var fso, f, f1, fc, arr, i, s;
  fso = new ActiveXObject( "Scripting.FileSystemObject" );
  f = fso.GetFolder( path );

  // Build the file list
  arr = new Array();
  i = 0;
  for ( fc = new Enumerator( f.files ); !fc.atEnd(); fc.moveNext() )
    arr[i++] = {path : fc.item().Path, date : fc.item().DateCreated};

  // Sort the file list
  arr.sort( sortByDate );

  // Display the file list
  s = "";
  for ( i=0 ; i&lt;arr.length ; ++i )
    s += arr[i].path + "&lt;br&gt;";
  return s;
}
Response.Write( showfiles( Server.MapPath( "." ) ) );
%&gt;
</pre><div style="MARGIN-TOP: 3px; MARGIN-BOTTOM: 10px"><a href="http://www.microsoft.com/china/MSDN/library/WebServices/WebServices/nacwebteam09032001.mspx#top"><img height="9" alt="返回页首" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_up.gif" width="7" border="0" /></a><a class="topOfPage" href="http://www.microsoft.com/china/MSDN/library/WebServices/WebServices/nacwebteam09032001.mspx#top">返回页首</a></div><a name="EPCAC"></a><h2>Web Team 简介</h2><p><b>Web </b><b>辅助功能</b></p><p><b>问：</b>Rob 想知道怎样使 Web 站点易于访问。</p><p><b>答：</b>请查看 Microsoft Enable 站点上的<a href="http://www.microsoft.com/enable/" target="_blank">辅助功能 Web 指导原则</a>。</p><p><b>针对色盲用户的开发注意事项</b></p><p><b>问：</b>Becca 问：是否有关于色盲以及考虑到这一情况时的 Web 开发的任何信息。</p><p><b>答：</b>请看 Robert Hess 在其定期专栏 <i>More or Hess</i> 中撰写的文章 <a href="http://msdn.microsoft.com/library/en-us/dnhess/html/hess10092000.asp" target="_blank">Can Color-Blind Users See Your Site?</a>。</p><p><b>行为</b></p><p><b>问：</b>Pierre 问：DHTML 行为有什么用途。</p><p><b>答：</b>MSDN 联机库中有一篇很好的<a href="http://msdn.microsoft.com/workshop/author/behaviors/overview.asp" target="_blank">概述文章</a>介绍这些行为。DHTML Dude 专栏也在名为 <a href="http://msdn.microsoft.com/library/en-us/dndude/html/dude07232001.asp" target="_blank">Fun with Tables</a> 的专栏中讨论了这一主题。</p><p><b>Intranet </b><b>身份验证</b></p><p><b>问：</b>Paul 想知道公司用户怎样能够使用其域用户名和密码来自动通过 Web 站点的身份验证。</p><p><b>答：</b>在 Internet Explorer 中，转至“工具”/“Internet 选项”，单击 <b>Security</b> 选项卡。然后单击 <b>Custom Level</b>，向下滚动至 <b>User Authentication</b>，并选择 <b>Automatic logon only in Intranet zone</b>。除非您公司的 IT 组配置了其他选项，否则此选项是默认选项。</p><p><b>Web Team</b></p><p><b>Mark Davis</b> 是 Internet Explorer SDK 组的软件设计工程师。Mark 来自英格兰，他目前正在接受训练，为攀登西北部的主峰作准备。<br /><br /><b>Heidi Housten</b> 是瑞典的一名 Microsoft 咨询服务顾问，在此之前，她在 Developer Support 组和 MSDN 组工作过一段时间。有人谣传说她搬至那里是为了躲避西雅图没完没了的小雨，实际上她去那里仅仅是为了参加八月的传统的小龙虾宴会。<br /><br /><b>Dan Mohr</b> 是 Microsoft Developer Support 的 Internet Client 组的工程师，他业余时间喜欢在自己的地下室录制磁带、编写他的 Commodore 64 程序，以及吹捧 70 年代末期的朋克摇滚乐。<br /><br /><b>Jay Allen</b> 是 Microsoft Developer Support 的 Internet Client 组的支持工程师，他渴望将记事本与 Emacs Lisp 集成。在工作之余，他将绝大部分时间都用来陪自己的四个孩子，剩下的一点时间则通常用来读数学书、学习日语以及用 Haskell 编程。</p><p><b>Web Team </b><b>大热门</b></p><p><a href="http://msdn.microsoft.com/library/en-us/dnwebteam/html/webmen-popup.asp" target="_blank">Web Team 话题列表</a></p><p><a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwebteam/html/webteam09032001.asp" target="_blank">转到原英文页面</a></p><br style="FONT-SIZE: 0pt" clear="all" /><div style="MARGIN-TOP: 16px; MARGIN-BOTTOM: 20px; WIDTH: 100%"><table cellspacing="0" cellpadding="0" width="100%" border="0"><tbody><tr><td><a href="http://www.microsoft.com/china/MSDN/library/WebServices/WebServices/nacwebteam09032001.mspx#top"><img height="9" alt="返回页首" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_up.gif" width="7" border="0" /></a><a class="topOfPage" href="http://www.microsoft.com/china/MSDN/library/WebServices/WebServices/nacwebteam09032001.mspx#top">返回页首</a></td></tr></tbody></table></div></div></td></tr></tbody></table><!--NOINDEX_START--><script language="javascript"><![CDATA[
              var framesValid = false;
              if (window.name == "MNPMainFrame")
              { var menuFrame = parent.frames["MNPMenuFrame"]; if (menuFrame) { framesValid = true; } }
              if (!framesValid) location.replace("/china/MSDN/library/WebServices/WebServices/nacwebteam09032001.mspx?mfr=true");
              
                else document.write('<layer visibility="hide"><div style="display:none"><img alt="" width="0" height="0" border="0" hspace="0" vspace="0" src="http://c.microsoft.com/trans_pixel.asp?source=www&amp;TYPE=PV&amp;p=china_MSDN_library_WebServices_WebServices&amp;URI=%2fchina%2fMSDN%2flibrary%2fWebServices%2fWebServices%2fnacwebteam09032001.mspx&amp;GUID=1F4FC18C-F71E-47FB-8FC9-612F8EE59C61&amp;r=http%3a%2f%2fwww.microsoft.com%2fCHINA%2fmnp_utility.mspx%2fframesmenu%3furl%3d%2fchina%2fMSDN%2flibrary%2fWebServices%2fWebServices%2fapnet30DownloadAPI.mspx&amp;lc=zh-chs"></div>/layer>');
              
              top.document.title = self.document.title;
            ]]&gt;</script><layer visibility="hide"><div style="DISPLAY: none"><img height="0" alt="" hspace="0" src="http://c.microsoft.com/trans_pixel.asp?source=www&amp;TYPE=PV&amp;p=china_MSDN_library_WebServices_WebServices&amp;URI=%2fchina%2fMSDN%2flibrary%2fWebServices%2fWebServices%2fnacwebteam09032001.mspx&amp;GUID=1F4FC18C-F71E-47FB-8FC9-612F8EE59C61&amp;r=http%3a%2f%2fwww.microsoft.com%2fCHINA%2fmnp_utility.mspx%2fframesmenu%3furl%3d%2fchina%2fMSDN%2flibrary%2fWebServices%2fWebServices%2fapnet30DownloadAPI.mspx&amp;lc=zh-chs" width="0" border="0" /></div></layer><table cellspacing="0" cellpadding="0" width="100%" border="0"><tbody><tr valign="bottom"><td><iframe id="footerId" style="HEIGHT: 260px" name="footerId" marginwidth="0" marginheight="0" src="/library/gallery/components/ratingControl/ratings.aspx?rurl=http%3a%2f%2fwww.microsoft.com%2fchina%2fMSDN%2flibrary%2fWebServices%2fWebServices%2fnacwebteam09032001.mspx&amp;l=zh-chs&amp;f=True&amp;d=LTR&amp;t=%e4%b8%80%e4%ba%9b%e5%a5%87%e7%89%b9%e7%9a%84+JavaScript+%e5%8a%9f%e8%83%bd" frameborder="0" width="100%" scrolling="no"></iframe></td></tr></tbody></table><br style="OVERFLOW: hidden; LINE-HEIGHT: 1px" clear="all" /><table id="msviFooter" cellspacing="0" cellpadding="0" width="100%"><tbody><tr valign="bottom"><td id="msviFooter2" style="FILTER: "><div id="msviLocalFooter"><nobr><a href="https://profile.microsoft.com/RegSysProfileCenter/Infodefault.aspx?LCID=2052" target="_top">个人信息中心</a> |</nobr><wbr></wbr><nobr><a href="http://www.microsoft.com/china/newsletter/case/MSDN.asp" target="_parent">MSDN中文速递邮件</a> |</nobr><wbr></wbr><nobr><a href="http://www.microsoft.com/china/MSDN/feedback/" target="_parent">联系我们</a></nobr></div><div id="msviGlobalFooter"><span dir="ltr">©2006 Microsoft Corporation. 版权所有.  </span><nobr><a href="http://www.microsoft.com/china/misc/cpyright.htm" target="_parent">保留所有权利</a> |</nobr><wbr></wbr><nobr><a href="http://www.microsoft.com/library/toolbar/3.0/trademarks/zh-cn.mspx" target="_top">商标</a> |</nobr><wbr></wbr><nobr><a href="http://www.microsoft.com/info/cn/privacy.mspx" target="_top">隐私权声明</a></nobr></div></td><td width="105" bgcolor="#669aff"><img title="" height="29" alt="Microsoft" src="http://www.microsoft.com/library/toolbar/3.0/text.aspx?t=TQ%3d%3d&amp;f=FFFFFF&amp;b=669AFF&amp;font=Microsoft+Logo+95%2c+13pt&amp;w=105&amp;h=29&amp;a=0&amp;l=0&amp;v=0&amp;c=eAdQAhJgwJihw2DKZGDGx4FnKIM%3d" width="105" border="0" /></td></tr></tbody></table><script language="javascript"><![CDATA[       var msviFooter2;        if (document.getElementById)        {        msviFooter2 = document.getElementById("msviFooter2");        msviFooter2.style.filter = "";        }      ]]&gt;</script><table style="WIDTH: 417px; ; WIDTH: expression(msviFooter2.offsetWidth); HEIGHT: 86px; ; HEIGHT: expression(msviFooter2.offsetHeight+1)" height="58" cellspacing="0" cellpadding="0" width="100%"><tbody><tr valign="top"><td><div style="WIDTH: 200px"></div></td><td style="FILTER: progid:DXImageTransform.Microsoft.Gradient(startColorStr='#FFFFFF', endColorStr='#669AFF', gradientType='1')" width="100%"></td></tr></tbody></table><img src ="http://www.cppblog.com/phenix_jiang/aggbug/4532.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/phenix_jiang/" target="_blank">拼命流血</a> 2006-03-24 14:28 <a href="http://www.cppblog.com/phenix_jiang/articles/4532.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在长时间操作过程中更新显示</title><link>http://www.cppblog.com/phenix_jiang/articles/4531.html</link><dc:creator>拼命流血</dc:creator><author>拼命流血</author><pubDate>Fri, 24 Mar 2006 06:15:00 GMT</pubDate><guid>http://www.cppblog.com/phenix_jiang/articles/4531.html</guid><wfw:comment>http://www.cppblog.com/phenix_jiang/comments/4531.html</wfw:comment><comments>http://www.cppblog.com/phenix_jiang/articles/4531.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/phenix_jiang/comments/commentRss/4531.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/phenix_jiang/services/trackbacks/4531.html</trackback:ping><description><![CDATA[
		<h1>
				<a name="dude02262001">
				</a>在长时间操作过程中更新显示</h1>
		<font class="90v">
				<p>作者：Dave Massy</p>
				<p class="clsPostDate">2001 年 2 月 26 日发布    将于 2001 年 3 月 26 日存档</p>
				<p>上个月我们讨论了使用 DHTML 提供 Web 服务，在接下来的几个月里，我们将进一步详细讨论这个主题。在 Web 服务这个问题上，越是思考它将为 Web 应用程序提供的种种可能，我就越感到兴奋。我知道这不太好，可这些事情确实让我兴奋。不过，这个月我想我该讲讲更基本的主题。近几个月来我卷入了一些关于这个问题的漫长的电子邮件讨论，我想解释一下这个问题为什么会存在，以及可能的解决方案。这会非常有趣。引起讨论的第一封电子邮件一般是这样写的：</p>
				<p>我编了一个使用 while 循环的脚本函数，它的执行时间很长。尽管我在循环里加入了一个作为迭代进程的更新显示的语句，可是总要到例程完成之后才会更新显示。</p>
				<p>邮件中往往附着这样一段脚本：</p>
				<pre class="clsCode">&lt;SCRIPT&gt;
function longtime()
{  
   var i=0;
   while (i&lt;=500)
   { 
      d1.innerHTML="Count ="+i;
      i++;
      // 以下语句代表一个很长的过程
      var j=0;   
      while (j&lt;=10000)
          j++;
   }
}
&lt;/SCRIPT&gt;
&lt;INPUT TYPE="BUTTON" onclick="longtime();" value="Click Me"&gt;
&lt;DIV id="d1"&gt;This is where the count of iterations should display&lt;/DIV&gt;
</pre>
				<p>
						<a href="http://www.microsoft.com/china/MSDN/library/archives/voiCEs/dude02262001-disp1.htm" target="new">查看示例</a>。</p>
				<p>编写 DHTML 的新手遇到这种问题并不奇怪。尽管编过一段时间 DHTML 的人会立刻回答：“这还不明显吗？”这个问题确实值得好好解释一番。</p>
				<p>这段 HTML 和脚本的预期效果是在执行长时间迭代操作的过程中显示进度计数。而实际的效果却非常糟糕。最明显的问题是，按下按钮后会有一个停顿，用户会看到提示，说脚本将运行很长时间，并询问是否放弃操作。同时，显示会更新为计数值。您可能会注意到出现提示之前的另一个细微效果：按钮保持按下状态，而用户根本无法使用浏览器。正是这一事实（用户被锁在浏览器之外）导致 Microsoft® Internet Explorer 对用户发出提示，以便用户能够避免运行时间过长的脚本。</p>
				<h3>这是为什么？</h3>
				<p>脚本在 Internet Explorer 中运行的一个原则是：它的运行是不可中断的。所以，执行上面的脚本时，浏览器将处于锁定状态，直至脚本运行结束。乍一看来，这象是一个糟糕的设计，一个缺陷。可是，如果停下来想一想：如果不这样做会怎样，您就可能会意识到，这根本不是缺陷，而是一个逻辑设计。</p>
				<p>让我们设想一下，如果上面的脚本按照作者的意图执行，用户将会在显示器上看到计数值从 0 增长到 500。这时，每次显示更新时就会生成 onresize 和 onchange 这样的事件。脚本会立即处理这些事件吗？很可能不，因为这会对脚本运行的原函数造成影响，例如，全局变量值的变化。另一种方案是，在执行原函数时所有事件均排队等候处理，但这也会带来一系列问题，而且与预期效果所距甚远。有一点对脚本很有用处，即能够执行并决定内容应该如何在屏幕上显示，然后让所有更新同步发生，而不是在屏幕的不同部分不断改变显示。</p>
				<p>那么，为什么会在提示放弃脚本操作时更新显示呢？这是因为对话框的显示会导致脚本转让控制权，所以显示引擎才有机会更新显示，显示当前的 DHTML 文档树。脚本转让控制权的思路非常重要，这一点类似于汽车让路给其他车辆加入车流。在浏览器中，当脚本引擎转让控制权时，允许显示引擎取得控制，这时，显示引擎查看 DHTML 文档树，并根据上次获得控制后发生的变化进行更新。这里我已经简化了浏览器的内部过程。显示引擎非常智能，能够找到显示内容中无效并需要调整的部分。这可能会导致当前显示内容的布局变化，继而强制屏幕的其他部分重新显示。这里需要注意的重点是，脚本控制权的转让允许显示更新和用户使用浏览器。所以，要使我们的示例脚本达到预期效果，需要强制脚本转让控制权。</p>
				<h3>使脚本转让控制权</h3>
				<p>要使脚本转让控制权，开发人员可以采用下面几种做法。首先，就像我们已经看到的，对话框会强制脚本转让控制权。显然，在我们这个示例里不想使用对话框，因为我们只想更新屏幕，而不想给用户任何提示。不过，对话框能够强制脚本转让控制权的事实引发了一个有关调试脚本的有趣问题。有时，开发人员会奇怪为什么一段代码不象预期的那样运行，而一种简单快捷的方法是在待查代码中插入如下代码行，以了解变量 <i>mystuff</i> 的值：</p>
				<pre class="clsCode">alert("The value of mystuff is: "+mystuff);  
</pre>
				<p>在大多数情况下，它工作得非常好。不过，因为警告会强制显示对话框，而脚本将转让控制权。这一转让会导致显示更新以及某些布局样式值的变化。所以，后续脚本流程可能会与脚本中不存在警告时不同。我经常使用的一种调试技巧是在浏览器的状态栏中显示变量的值（而不是使用警告）：</p>
				<pre class="clsCode">window.status="The value of mystuff is: "+mystuff;  
</pre>
				<p>这样脚本的流程不会因为出现对话框而中断。</p>
				<p>另一种强制脚本转让控制权的方法是使用超时，在我们的示例脚本中将使用这一技巧。</p>
				<h3>超时</h3>
				<p>超时并不仅仅是美式足球中使用的一个奇怪概念。（在美式足球中，超时允许一个队中断比赛。）它还是一种强有力的脚本编写技巧，允许在经过一段时间后再调用脚本。可用的计时器方法有两种：<a href="http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/settimeout.asp">setTimeout</a>（英文）和 <a href="http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/setinterval.asp">setInterval</a>（英文）。它们的功能类似，<b>setTimeout</b> 提供对函数的唯一一次回调，而 <b>setInterval</b> 按照适当的时间间隔重复回调函数。这里我们使用 setTimeout。</p>
				<pre class="clsCode">&lt;SCRIPT&gt;
var i;
function longtime()
{
  i=0;
  timedIterations(); 
}

function timedIterations()
{
   if (i&lt;=500)
   { 
      d1.innerHTML="Count ="+i;
      // 下列语句代表需要一段时间的计算
      var j=0;      
      while (j&lt;=10000)
          j++;  
      setTimeout("timedIterations();", 1);
      i++;   
   }
}
&lt;/SCRIPT&gt;
&lt;INPUT TYPE="BUTTON" onclick="longtime();" value="Click Me"&gt;
&lt;DIV id="d1"&gt;This is where the count of iterations should display&lt;/DIV&gt;
&lt;SCRIPT&gt;
var i;
function longtime()
{
  i=0;
  timedIterations(); 
}

function timedIterations()
{
   if (i&lt;=1000)
   { 
      d1.innerHTML="Count ="+i;
      // 下列语句代表需要一段时间的计算
      var j=0;      
      while (j&lt;=10000)
          j++;  
      setTimeout("timedIterations();", 1);
      i++;   
   }
}
&lt;/SCRIPT&gt;
&lt;INPUT TYPE="BUTTON" onclick="longtime();" value="Click Me"&gt;
&lt;DIV id="d1"&gt;This is where the count of iterations should display&lt;/DIV&gt;
</pre>
				<p>
						<a href="http://www.microsoft.com/china/MSDN/library/archives/voiCEs/dude02262001-disp2.htm" target="new">查看示例</a>。</p>
				<p>在上面的示例中，我们使用了原来的代码。为清楚起见，我们将其分为两个函数，其中主函数 <i>timedIterations </i>使用 <b>setTimeout</b> 来再次调用其自身。这里 <b>setTimeout</b> 的频率设置为 1 毫秒，以便其能够尽快回调。不能依赖这些计时器来计算精确的毫秒数，但如果在上述示例中将超时设置为 1000 毫秒，其结果将精确到每次迭代耗时一秒。当然，您可以根据所执行的任务，自行决定如何将过程划分为片断来进行计时迭代。</p>
				<h3>让用户等待</h3>
				<p>现在这个示例做得很好，不过，我们往往想让用户在处理过程中等待，直至处理结束。一个简单的实现方法是禁止输入并显示等待光标：</p>
				<pre class="clsCode">&lt;SCRIPT&gt;
var i;
function longtime()
{
  i=0;
  b1.style.cursor="wait";
  b1.disabled=true; 
  timedIterations(); 
}

function timedIterations()
{
   if (i&lt;=500)
   { 
      d1.innerHTML="Count ="+i;
      // 下列语句代表需要一段时间的计算
      var j=0;      
      while (j&lt;=10000)
          j++;  
      setTimeout("timedIterations();", 1);
      i++;   
   }
   else
   {
        b1.style.cursor="";
        b1.disabled=false; 
   }
}
&lt;/SCRIPT&gt;
&lt;BODY id=b1&gt;
&lt;INPUT id="ip1" TYPE="BUTTON" onclick="longtime();" value="Click Me"&gt;
&lt;DIV id="d1"&gt;This is where the count of iterations should display&lt;/DIV&gt;
&lt;/BODY&gt;
</pre>
				<p>
						<a href="http://www.microsoft.com/china/MSDN/library/archives/voiCEs/dude02262001-disp3.htm" target="new">查看示例</a>。</p>
				<p>在上面的示例中，我加入了一点代码来禁用整个文档内容，并在进行迭代时显示等待光标。因此，浏览器将继续更新，用户不会锁定它，但同时用户也不能操作页面和导致其他事件发生。当然，这种方法非常直接，而您可能希望禁用页面的某些部分，而用户仍然能够通过一种集成的方式来放弃操作。“别只是拦住用户！”</p>
				<p>这个月要说的最后一点是：在编写 DHTML 功能时，重要的一点是不要将用户与浏览器隔离开来。如果整个浏览器看起来像是锁住了，会让用户感到非常不快。即使您不希望用户在执行长时间操作时更改页面上的任何内容，也不应该这样。可以在浏览器中使用某种功能给用户提供当前状态的反馈，让用户感觉良好。最后，我们对示例做了一个非常简单的修改，显示一个随迭代进度而增长的进度栏。</p>
				<p>
						<a href="http://www.microsoft.com/china/MSDN/library/archives/voiCEs/dude02262001-disp4.htm" target="new">查看示例</a>。</p>
				<p> </p>
				<hr noshade="" size="1" />
				<p class="clsMagFooter">
						<b>David Massy</b> 偶尔会戴上太阳眼镜扮酷，不过摘下墨镜的他是 Windows 和 Internet Explorer 技术的宣传人，也就是说，他向 Microsoft 的客户们介绍如何能够将各种技术发挥至极致。在成为技术宣传人之前，Dave 是 Internet Explorer 组的程序经理。因为 Dave 来自英国，他总是在不厌其烦地教美国同事们如何正确地读“tomato”这个词。 
</p>
				<p>
						<br />
				</p>
				<h4>已存档的 DHTML Dude 专栏文章</h4>
				<!-- START dude.inc -->
				<table class="clsCatItems" cellspacing="0" cellpadding="0" border="0">
						<tbody>
								<tr>
										<th colspan="2">
										</th>
										<th class="clsStoryTD" align="left">2001 年</th>
								</tr>
								<tr valign="top">
										<td class="clsPubdate" align="right" width="100">1 月 22 日</td>
										<td width="10">   </td>
										<td class="clsStoryTD">
												<a href="http://msdn.microsoft.com/workshop/author/dhtml/dude/dude01222001.asp">从 DHTML 访问 Web 服务</a>（英文）</td>
								</tr>
								<tr>
										<th colspan="2">
										</th>
										<th class="clsStoryTD" align="left">2000 年</th>
								</tr>
								<tr valign="top">
										<td class="clsPubdate" align="right" width="100">11 月 27 日</td>
										<td width="10">   </td>
										<td class="clsStoryTD">
												<a href="http://msdn.microsoft.com/workshop/author/dhtml/dude/dude11272000.asp">受挫的 Dude！（英文）</a>
										</td>
								</tr>
								<tr valign="top">
										<td class="clsPubdate" align="right" width="100">9 月 25 日</td>
										<td width="10">   </td>
										<td class="clsStoryTD">
												<a href="http://msdn.microsoft.com/workshop/author/dhtml/dude/dude09252000.asp">好的对话框的重要性（英文）</a>
										</td>
								</tr>
								<tr valign="top">
										<td class="clsPubdate" align="right" width="100">8 月 28 日</td>
										<td width="10">   </td>
										<td class="clsStoryTD">
												<a href="http://msdn.microsoft.com/workshop/author/dhtml/dude/dude08282000.asp">遗漏的失误</a>（英文）</td>
								</tr>
								<tr valign="top">
										<td class="clsPubdate" align="right" width="100">7 月 12 日</td>
										<td width="10">   </td>
										<td class="clsStoryTD">
												<a href="http://msdn.microsoft.com/workshop/author/dhtml/dude/dude07122000.asp">组件，组件，组件</a>（英文）</td>
								</tr>
								<tr valign="top">
										<td class="clsPubdate" align="right" width="100">6 月 5 日</td>
										<td width="10">   </td>
										<td class="clsStoryTD">
												<a href="http://msdn.microsoft.com/workshop/author/dhtml/dude/dude06052000.asp">完整的圆</a>（英文）</td>
								</tr>
								<tr valign="top">
										<td class="clsPubdate" align="right" width="100">4 月 3 日</td>
										<td width="10">   </td>
										<td class="clsStoryTD">
												<a href="http://msdn.microsoft.com/workshop/author/dhtml/dude/dude04032000.asp">定位和编辑</a>（英文）</td>
								</tr>
								<tr valign="top">
										<td class="clsPubdate" align="right" width="100">3 月 6 日</td>
										<td width="10">   </td>
										<td class="clsStoryTD">
												<a href="http://msdn.microsoft.com/workshop/author/dhtml/dude/dude03062000.asp">Web 服务</a>（英文）</td>
								</tr>
								<tr valign="top">
										<td class="clsPubdate" align="right" width="100">2 月 7 日</td>
										<td width="10">   </td>
										<td class="clsStoryTD">
												<a href="http://msdn.microsoft.com/workshop/standards/dude02072000.asp">Internet Explorer 和标准</a>（英文）</td>
								</tr>
								<tr valign="top">
										<td class="clsPubdate" align="right" width="100">1 月 3 日</td>
										<td width="10">   </td>
										<td class="clsStoryTD">
												<a href="http://msdn.microsoft.com/workshop/author/dhtml/dude/dude01032000.asp">组件万岁！（英文）</a>
										</td>
								</tr>
								<tr>
										<th colspan="2">
										</th>
										<th class="clsStoryTD" align="left">1999 年</th>
								</tr>
								<tr valign="top">
										<td class="clsPubdate" align="right" width="100">12 月 6 日</td>
										<td width="10">   </td>
										<td class="clsStoryTD">
												<a href="http://msdn.microsoft.com/workshop/author/databind/dude120699.asp">在访问数据源时设置</a>（英文）</td>
								</tr>
								<tr valign="top">
										<td class="clsPubdate" align="right" width="100">11 月 1 日</td>
										<td width="10">   </td>
										<td class="clsStoryTD">
												<a href="http://msdn.microsoft.com/workshop/author/databind/dude110199.asp">使用数据绑定的乐趣</a>（英文）</td>
								</tr>
								<tr valign="top">
										<td class="clsPubdate" align="right" width="100">10 月 4 日</td>
										<td width="10">   </td>
										<td class="clsStoryTD">
												<a href="http://msdn.microsoft.com/workshop/author/dhtml/dude/dude100499.asp">提高性能的更多技巧</a>（英文）</td>
								</tr>
								<tr valign="top">
										<td class="clsPubdate" align="right" width="100">9 月 6 日</td>
										<td width="10">   </td>
										<td class="clsStoryTD">
												<a href="http://msdn.microsoft.com/workshop/author/dhtml/dude/dude090699.asp">侏罗纪小子</a>（英文）</td>
								</tr>
								<tr valign="top">
										<td class="clsPubdate" align="right" width="100">8 月 2 日</td>
										<td width="10">   </td>
										<td class="clsStoryTD">
												<a href="http://msdn.microsoft.com/workshop/author/databind/dude080299.asp">重访虚拟列表</a>（英文）</td>
								</tr>
								<tr valign="top">
										<td class="clsPubdate" align="right" width="100">7 月 5 日</td>
										<td width="10">   </td>
										<td class="clsStoryTD">
												<a href="http://msdn.microsoft.com/workshop/author/hta/dude070599.asp">HTML 应用程序</a>（英文）</td>
								</tr>
								<tr valign="top">
										<td class="clsPubdate" align="right" width="100">6 月 7 日</td>
										<td width="10">   </td>
										<td class="clsStoryTD">
												<a href="http://msdn.microsoft.com/workshop/author/dhtml/dude/dude060799.asp">矢量和您</a>（英文）</td>
								</tr>
								<tr valign="top">
										<td class="clsPubdate" align="right" width="100">5 月 3 日</td>
										<td width="10">   </td>
										<td class="clsStoryTD">
												<a href="http://msdn.microsoft.com/workshop/author/dhtml/dude/dude050399.asp">Tabula Rasa</a>（英文）</td>
								</tr>
								<tr valign="top">
										<td class="clsPubdate" align="right" width="100">3 月 18 日</td>
										<td width="10">   </td>
										<td class="clsStoryTD">
												<a href="http://msdn.microsoft.com/workshop/author/dhtml/dude/dude031899.asp">您的最佳表现</a>（英文）</td>
								</tr>
								<tr>
								</tr>
								<tr valign="top">
										<td class="clsPubdate" align="right" width="100">1 月 4 日</td>
										<td width="10">   </td>
										<td class="clsStoryTD">
												<a href="http://msdn.microsoft.com/workshop/author/databind/dude010499.asp">倾斜的、平均的和事实上的数据绑定</a>（英文）</td>
								</tr>
								<tr>
										<th colspan="2">
										</th>
										<th class="clsStoryTD" align="left">1998 年</th>
								</tr>
								<tr>
								</tr>
								<tr valign="top">
										<td class="clsPubdate" align="right" width="100">12 月 7 日</td>
										<td>   </td>
										<td class="clsStoryTD">
												<a href="http://msdn.microsoft.com/workshop/author/dhtml/dude/dude120798.asp">假日小子</a>（英文）</td>
								</tr>
								<tr valign="top">
										<td class="clsPubdate" align="right" width="100">11 月 4 日</td>
										<td>   </td>
										<td class="clsStoryTD">
												<a href="http://msdn.microsoft.com/workshop/author/dhtml/dude/dude110498.asp">Beta 版表现更佳：自定义上下文菜单，从脚本打印，精美对话框</a>（英文）</td>
								</tr>
								<tr valign="top">
										<td class="clsPubdate" align="right" width="100">9 月 22 日</td>
										<td>   </td>
										<td class="clsStoryTD">
												<a href="http://msdn.microsoft.com/workshop/author/dhtml/dude/dude092298.asp">异步：<i>倍受喜爱</i>的性能</a>（英文）</td>
								</tr>
								<tr valign="top">
										<td class="clsPubdate" align="right" width="100">8 月 17 日</td>
										<td>   </td>
										<td class="clsStoryTD">
												<a href="http://msdn.microsoft.com/workshop/author/dhtml/dude/dude081798.asp">夏天，DHTML 很简单</a>（英文）</td>
								</tr>
								<tr valign="top">
										<td class="clsPubdate" align="right" width="100">7 月 17 日</td>
										<td>   </td>
										<td class="clsStoryTD">
												<a href="http://msdn.microsoft.com/workshop/author/dhtml/dude/dude071798.asp">条件注释，单选按钮</a>（英文）</td>
								</tr>
								<tr valign="top">
										<td class="clsPubdate" align="right" width="100">6 月 11 日</td>
										<td>   </td>
										<td class="clsStoryTD">
												<a href="http://msdn.microsoft.com/workshop/author/dhtml/dude061198.asp">动态性更强</a>（英文）</td>
								</tr>
								<tr valign="top">
										<td class="clsPubdate" align="right" width="100">4 月 6 日</td>
										<td>   </td>
										<td class="clsStoryTD">
												<a href="http://msdn.microsoft.com/workshop/author/dhtml/dude/dude040698.asp">现在是讨论许多事情的时候了</a>（英文）</td>
								</tr>
								<tr valign="top">
										<td class="clsPubdate" align="right" width="100">3 月 2 日</td>
										<td>   </td>
										<td class="clsStoryTD">
												<a href="http://msdn.microsoft.com/workshop/author/databind/dude030298.asp">让数据说话</a>（英文）</td>
								</tr>
								<tr valign="top">
										<td class="clsPubdate" align="right" width="100">1 月 5 日</td>
										<td>   </td>
										<td class="clsStoryTD">
												<a href="http://msdn.microsoft.com/workshop/author/dhtml/dude/dude010598.asp">吼叫的 Mouseover：面向对象的 HTML</a>（英文）</td>
								</tr>
								<tr>
										<th colspan="2">
										</th>
										<th class="clsStoryTD" align="left">1997 年</th>
								</tr>
								<tr>
								</tr>
								<tr valign="top">
										<td class="clsPubdate" align="right" width="100">12 月 1 日</td>
										<td>   </td>
										<td class="clsStoryTD">
												<a href="http://msdn.microsoft.com/workshop/author/dhtml/dude/dude1201.asp">频繁的飞跃：提高 DHTML 页面的性能</a>（英文）</td>
								</tr>
								<tr valign="top">
										<td class="clsPubdate" align="right" width="100">11 月 3 日</td>
										<td>   </td>
										<td class="clsStoryTD">
												<a href="http://msdn.microsoft.com/workshop/author/databind/dude1103.asp">绑定页面数据</a>（英文）</td>
								</tr>
								<tr valign="top">
										<td class="clsPubdate" align="right" width="100">10 月 1 日</td>
										<td>   </td>
										<td class="clsStoryTD">
												<a href="http://msdn.microsoft.com/workshop/author/dhtml/dude/dude1001.asp">识别您使用 DHTML 方法中的错误</a>（英文）</td>
								</tr>
						</tbody>
				</table>
				<!-- END TOTAL PAGE CONTENT -->
		</font>
<img src ="http://www.cppblog.com/phenix_jiang/aggbug/4531.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/phenix_jiang/" target="_blank">拼命流血</a> 2006-03-24 14:15 <a href="http://www.cppblog.com/phenix_jiang/articles/4531.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>从别人那转的:100本计算机经典书籍下载URL</title><link>http://www.cppblog.com/phenix_jiang/articles/4526.html</link><dc:creator>拼命流血</dc:creator><author>拼命流血</author><pubDate>Fri, 24 Mar 2006 05:17:00 GMT</pubDate><guid>http://www.cppblog.com/phenix_jiang/articles/4526.html</guid><wfw:comment>http://www.cppblog.com/phenix_jiang/comments/4526.html</wfw:comment><comments>http://www.cppblog.com/phenix_jiang/articles/4526.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/phenix_jiang/comments/commentRss/4526.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/phenix_jiang/services/trackbacks/4526.html</trackback:ping><description><![CDATA[
		<h1 class="block_title">
				<a id="viewpost1_TitleUrl" href="/liangbo/archive/2006/03/23/4503.html">从别人那转的:100本计算机经典书籍下载URL</a>
		</h1>
		<div class="post">
				<div class="postcontent">1.vc++技术内幕第四版 (潘爱民) <br />ftp://210.32.157.56/课件/c++primer/vc++技术内幕IV(潘爱民).rar <br />2.C++经典对话系列 <br />中文：http://www.jka77.com/book/cvst_cn.chm <br /><br />3.MFC Windows 程序设计(第二版) <br />英文版：http://www.jka77.com/book/progmfc2.chm <br />中文版：暂无，制作中... <br />4.Effective C++中文版： <br />http://dlb.pchome.net/development/reference/effectiveCplus.zip <br />5.More Effective C++中文版-zhc译 <br />http://cable.pchome.net/development/reference/MEC0410.zip <br /><br />6.More Effective C++中文版-候捷译 <br />http://www.nethovel.com/resources/MoreEffectiveC++(WQ).zip <br /><br />7.Essential C++中文版(全)－候捷译 <br />http://www.nethovel.com/resources/Essential%20C++中文版(全).rar <br /><br />8.深入浅出MFC 2/e <br />http://218.30.21.125:8084/ebook/programme/mfc2e.zip <br /><br />9.代码大全中文版 <br />http://www.delphidevelopers.com/docs/tecsubject/cc/CodeComplet110.zip <br /><br />11.C++经典对话系列 <br />中文：http://www.jka77.com/book/cvst_cn.chm <br /><br />12.MFC Windows 程序设计(第二版) <br />英文版：http://www.jka77.com/book/progmfc2.chm <br />中文版：暂无，制作中... <br /><br />13.数据结构 C++ 语言描述(中文版) <br />http://www.code-labs.com/manual/c_c015.zip <br /><br />14.Java编程思想中文版 <br />ftp://202.118.72.12/pub/doc-book/Java/Java编程思想.zip <br /><br />15.C++标准库英文版 <br />ftp://166.111.64.4/incoming/新文件夹/f/The%20C++%20Standard%20Library(with%20TOC).pdf <br /><br />16.Windows核心编程 <br />英文：http://www.fmdstudio.net/book/prgapps4.zip <br /><br />17.TCP-IP详解卷1：协议 <br />ftp://202.204.4.161/学习资料/TCPIP/TCP-IP详解卷1：协议.pdf <br /><br />18.TCP-IP详解卷2：实现 <br />ftp://202.204.4.161/学习资料/TCPIP/TCP-IP详解卷3：TCP事务协议，HTTP，NNTP.pdf <br /><br />19.TCP-IP详解卷3：TCP事务协议 <br />ftp://202.204.4.161/学习资料/TCPIP/TCP-IP详解卷2：实现.pdf <br /><br />20.实用算法的分析与程序设计 <br />ftp://202.204.8.10/[4]%20编程资源/[%20书籍资料%20]/[算法与数据结构]/实用算法的分析与程序设计.rar <br /><br />21.vc++技术内幕第四版 (潘爱民) <br />ftp://210.32.157.56/课件/c++primer/vc++技术内幕IV(潘爱民).rar <br /><br />22.C++ Primer英文版： <br />http://computerstep.w18.net/C/C++%20Primer.zip <br /><br />23.Effective C++中文版： <br />http://dlb.pchome.net/development/reference/effectiveCplus.zip <br /><br />24.More Effective C++中文版-zhc译 <br />http://cable.pchome.net/development/reference/MEC0410.zip <br /><br />25.More Effective C++中文版-候捷译 <br />http://www.nethovel.com/resources/MoreEffectiveC++(WQ).zip <br /><br />26.Essential C++中文版(全)－候捷译 <br />http://www.nethovel.com/resources/Essential%20C++中文版(全).rar <br /><br />27.Programming Windows程式开发设计指南－Petzoldi著 余孟学 译 <br />中文版：http://www.nethovel.com/resources/ProgrammingWindows_tw.chm <br />英文版：http://www.nethovel.com/resources/Petzoldi.chm <br /><br />28.WinAsm32汇编教程－ Iczelion <br />http://www.nethovel.com/resources/winasm.chm <br /><br />29.Windows 95 程序设计指南－候捷译 <br />http://www.nethovel.com/resources/win95adg.zip <br /><br />30.Thinking in C++ 2nd Edition(C++编程思想) <br />英文版：http://www.nethovel.com/resources/ThinkinginC++.zip <br />中文版：http://www.dingbing.com/book/thinkc.zip <br /><br />31.人月神话－中文版 <br />http://www.goodassister.com/book/rysh.pdf <br /><br />32.The C++ Programming Language英文 <br />http://computerstep.w18.net/C/The%20C++%20Programming%20Language.rar <br /><br />33.VC技术内幕第五版 http://www.helpwork.com/downdata/book/programming/vc/book/vc++2/invcpp5.chm <br /><br />34.com技术内幕 <br />http://www.helpwork.com/book/html/user/download.asp?id=1123 <br /><br />35.com＋技术内幕 <br />http://www.helpwork.com/book/html/user/download.asp?id=952 <br /><br />36.新编 Windows API参考大全 <br />http://www.4046.com/nnsrc/down/WindowsAPIdq.rar <br /><br />37.The C programming Language // By Brian W. Kernighan and Dennis M. Ritchie <br />下载地址：http://www.jka77.com/book/The_C_programmin.chm <br /><br />38.C语言编程手册 <br />下载地址：http://www.jka77.com/book/CL.chm <br /><br />39.Delphi 7高效数据库程序设计 <br />By 李维 <br />下载地址:http://www.codestudy.net/book/download.asp?id=1163&amp;sort=5 <br /><br />40.Windows网络编程(第2版) <br />By Anthony Jones,Jim Ohlund 清华大学出版社 <br />下载地址：英文版:http://www.guxiang.com/epubcn/readings/diannaotushu/500/download/1107/network_prog_for_win_2nd.zip <br /><br />41.Windows2000编程技术内幕 <br />By Mickey Williams 机械工业出版社 <br />下载地址：ftp://ftp.frontfree.net/Pub/Books/C&amp;C++/VC/Windows2000编程技术内幕.rar <br /><br />42.数据仓库 <br />By W.H.Inmon 清华大学出版社 <br />下载地址1：http://tips.9hao.com/vvbksd/20011120/数据仓库.zip <br />下载地址2: ftp://ftp.math.nankai.edu.cn/Ebook/China-pub/chinapub_computerscience_multimedia/ComputerScience/%CA%FD%BE%DD%B2%D6%BF%E2/ <br /><br />43.编码的奥秘 <br />By Charles Petzold 机械工业出版社 <br />下载地址：ftp://ftp.math.nankai.edu.cn/Ebook/China-pub/chinapub_computerscience_multimedia/ComputerScience/%B1%E0%C2%EB%B5%C4%B0%C2%C3%D8/ <br /><br />44.编译原理及实践 <br />By Louden, K.C 机械工业出版社 <br />下载地址：ftp://ftp.math.nankai.edu.cn/Ebook/China-pub/chinapub_computerscience_multimedia/ComputerScience/%B1%E0%D2%EB%D4%AD%C0%ED%BC%B0%CA%B5%BC%F9/ <br /><br />45.Inside C++ Object Model(深度探索C++对象模型） <br />By Lippman 候捷译 <br />下载地址：http://www.jka77.com/book/inside-the-cpp-object-model.pdf <br /><br />46.C++标准程序库 <br />By Josuttis <br />下载地址1：http://www.codestudy.net/book/download.asp?id=1205&amp;sort=5 <br />下载地址2: ftp://ftp.math.nankai.edu.cn/Ebook/C_C++/The Cpp Standard Library.pdf <br /><br />47.STL源码剖析 <br />By 候捷 <br />下载地址：ftp://ftp.math.nankai.edu.cn/Ebook/C_C++/STL源码剖析--侯捷.pdf <br /><br />48.C++批判(第三版) -看看C++的坏话！ <br />By I don't know <br />下载地址：http://www.jka77.com/book/CPPPP.pdf <br /><br />49.程序设计实践 <br />下载地址：ftp://ftp.math.nankai.edu.cn/Ebook/China-pub/chinapub_computerscience_multimedia/%B3%CC%D0%F2%C9%E8%BC%C6%CA%B5%BC%F9/ <br /><br />50.c++沉思录 <br />By Andrew Koenig Barbara Moo 人民邮电出版社 <br />下载地址：http://www.codestudy.net/book/download.asp?id=1261&amp;sort=5 <br /><br />51.C++Builder4技术内幕 (这本书俺不知道好不好） <br />By I don't Know <br />下载地址：http://www.codestudy.net/book/download.asp?id=1254&amp;sort=5 <br /><br />52.下面两本书一般大家硬盘里都有的吧，而且很老了，但是为了全面，就提上来吧 <br />(1)Windows 95 程式设计指南 - 候捷 <br />下载地址：http://jjhou.csdn.net/win95-a-developers-guide.pdf <br />(2)Windows 95 系统程式设计大奥秘 - 候捷 <br />下载地址：http://jjhou.csdn.net/windows95-system-programming-secrets.pdf <br /><br />53. 中国大百科全书·数学 <br />下载地址：ftp://ftp.math.nankai.edu.cn/Ebook/中国大百科全书/中国大百科全书·数学.pdf <br /><br />54、4.0M Bjarne Stroustrup - The C++ Programming Language <br />http://www.u-n-f.com/books/archive/The%20C++%20Programming%20Language.tar.gz <br /><br />55、1.0M Richard Stevens - TCP-IP Illustrated <br />http://www.u-n-f.com/books/archive/TCP-IP%20Illustrated.tar.gz <br /><br />56、4.5M Randall Hyde - Art Of Assembly <br />http://www.u-n-f.com/books/archive/Randall%20Hyde%20-%20Art%20Of%20Assembly.tar.gz <br /><br />57、2.1M M. Abrash - Zen of Graphics Programming <br />http://www.u-n-f.com/books/archive/M.%20Abrash%20-%20Zen%20of%20Graphics%20Programming.zip <br /><br />58、249k Kernighan and Ritche - The C Programming Language <br />http://www.u-n-f.com/books/archive/Kernighan%20and%20Ritchie%20-%20The%20C%20Programming%20Language.zip <br /><br />59、3.3M Bruce Schneier - Applied Cryptography <br />http://www.u-n-f.com/books/archive/Bruce%20Schneier%20-%20Applied%20Cryptography.zip <br /><br />60、PHP4_Grundlagen_und_Profiwissen <br />http://www.u-n-f.com/books/archive/lamp/PHP4_Grundlagen_und_Profiwissen.pdf <br /><br />61.《C++ Builder高级编程技术》 <br />http://www.dingbing.com/book/builder.zip <br /><br />62.《VC++ 6.0 TLR 模板库参考手册》 <br />http://www.easysea.com/diannao/download/prog/c/mbkc.zip <br /><br />63.《BORLAND C++ BUILDER 实用培训教程》 <br />http://202.101.232.120/book/openfile.asp?id=223&amp;filename=BC98_CB526.zip <br /><br />64.《Delphi高级开发指南》 <br />http://www.pcbookcn.com/s10899book/program/delphi/Delphi_gjkfzn_for3.rar <br /><br />65.《新编 Windows API参考大全》 <br />ftp://book:book@down.pcbookcn.com/pro/delphi/新编Windows_API_参考大全.rar <br /><br />66.《Delphi深度历险-附书源码》 <br />http://www.pcbookcn.com/s10899book/program/delphi/Delphi_sdlx_code.rar <br /><br />67.《Delphi 7高效数据库程序设计》 <br />ftp://book:book@down.pcbookcn.com/pro/delphi/李维的新书《Delphi7高效数据库程序设计》.rar <br /><br />68.《Delphi7开发指南》 <br />ftp://book:book@down.pcbookcn.com/pro/delphi/delphi7开发指南.rar <br /><br />69.《Delphi6集成开发环境》 <br />ftp://book:book@down.pcbookcn.com/pro/delphi/Delphi6集成开发环境.rar <br /><br />70.《Delphi6数据库编程》 <br />ftp://book:book@down.pcbookcn.com/pro/delphi/Delphi6数据库编程.rar <br /><br />72.《Delphi5.xADO_MTS_COM+高级程序设计篇》 <br />ftp://book:book@down.pcbookcn.com/pro/delphi/Delphi5.xADO_MTS_COM+高级程序设计篇.rar <br /><br />73.《VISUAL BASIC 编程标准》 <br />http://www.dingbing.com/book/vb.zip <br /><br />74.《Visual Basic6.0中文版程序员指南》 <br />http://www.easysea.com/diannao/download/prog/vb/zwbc.zip <br /><br />75.《Visual Basic 6.0 控件参考手册》 <br />http://www.easysea.com/diannao/download/prog/vb/kjck.zip <br /><br />76.《Visual Basic 6.0中文版语言参考手册》 <br />http://www.easysea.com/diannao/download/prog/vb/zwby.zip <br /><br />77.《Visual Basic 6.0 开发宝典》 <br />http://www.easysea.com/diannao/download/prog/vb/kfbd.zip <br /><br />78.《Visual Basic 6.0 实例教程》 <br />http://www.easysea.com/diannao/download/prog/vb/sljc.zip <br /><br />79.《VB 6.0 中文版实用参考手册》 <br />http://www.easysea.com/diannao/download/prog/vb/syck.zip <br /><br />80.《Visual Basic 6开发人员指南》 <br />http://www.easysea.com/diannao/download/prog/vb/kfzn.zip <br /><br />81.《VB 和 SQL Server 编程指南（第五版）》 <br />http://www.easysea.com/diannao/download/prog/vb/bczn.zip <br /><br />82.《Jbuilder 5 中文帮助》 <br />http://www.pdown.net/download.asp?downid=2&amp;id=991 <br /><br />83.《JBuilder开发人员指南》 <br />http://youth.dlmu.edu.cn/book/list_down.php?bkid=224 <br /><br />84.《Win32的Internet函数说明》 <br />档案大小： 245248K <br />http://www.easysea.com/diannao/download/prog/windows/win32int.zip <br /><br />85.《Visual InterDev 从入门到精通》 <br />http://www.easysea.com/diannao/download/prog/interdev/crmd.wdl <br /><br />86.《Visual InterDev 6.0 Web 参考手册 》 <br />http://www.easysea.com/diannao/download/prog/interdev/jsck.zip <br /><br />87.《Visual InterDev 6.0 Guide 程序员》 <br />http://www.easysea.com/diannao/download/prog/interdev/cxyz.zip <br /><br />88.《JavaScript 程序开发手册》 <br />http://www.cty99.com/Templet/bookdownmore.asp?booktype=script# <br /><br />89.《JAVA 大全》 <br />http://www.easysea.com/diannao/download/prog/java/cxkf.zip <br /><br />90.《Visual J++ 6.0 WFC 类库参考手册》 <br />http://www.easysea.com/diannao/download/prog/java/lkck.zip <br /><br />91.《Java联想（中文）》 <br />http://www.easysea.com/diannao/download/prog/java/lkck.zip <br /><br />92.《Oracle 8 实用大全》 <br />http://www.easysea.com/diannao/download/prog/oracle/sydq.zip <br /><br />93.《Microsoft SQL Server 管理员手册》 <br />http://www.easysea.com/diannao/download/prog/sql/glys.zip <br /><br />94.《掌握ACCESS开发》 <br />http://www.easysea.com/diannao/download/prog/sql/glys.zip <br /><br />95.《Oracle Performance Tuning and Optimization》 <br />http://www.oradb.net/book/oracle_pt.zip <br /><br />96.《Oracle ProC 程序设计》 <br />http://www.oradb.net/book/oracleproc.zip <br /><br />97.《Oracle8初学者指南》 <br />http://www.easysea.com/diannao/download/prog/oracle/cxzz.zip <br /><br />98.《RED HAT LINUX 6大全》 <br />http://www.dingbing.com/book/redhatall.zip <br /><br />99.《RED HAT LINUX 6管理工具》 <br />http://www.dingbing.com/book/redhatman.zip <br /><br />100.《VC++高级编程》 <br />http://www.easysea.com/diannao/download/prog/c/vcgj.zip<br /></div>
		</div>
<img src ="http://www.cppblog.com/phenix_jiang/aggbug/4526.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/phenix_jiang/" target="_blank">拼命流血</a> 2006-03-24 13:17 <a href="http://www.cppblog.com/phenix_jiang/articles/4526.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>每个开发人员现在应该下载的十种</title><link>http://www.cppblog.com/phenix_jiang/articles/4408.html</link><dc:creator>拼命流血</dc:creator><author>拼命流血</author><pubDate>Tue, 21 Mar 2006 04:49:00 GMT</pubDate><guid>http://www.cppblog.com/phenix_jiang/articles/4408.html</guid><wfw:comment>http://www.cppblog.com/phenix_jiang/comments/4408.html</wfw:comment><comments>http://www.cppblog.com/phenix_jiang/articles/4408.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/phenix_jiang/comments/commentRss/4408.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/phenix_jiang/services/trackbacks/4408.html</trackback:ping><description><![CDATA[
		<h2>
				<a id="viewpost1_TitleUrl" href="http://blog.aspcool.com/tim/archive/2004/07/22/644.html">每个开发人员现在应该下载的十种必备工具</a>
		</h2>
		<div class="postbody">
				<div class="overview">
						<p>转自：<a href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/TenMHToolEDevShouDN.mspx">Microsoft </a></p>
						<p>本文讨论：</p>
						<table cellspacing="0" cellpadding="0" border="0">
								<tbody>
										<tr>
												<td class="listBullet" valign="top">•</td>
												<td class="listItem">
														<p>用于编写单元测试的 NUnit</p>
												</td>
										</tr>
										<tr>
												<td class="listBullet" valign="top">•</td>
												<td class="listItem">
														<p>用于创建代码文档资料的 NDoc</p>
												</td>
										</tr>
										<tr>
												<td class="listBullet" valign="top">•</td>
												<td class="listItem">
														<p>用于生成解决方案的 NAnt</p>
												</td>
										</tr>
										<tr>
												<td class="listBullet" valign="top">•</td>
												<td class="listItem">
														<p>用于生成代码的 CodeSmith</p>
												</td>
										</tr>
										<tr>
												<td class="listBullet" valign="top">•</td>
												<td class="listItem">
														<p>用于监视代码的 FxCop</p>
												</td>
										</tr>
										<tr>
												<td class="listBullet" valign="top">•</td>
												<td class="listItem">
														<p>用于编译少量代码的 Snippet Compiler</p>
												</td>
										</tr>
										<tr>
												<td class="listBullet" valign="top">•</td>
												<td class="listItem">
														<p>两种不同的转换器工具：ASP.NET 版本转换器和 Visual Studio .NET 项目转换器</p>
												</td>
										</tr>
										<tr>
												<td class="listBullet" valign="top">•</td>
												<td class="listItem">
														<p>用于生成正则表达式的 Regulator</p>
												</td>
										</tr>
										<tr>
												<td class="listBullet" valign="top">•</td>
												<td class="listItem">
														<p>用于分析程序集的 .NET Reflector</p>
												</td>
										</tr>
								</tbody>
						</table>
						<p>
								<b>本文使用了下列技术：</b>
						</p>
						<p>.NET、C# 或 Visual Basic .NET、Visual Studio .NET</p>
						<p>除非您使用能够获得的最佳工具，否则您无法期望生成一流的应用程序。除了像 Visual Studio®.NET 这样的著名工具以外，还可以从 .NET 社区获得许多小型的、不太为人所知的工具。在本文中，我将向您介绍一些目前可以获得的、面向 .NET 开发的最佳免费工具。我将引导您完成一个有关如何使用其中每种工具的快速教程 — 一些工具在许多时候可以使您节约一分钟，而另一些工具则可能彻底改变您编写代码的方式。因为我要在本篇文章中介绍如此之多的不同工具，所以我无法详尽讨论其中每种工具，但您应该了解到有关每种工具的足够信息，以便判断哪些工具对您的项目有用。</p>
				</div>
				<center>
						<img title="" height="6" alt="*" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/3squares.gif" width="30" border="0" />
				</center>
				<div style="HEIGHT: 18px">
				</div>
				<h5 style="PADDING-TOP: 2px">本页内容</h5>
				<table style="MARGIN-TOP: 7px; MARGIN-BOTTOM: 12px" cellspacing="0" cellpadding="0" border="0">
						<tbody>
								<tr valign="top">
										<td>
												<a href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/TenMHToolEDevShouDN.mspx#XSLTsection122121120120">
														<img height="9" alt="Snippet Compiler" hspace="4" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_down.gif" width="7" vspace="2" border="0" />
												</a>
										</td>
										<td class="onThisPage">
												<a href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/TenMHToolEDevShouDN.mspx#XSLTsection122121120120">Snippet Compiler</a>
										</td>
								</tr>
								<tr valign="top">
										<td>
												<a href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/TenMHToolEDevShouDN.mspx#XSLTsection123121120120">
														<img height="9" alt="Regulator" hspace="4" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_down.gif" width="7" vspace="2" border="0" />
												</a>
										</td>
										<td class="onThisPage">
												<a href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/TenMHToolEDevShouDN.mspx#XSLTsection123121120120">Regulator</a>
										</td>
								</tr>
								<tr valign="top">
										<td>
												<a href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/TenMHToolEDevShouDN.mspx#XSLTsection124121120120">
														<img height="9" alt="CodeSmith" hspace="4" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_down.gif" width="7" vspace="2" border="0" />
												</a>
										</td>
										<td class="onThisPage">
												<a href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/TenMHToolEDevShouDN.mspx#XSLTsection124121120120">CodeSmith</a>
										</td>
								</tr>
								<tr valign="top">
										<td>
												<a href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/TenMHToolEDevShouDN.mspx#XSLTsection125121120120">
														<img height="9" alt="生成自定义模板" hspace="4" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_down.gif" width="7" vspace="2" border="0" />
												</a>
										</td>
										<td class="onThisPage">
												<a href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/TenMHToolEDevShouDN.mspx#XSLTsection125121120120">生成自定义模板</a>
										</td>
								</tr>
								<tr valign="top">
										<td>
												<a href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/TenMHToolEDevShouDN.mspx#XSLTsection126121120120">
														<img height="9" alt="NUnit" hspace="4" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_down.gif" width="7" vspace="2" border="0" />
												</a>
										</td>
										<td class="onThisPage">
												<a href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/TenMHToolEDevShouDN.mspx#XSLTsection126121120120">NUnit</a>
										</td>
								</tr>
								<tr valign="top">
										<td>
												<a href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/TenMHToolEDevShouDN.mspx#XSLTsection127121120120">
														<img height="9" alt="编写 NUnit 测试" hspace="4" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_down.gif" width="7" vspace="2" border="0" />
												</a>
										</td>
										<td class="onThisPage">
												<a href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/TenMHToolEDevShouDN.mspx#XSLTsection127121120120">编写 NUnit 测试</a>
										</td>
								</tr>
								<tr valign="top">
										<td>
												<a href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/TenMHToolEDevShouDN.mspx#XSLTsection128121120120">
														<img height="9" alt="FxCop" hspace="4" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_down.gif" width="7" vspace="2" border="0" />
												</a>
										</td>
										<td class="onThisPage">
												<a href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/TenMHToolEDevShouDN.mspx#XSLTsection128121120120">FxCop</a>
										</td>
								</tr>
								<tr valign="top">
										<td>
												<a href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/TenMHToolEDevShouDN.mspx#XSLTsection129121120120">
														<img height="9" alt="Lutz Roeder 的 .NET Reflector" hspace="4" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_down.gif" width="7" vspace="2" border="0" />
												</a>
										</td>
										<td class="onThisPage">
												<a href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/TenMHToolEDevShouDN.mspx#XSLTsection129121120120">Lutz Roeder 的 .NET Reflector</a>
										</td>
								</tr>
								<tr valign="top">
										<td>
												<a href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/TenMHToolEDevShouDN.mspx#XSLTsection130121120120">
														<img height="9" alt="NDoc" hspace="4" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_down.gif" width="7" vspace="2" border="0" />
												</a>
										</td>
										<td class="onThisPage">
												<a href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/TenMHToolEDevShouDN.mspx#XSLTsection130121120120">NDoc</a>
										</td>
								</tr>
								<tr valign="top">
										<td>
												<a href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/TenMHToolEDevShouDN.mspx#XSLTsection131121120120">
														<img height="9" alt="NAnt" hspace="4" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_down.gif" width="7" vspace="2" border="0" />
												</a>
										</td>
										<td class="onThisPage">
												<a href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/TenMHToolEDevShouDN.mspx#XSLTsection131121120120">NAnt</a>
										</td>
								</tr>
								<tr valign="top">
										<td>
												<a href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/TenMHToolEDevShouDN.mspx#XSLTsection132121120120">
														<img height="9" alt="实际运行的 NAnt" hspace="4" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_down.gif" width="7" vspace="2" border="0" />
												</a>
										</td>
										<td class="onThisPage">
												<a href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/TenMHToolEDevShouDN.mspx#XSLTsection132121120120">实际运行的 NAnt</a>
										</td>
								</tr>
								<tr valign="top">
										<td>
												<a href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/TenMHToolEDevShouDN.mspx#XSLTsection133121120120">
														<img height="9" alt="转换工具" hspace="4" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_down.gif" width="7" vspace="2" border="0" />
												</a>
										</td>
										<td class="onThisPage">
												<a href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/TenMHToolEDevShouDN.mspx#XSLTsection133121120120">转换工具</a>
										</td>
								</tr>
								<tr valign="top">
										<td>
												<a href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/TenMHToolEDevShouDN.mspx#XSLTsection134121120120">
														<img height="9" alt="小结" hspace="4" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_down.gif" width="7" vspace="2" border="0" />
												</a>
										</td>
										<td class="onThisPage">
												<a href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/TenMHToolEDevShouDN.mspx#XSLTsection134121120120">小结</a>
										</td>
								</tr>
						</tbody>
				</table>
				<a name="XSLTsection122121120120">
				</a>
				<h2>Snippet Compiler</h2>
				<p>Snippet Compiler 是一个基于 Windows® 的小型应用程序，您可以通过它来编写、编译和运行代码。如果您具有较小的代码段，并且您不希望为其创建完整的 Visual Studio .NET 项目（以及伴随该项目的所有文件），则该工具将很有用。</p>
				<p>例如，假设我希望向您说明如何从 Microsoft?.NET 框架中启动另一个应用程序。在 Snippet Compiler 中，我将通过新建一个能够创建小型控制台应用程序的文件开始。可以在该控制台应用程序的 Main 方法内部创建代码片段，而这正是我要在这里做的事情。下面的代码片段演示了如何从 .NET 框架中创建记事本实例： </p>
				<pre class="codeSample">System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo.FileName= "notepad.exe";
proc.Start();
proc.WaitForExit();
</pre>
				<p>当然该代码片段本身无法编译，而这正是 Snippet Compiler 的用武之地。图 1 显示了 Snippet Compiler 中的这一代码示例。</p>
				<div style="WIDTH: 400px">
						<img height="320" alt="" src="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/art/TMHTEDSDN01.gif" width="400" border="0" />
						<br />
						<p class="figureCaption">
								<b>图</b>
								<b> 1</b> Snippet Compiler</p>
						<div class="figureRule">
						</div>
				</div>
				<p>要测试该代码片段，只须按 play（运行）按钮（绿色三角形），它就会在调试模式下运行。该代码片段将生成一个弹出式控制台应用程序，并且将显示记事本。当您关闭记事本时，该控制台应用程序也将关闭。</p>
				<p>就我个人而言，我是在尝试为某位向我求助的人士创建一个小型示例时，才发现 Snippet Compiler 是如此宝贵的 — 如果不使用该工具，则我通常必须新建一个项目，确保每个部分都能编译通过，然后将代码片段发送给求助者，并删除该项目。Snippet Compiler 使得这一过程变得更加容易、更加愉快。</p>
				<p>Snippet Compiler 由 Jeff Key 编写，并且可以从 <a href="http://www.sliver.com/dotnet/SnippetCompiler" target="_blank">http://www.sliver.com/dotnet/SnippetCompiler</a> 下载。</p>
				<div style="MARGIN-TOP: 3px; MARGIN-BOTTOM: 10px">
						<a href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/TenMHToolEDevShouDN.mspx#top">
								<img height="9" alt="返回页首" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_up.gif" width="7" border="0" />
						</a>
						<a class="topOfPage" href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/TenMHToolEDevShouDN.mspx#top">返回页首</a>
				</div>
				<a name="XSLTsection123121120120">
				</a>
				<h2>Regulator</h2>
				<p>Regulator 是最后一个添加到我的头等工具清单中的。它是一种很有特色的工具，能够使生成和测试正则表达式变得很容易。人们对正则表达式重新产生了兴趣，因为它们在 .NET 框架中受到很好的支持。正则表达式用来基于字符、频率和字符顺序定义字符串中的模式。它们最常见的用途是作为验证用户输入有效性的手段或者作为在较大字符串中查找字符串的方法 — 例如，在 Web 页上查找 URL 或电子邮件地址。</p>
				<p>Regulator 使您可以输入一个正则表达式以及一些针对其运行该表达式的输入内容。这样，在应用程序中实现该正则表达式之前，您可以了解它将产生什么效果以及它将返回哪些种类的匹配项。<a href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/art/TMHTEDSDN02.htm" target="_blank">图 2</a> 显示了带有简单正则表达式的 Regulator。</p>
				<p>文档中包含该正则表达式 — 在该示例中，它是 [0-9]*，应该匹配一行中任意数量的数字。右下侧的框中含有针对该正则表达式的输入，而左下侧的框显示了该正则表达式在输入内容中找到的匹配项。在这样的单独应用程序中编写和测试正则表达式，要比尝试在您的应用程序中处理它们容易得多。</p>
				<p>Regulator 中的最佳功能之一是能够在 regexlib.com 搜索联机正则表达式库。例如，如果您在搜索框中输入字符串“phone”，您将找到 20 种以上能够匹配各种电话号码的不同的正则表达式，包括用于英国、澳大利亚的表达式以及其他许多电话号码。Regulator 由 Roy Osherove 编写，并且可以在 <a href="http://royo.is-a-geek.com/regulator" target="_blank">http://royo.is-a-geek.com/regulator</a> 下载。</p>
				<div style="MARGIN-TOP: 3px; MARGIN-BOTTOM: 10px">
						<a href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/TenMHToolEDevShouDN.mspx#top">
								<img height="9" alt="返回页首" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_up.gif" width="7" border="0" />
						</a>
						<a class="topOfPage" href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/TenMHToolEDevShouDN.mspx#top">返回页首</a>
				</div>
				<a name="XSLTsection124121120120">
				</a>
				<h2>CodeSmith</h2>
				<p>CodeSmith 是一种基于模板的代码生成工具，它使用类似于 ASP.NET 的语法来生成任意类型的代码或文本。与其他许多代码生成工具不同，CodeSmith 不要求您订阅特定的应用程序设计或体系结构。使用 CodeSmith，可以生成包括简单的强类型集合和完整应用程序在内的任何东西。</p>
				<p>当您生成应用程序时，您经常需要重复完成某些特定的任务，例如编写数据访问代码或者生成自定义集合。CodeSmith 在这些时候特别有用，因为您可以编写模板自动完成这些任务，从而不仅提高您的工作效率，而且能够自动完成那些最为乏味的任务。CodeSmith 附带了许多模板，包括对应于所有 .NET 集合类型的模板以及用于生成存储过程的模板，但该工具的真正威力在于能够创建自定义模板。为了使您能够入门，我将快速介绍一下如何生成自定义模板。</p>
				<div style="MARGIN-TOP: 3px; MARGIN-BOTTOM: 10px">
						<a href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/TenMHToolEDevShouDN.mspx#top">
								<img height="9" alt="返回页首" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_up.gif" width="7" border="0" />
						</a>
						<a class="topOfPage" href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/TenMHToolEDevShouDN.mspx#top">返回页首</a>
				</div>
				<a name="XSLTsection125121120120">
				</a>
				<h2>生成自定义模板</h2>
				<p>CodeSmith 模板只是一些可以在任意文本编辑器中创建的文本文件。它们的唯一要求是用 .cst 文件扩展名来保存它们。我将要生成的示例模板将接受一个字符串，然后基于该字符串生成一个类。创建模板的第一步是添加模板头，它可声明模板的语言、目标语言以及简要模板说明： </p>
				<pre class="codeSample"><![CDATA[<%@ CodeTemplate Language="C#"    
   TargetLanguage="C#" 
   Description="Car Template" %>]]&gt;</pre>
				<p>模板的下一部分是属性声明，在这里可声明将在模板每次运行时指定的属性。就该模板而言，我要使用的唯一属性只是一个字符串，因此属性声明如下所示： </p>
				<pre class="codeSample"><![CDATA[<%@ Property Name="ClassName" Type="String" Category="Context" 
    Description="Class Name" %>]]&gt;</pre>
				<p>该属性声明将使 ClassName 属性出现在 CodeSmith 属性窗口中，以便可以在模板运行时指定它。下一步是实际生成模板主体，它非常类似于用 ASP.NET 进行编码。您可以在<a href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/art/TMHTEDSDN03.htm" target="_blank">图 3</a> 中查看该模板的主体。[<b>编辑更新 — </b><b>6/16/2004</b>：图 3 中的代码已被更新，以便对多线程操作保持安全。]</p>
				<p>正如您所见，该模板接受字符串输入并使用该类名生成单独的类。在模板主体中，使用与 ASP.NET 中相同的起始和结束标记。在该模板中，我只是插入属性值，但您还可以在这些标记内部使用任意类型的 .NET 代码。在该模板完成之后，您就可以通过双击它或者从 CodeSmith 应用程序中打开它将其加载到 CodeSmith 中。<a href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/art/TMHTEDSDN04.htm" target="_blank">图 4</a> 显示了已经加载到 CodeSmith 中的该模板。</p>
				<p>您可以看到左侧的属性正是我在该模板中声明的属性。如果我输入“SingletonClass”作为类名，并单击 Generate 按钮，则将生成<a href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/art/TMHTEDSDN03.htm" target="_blank">图 3</a> 的底部显示的类。</p>
				<p>CodeSmith 使用起来相当容易，如果能够正确应用，则可以产生一些令人难以置信的结果。面向代码生成的应用程序中最常见的部分之一是数据访问层。CodeSmith 包括一个名为 SchemaExplorer 的特殊的程序集，可用来从表、存储过程或几乎任何其他 SQL Server? 对象生成模板。</p>
				<p>CodeSmith 由 Eric J. Smith 编写，并且可以在 <a href="http://www.ericjsmith.net/codesmith" target="_blank">http://www.ericjsmith.net/codesmith</a> 下载。</p>
				<div style="MARGIN-TOP: 3px; MARGIN-BOTTOM: 10px">
						<a href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/TenMHToolEDevShouDN.mspx#top">
								<img height="9" alt="返回页首" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_up.gif" width="7" border="0" />
						</a>
						<a class="topOfPage" href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/TenMHToolEDevShouDN.mspx#top">返回页首</a>
				</div>
				<a name="XSLTsection126121120120">
				</a>
				<h2>NUnit</h2>
				<p>NUnit 是为 .NET 框架生成的开放源代码单元测试框架。NUnit 使您可以用您喜欢的语言编写测试，从而测试应用程序的特定功能。当您首次编写代码时，单元测试是一种测试代码功能的很好方法，它还提供了一种对应用程序进行回归测试的方法。NUnit 应用程序提供了一个用于编写单元测试的框架，以及一个运行这些测试和查看结果的图形界面。</p>
				<div style="MARGIN-TOP: 3px; MARGIN-BOTTOM: 10px">
						<a href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/TenMHToolEDevShouDN.mspx#top">
								<img height="9" alt="返回页首" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_up.gif" width="7" border="0" />
						</a>
						<a class="topOfPage" href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/TenMHToolEDevShouDN.mspx#top">返回页首</a>
				</div>
				<a name="XSLTsection127121120120">
				</a>
				<h2>编写 NUnit 测试</h2>
				<p>作为示例，我将测试 .NET 框架中 Hashtable 类的功能，以确定是否可以添加两个对象并且随后检索这些对象。我的第一步是添加对 NUnit.Framework 程序集的引用，该程序集将赋予我对 NUnit 框架的属性和方法的访问权。接下来，我将创建一个类并用 TestFixture 属性标记它。该属性使 NUnit 可以知道该类包含 NUnit 测试： </p>
				<pre class="codeSample">using System;
using System.Collections;
using NUnit.Framework;

namespace NUnitExample
{
    [TestFixture]
    public class HashtableTest {
        public HashtableTest() {
            
        }
    }
}
</pre>
				<p>下一步，我将创建一个方法并用 [Test] 属性标记它，以便 NUnit 知道该方法是一个测试。然后，我将建立一个 Hashtable 并向其添加两个值，再使用 Assert.AreEqual 方法查看我是否可以检索到与我添加到 Hashtable 的值相同的值，如下面的代码所示： </p>
				<pre class="codeSample">[Test]
public void HashtableAddTest()
{
    Hashtable ht = new Hashtable();
            
    ht.Add("Key1", "Value1");
    ht.Add("Key2", "Value2");

    Assert.AreEqual("Value1", ht["Key1"], "Wrong object returned!");
    Assert.AreEqual("Value2", ht["Key2"], "Wrong object returned!");
}
</pre>
				<p>这将确认我可以首先向 Hashtable 中添加值并随后检索相应的值 — 这是一个很简单的测试，但能够表现 NUnit 的功能。存在许多测试类型以及各种 Assert 方法，可使用它们来测试代码的每个部分。</p>
				<p>要运行该测试，我需要生成项目，在 NUnit 应用程序中打开生成的程序集，然后单击 Run 按钮。图 5 显示了结果。当我看到那个大的绿色条纹时，我有一种兴奋和头晕的感觉，因为它让我知道测试已经通过了。这个简单的示例表明 NUnit 和单元测试是多么方便和强大。由于能够编写可以保存的单元测试，并且每当您更改代码时都可以重新运行该单元测试，您不仅可以更容易地检测到代码中的缺陷，而且最终能够交付更好的应用程序。</p>
				<div style="WIDTH: 400px">
						<img height="233" alt="" src="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/art/TMHTEDSDN05.gif" width="400" border="0" />
						<br />
						<p class="figureCaption">
								<b>图</b>
								<b> 5</b> NUnit</p>
						<div class="figureRule">
						</div>
				</div>
				<p>NUnit 是一个开放源代码项目，并且可以从 <a href="http://www.nunit.org/" target="_blank">http://www.nunit.org</a> 下载。还有一个优秀的 NUnit Visual Studio .NET 外接程序，它使您可以直接从 Visual Studio 中运行单元测试。您可以在 <a href="http://sourceforge.net/projects/nunitaddin" target="_blank">http://sourceforge.net/projects/nunitaddin</a> 找到它。有关 NUnit 及其在测试驱动开发中的地位的详细信息，请参阅文章“<a href="http://msdn.microsoft.com/msdnmag/issues/04/04/ExtremeProgramming/" target="_blank">Test-Driven C#: Improve the Design and Flexibility of Your Project with Extreme Programming Techniques</a>”（<i>MSDN</i> ®<i>Magazine</i> 2004 年 4 月刊）。</p>
				<div style="MARGIN-TOP: 3px; MARGIN-BOTTOM: 10px">
						<a href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/TenMHToolEDevShouDN.mspx#top">
								<img height="9" alt="返回页首" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_up.gif" width="7" border="0" />
						</a>
						<a class="topOfPage" href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/TenMHToolEDevShouDN.mspx#top">返回页首</a>
				</div>
				<a name="XSLTsection128121120120">
				</a>
				<h2>FxCop</h2>
				<p>.NET 框架非常强大，这意味着存在创建优秀应用程序的极大可能，但是也同样存在创建劣质程序的可能。FxCop 是有助于创建更好的应用程序的工具之一，它所采用的方法是：使您能够分析程序集，并使用一些不同的规则来检查它是否符合这些规则。FxCop 随附了由 Microsoft 创建的固定数量的规则，但您也可以创建并包括您自己的规则。例如，如果您决定所有的类都应该具有一个不带任何参数的默认构造函数，则可以编写一条规则，以确保程序集的每个类上都具有一个构造函数。这样，无论是谁编写该代码，您都将获得一定程度的一致性。如果您需要有关创建自定义规则的详细信息，请参阅 John Robbins 的有关该主题的 <a href="http://msdn.microsoft.com/msdnmag/issues/04/06/bugslayer/" target="_blank">Bugslayer</a> 专栏文章（<i>MSDN</i> ®<i> Magazine</i> 2004 年 6 月刊）。</p>
				<p>那么，让我们观察一下实际运行的 FxCop，并且看一下它在我一直在处理的 NUnitExample 程序集中找到哪些错误。当您打开 FxCop 时，您首先需要创建一个 FxCop 项目，然后向其添加您要测试的程序集。在将该程序集添加到项目以后，就可以按 Analyze，FxCop 将分析该程序集。<a href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/art/TMHTEDSDN06.htm" target="_blank">图 6</a> 中显示了在该程序集中找到的错误和警告。</p>
				<p>FxCop 在我的程序集中找到了几个问题。您可以双击某个错误以查看详细信息，包括规则说明以及在哪里可以找到更多信息。（您可以做的一件有趣的事情是在框架程序集上运行 FxCop 并查看发生了什么事情。）</p>
				<p>FxCop 可以帮助您创建更好的、更一致的代码，但它无法补偿低劣的应用程序设计或非常简单拙劣的编程。FxCop 也不能替代对等代码检查，但是因为它可以在进行代码检查之前捕获大量错误，所以您可以花费更多时间来解决严重的问题，而不必担心命名约定。FxCop 由 Microsoft 开发，并且可以从 <a href="http://www.gotdotnet.com/team/fxcop" target="_blank">http://www.gotdotnet.com/team/fxcop</a> 下载。</p>
				<div style="MARGIN-TOP: 3px; MARGIN-BOTTOM: 10px">
						<a href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/TenMHToolEDevShouDN.mspx#top">
								<img height="9" alt="返回页首" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_up.gif" width="7" border="0" />
						</a>
						<a class="topOfPage" href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/TenMHToolEDevShouDN.mspx#top">返回页首</a>
				</div>
				<a name="XSLTsection129121120120">
				</a>
				<h2>Lutz Roeder 的 .NET Reflector</h2>
				<p>下一个必不可少的工具称为 .NET Reflector，它是一个类浏览器和反编译器，可以分析程序集并向您展示它的所有秘密。.NET 框架向全世界引入了可用来分析任何基于 .NET 的代码（无论它是单个类还是完整的程序集）的反射概念。反射还可以用来检索有关特定程序集中包含的各种类、方法和属性的信息。使用 .NET Reflector，您可以浏览程序集的类和方法，可以分析由这些类和方法生成的 Microsoft 中间语言 (MSIL)，并且可以反编译这些类和方法并查看 C# 或 Visual Basic ®.NET 中的等价类和方法。</p>
				<p>为了演示 .NET Reflector 的工作方式，我将加载和分析前面已经显示的 NUnitExample 程序集。图 7 显示了 .NET Reflector 中加载的该程序集。</p>
				<div style="WIDTH: 250px">
						<img height="432" alt="" src="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/art/TMHTEDSDN07.gif" width="250" border="0" />
						<br />
						<p class="figureCaption">
								<b>图</b>
								<b> 7</b> NUnitExample 程序集</p>
						<div class="figureRule">
						</div>
				</div>
				<p>在 .NET Reflector 内部，有各种可用来进一步分析该程序集的工具。要查看构成某个方法的 MSIL，请单击该方法并从菜单中选择 Disassembler。</p>
				<p>除了能够查看 MSIL 以外，您还可以通过选择 Tools 菜单下的 Decompiler 来查看该方法的 C# 形式。通过在 Languages 菜单下更改您的选择，您还可以查看该方法被反编译到 Visual Basic .NET 或 Delphi 以后的形式。以下为 .NET Reflector 生成的代码： </p>
				<pre class="codeSample">public void HashtableAddTest()
{ 
    Hashtable hashtable1;
    hashtable1 = new Hashtable();
    hashtable1.Add("Key1", "Value1");
    hashtable1.Add("Key2", "Value2");
    Assert.AreEqual("Value1", hashtable1["Key1"], 
       "Wrong object returned!");
    Assert.AreEqual("Value2", hashtable1["Key2"],
       "Wrong object returned!");
}
</pre>
				<p>前面的代码看起来非常像我为该方法实际编写的代码。以下为该程序集中的实际代码： </p>
				<pre class="codeSample">public void HashtableAddTest()
{
    Hashtable ht = new Hashtable();
            
    ht.Add("Key1", "Value1");
    ht.Add("Key2", "Value2");

    Assert.AreEqual("Value1", ht["Key1"],
        "Wrong object returned!");
    Assert.AreEqual("Value2", ht["Key2"],
        "Wrong object returned!");
}
</pre>
				<p>尽管上述代码中存在一些小的差异，但它们在功能上是完全相同的。</p>
				<p>虽然该示例是一种显示实际代码与反编译代码之间对比的好方法，但在我看来，它并不代表 .NET Reflector 所具有的最佳用途 — 分析 .NET 框架程序集和方法。.NET 框架提供了许多执行类似操作的不同方法。例如，如果您需要从 XML 中读取一组数据，则存在多种使用 XmlDocument、XPathNavigator 或 XmlReader 完成该工作的不同方法。通过使用 .NET Reflector，您可以查看 Microsoft 在编写数据集的 ReadXml 方法时使用了什么，或者查看他们在从配置文件读取数据时做了哪些工作。.NET Reflector 还是一个了解以下最佳实施策略的优秀方法：创建诸如 HttpHandlers 或配置处理程序之类的对象，因为您可以了解到 Microsoft 工作组实际上是如何在框架中生成这些对象的。</p>
				<p>.NET Reflector 由 Lutz Roeder 编写，并且可以从 <a href="http://www.aisto.com/roeder/dotnet" target="_blank">http://www.aisto.com/roeder/dotnet</a> 下载。</p>
				<div style="MARGIN-TOP: 3px; MARGIN-BOTTOM: 10px">
						<a href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/TenMHToolEDevShouDN.mspx#top">
								<img height="9" alt="返回页首" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_up.gif" width="7" border="0" />
						</a>
						<a class="topOfPage" href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/TenMHToolEDevShouDN.mspx#top">返回页首</a>
				</div>
				<a name="XSLTsection130121120120">
				</a>
				<h2>NDoc</h2>
				<p>编写代码文档资料几乎总是一项令人畏惧的任务。我所说的不是早期设计文档，甚至也不是更为详细的设计文档；我说的是记录类上的各个方法和属性。NDoc 工具能够使用反射来分析程序集，并使用从 C# XML 注释生成的 XML 自动为代码生成文档资料。XML 注释仅适用于 C#，但有一个名为 VBCommenter 的 Visual Studio .NET Power Toy，它能够为 Visual Basic .NET 完成类似的工作。此外，下一版本的 Visual Studio 将为更多语言支持 XML 注释。</p>
				<p>使用 NDoc 时，您仍然在编写代码的技术文档，但您是在编写代码的过程中完成了文档编写工作（在 XML 注释中），而这更容易忍受。使用 NDoc 时，第一步是为您的程序集打开 XML 注释生成功能。右键单击该项目并选择 Properties | Configuration Properties | Build，然后在 XML Documentation File 选项中输入用于保存 XML 文件的路径。当该项目生成时，将创建一个 XML 文件，其中包含所有 XML 注释。下面是 NUnit 示例中的一个用 XML 编写了文档的方法： </p>
				<pre class="codeSample">/// <summary>
/// This test adds a number of values to the Hashtable collection 
/// and then retrieves those values and checks if they match.
/// </summary>
[Test]
public void HashtableAddTest()
{
    //Method Body Here
}
</pre>
				<p>有关该方法的 XML 文档资料将被提取并保存在 XML 文件中，如下所示： </p>
				<pre class="codeSample">
						<member name="M:NUnitExample.HashtableTest.HashtableAddTest">
								<summary>This test adds a number of values to the Hashtable collection
    and then retrieves those values and checks if they match.</summary>
						</member>
				</pre>
				<p>NDoc 使用反射来考察您的程序集，然后读取该文档中的 XML，并且将它们进行匹配。NDoc 使用该数据来创建任意数量的不同文档格式，包括 HTML 帮助文件 (CHM)。在生成 XML 文件以后，下一步是将程序集和 XML 文件加载到 NDoc 中，以便可以对它们进行处理。通过打开 NDoc 并单击 Add 按钮，可以容易地完成该工作。</p>
				<p>在将程序集和 XML 文件加载到 NDoc 中并且使用可用的属性范围自定义输出以后，单击 Generate 按钮将启动生成文档资料的过程。使用默认的属性，NDoc 可以生成一些非常吸引人并且实用的 .html 和 .chm 文件，从而以快速有效的方式自动完成原来非常乏味的任务。</p>
				<p>NDoc 是一个开放源代码项目，并且可以从 <a href="http://ndoc.sourceforge.net/" target="_blank">http://ndoc.sourceforge.net</a> 下载。</p>
				<div style="MARGIN-TOP: 3px; MARGIN-BOTTOM: 10px">
						<a href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/TenMHToolEDevShouDN.mspx#top">
								<img height="9" alt="返回页首" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_up.gif" width="7" border="0" />
						</a>
						<a class="topOfPage" href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/TenMHToolEDevShouDN.mspx#top">返回页首</a>
				</div>
				<a name="XSLTsection131121120120">
				</a>
				<h2>NAnt</h2>
				<p>NAnt 是一个基于 .NET 的生成工具，与当前版本的 Visual Studio .NET 不同，它使得为您的项目创建生成过程变得非常容易。当您拥有大量从事单个项目的开发人员时，您不能依赖于从单个用户的座位进行生成。您也不希望必须定期手动生成该项目。您更愿意创建每天晚上运行的自动生成过程。NAnt 使您可以生成解决方案、复制文件、运行 NUnit 测试、发送电子邮件，等等。遗憾的是，NAnt 缺少漂亮的图形界面，但它的确具有可以指定应该在生成过程中完成哪些任务的控制台应用程序和 XML 文件。注意，MSBuild（属于 Visual Studio 2005 的新的生成平台）为每种健壮的生成方案进行了准备，并且由基于 XML 的项目文件以类似的方式驱动。</p>
				<div style="MARGIN-TOP: 3px; MARGIN-BOTTOM: 10px">
						<a href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/TenMHToolEDevShouDN.mspx#top">
								<img height="9" alt="返回页首" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_up.gif" width="7" border="0" />
						</a>
						<a class="topOfPage" href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/TenMHToolEDevShouDN.mspx#top">返回页首</a>
				</div>
				<a name="XSLTsection132121120120">
				</a>
				<h2>实际运行的 NAnt</h2>
				<p>在该示例中，我将为前面创建的 NUnitExample 解决方案创建一个 NAnt 版本文件。首先，我需要创建一个具有 .build 扩展名的 XML 文件，将其放在我的项目的根目录中，然后向该文件的顶部添加一个 XML 声明。我需要添加到该文件的第一个标记是 project 标记： </p>
				<pre class="codeSample">
						<pre class="codeSample">
								<project name="NUnit Example" basedir="." default="build">
										<description>The NUnit Example Project</description>
								</project>
						</pre>
						<p>项目标记还用于设置项目名称、默认目标以及基目录。Description 标记用于设置该项目的简短说明。</p>
						<p>接下来，我将添加 property 标记，该标记可用于将设置存储到单个位置（随后可以从文件中的任意位置访问该位置）。在该例中，我将创建一个名为 debug 的属性，我可以随后将其设置为 true 或 false，以反映我是否要在调试配置下编译该项目。（最后，这一特定属性并未真正影响如何生成该项目；它只是您设置的一个变量，当您真正确定了如何生成该项目时将读取该变量。）</p>
						<p>接下来，我需要创建一个 target 标记。一个项目可以包含多个可在 NAnt 运行时指定的 target。如果未指定 target，则使用默认 target（我在 project 元素中设置的 target）。在该示例中，默认 target 是 build。让我们观察一下 target 元素，它将包含大多数生成信息： </p>
						<pre class="codeSample">
								<target name="build" description="compiles the source code">
								</target>
						</pre>
						<p>在 target 元素内，我将把 target 的名称设置为 build，并且创建有关该 target 将做哪些工作的说明。我还将创建一个 csc 元素，该元素用于指定应该传递给 csc C# 编译器的数据。让我们看一下该 csc 元素： </p>
						<pre class="codeSample">
								<csc debug="${debug}" output=".\bin\debug\NUnitExample.dll" target="library">
										<references>
												<includes name="C:\program files\NUnit V2.1\bin\NUnit.Framework.dll" />
										</references>
										<sources>
												<includes name="HashtableTest.cs" />
										</sources>
								</csc>
						</pre>
						<p>首先，我必须设置该 csc 元素的 target。在该例中，我将创建一个 .dll 文件，因此我将 target 设置为 library。接下来，我必须设置 csc 元素的 output，它是将要创建 .dll 文件的位置。最后，我需要设置 debug 属性，它确定了是否在调试中编译该项目。因为我在前面创建了一个用于存储该值的属性，所以我可以使用下面的字符串来访问该属性的值：${debug}。Csc 元素还包含一些子元素。我需要创建两个元素：references 元素将告诉 NAnt 需要为该项目引用哪些程序集，sources 元素告诉 NAnt 要在生成过程中包含哪些文件。在该示例中，我引用了 NUnit.Framework.dll 程序集并包含了 HashtableTest.cs 文件。<a href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/art/TMHTEDSDN08.htm" target="_blank">图 8</a> 中显示了完整的生成文件。（您通常还要创建一个干净的 target，用于删除生成的文件，但为了简洁起见，我已经将其省略。）</p>
						<p>要生成该文件，我需要转到我的项目的根目录（生成文件位于此处），然后从该位置执行 nant.exe。如果生成成功，您可以在该应用程序的 bin 目录中找到 .dll 和 .pdb 文件。尽管使用 NAnt 肯定不像在 Visual Studio 中单击 Build 那样简单，但它仍然是一种非常强大的工具，可用于开发按自动计划运行的生成过程。NAnt 还包括一些有用的功能，例如能够运行单元测试或者复制附加文件（这些功能没有受到当前 Visual Studio 生成过程的支持）。</p>
						<p>NAnt 是一个开放源代码项目，并且可以从 <a href="http://nant.sourceforge.net/" target="_blank">http://nant.sourceforge.net</a> 下载。</p>
						<div style="MARGIN-TOP: 3px; MARGIN-BOTTOM: 10px">
								<a href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/TenMHToolEDevShouDN.mspx#top">
										<img height="9" alt="返回页首" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_up.gif" width="7" border="0" />
								</a>
								<a class="topOfPage" href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/TenMHToolEDevShouDN.mspx#top">返回页首</a>
						</div>
						<a name="XSLTsection133121120120">
						</a>
						<h2>转换工具</h2>
						<p>我已经将两个独立的工具合在一起放在标题“转换工具”下面。这两个工具都非常简单，但又可能极为有用。第一个工具是 ASP.NET 版本转换器，它可用于转换 ASP.NET（虚拟目录在它下面运行）的版本。第二个工具是 Visual Studio Converter，它可用于将项目文件从 Visual Studio .NET 2002 转换到 Visual Studio .NET 2003。</p>
						<p>当 IIS 处理请求时，它会查看正在请求的文件的扩展名，然后基于该 Web 站点或虚拟目录的扩展名映射，将请求委派给 ISAPI 扩展或者自己处理该请求。这正是 ASP.NET 的工作方式；将为所有 ASP.NET 扩展名注册扩展名映射，并将这些扩展名映射导向 aspnet_isapi.dll。这种工作方式是完美无缺的，除非您安装了 ASP.NET 1.1 — 它会将扩展名映射升级到新版本的 aspnet_isapi.dll。当在 ASP.NET 1.0 上生成的应用程序试图用 1.1 版运行时，这会导致错误。要解决该问题，可以将所有扩展名映射重新转换到 1.0 版的 aspnet_isapi.dll，但是由于有 18 种扩展名映射，所以手动完成这一工作将很枯燥。这正是 ASP.NET 版本转换器可以发挥作用的时候。使用这一小型实用工具，可以转换任何单个 ASP.NET 应用程序所使用的 .NET 框架的版本。</p>
						<div style="WIDTH: 280px">
								<img height="232" alt="" src="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/art/TMHTEDSDN09.gif" width="280" border="0" />
								<br />
								<p class="figureCaption">
										<b>图</b>
										<b> 9</b> ASP.NET 版本转换器</p>
								<div class="figureRule">
								</div>
						</div>
						<p>图 9 显示了实际运行的 ASP.NET 版本转换器。它的使用方法非常简单，只须选择相应的应用程序，然后选择您希望该应用程序使用的 .NET 框架版本。该工具随后将使用 aspnet_regiis.exe 命令行工具将该应用程序转换到所选版本的框架。随着将来版本的 ASP.NET 和 .NET 框架的发布，该工具将变得更为有用。</p>
						<p>ASP.NET 版本转换器由 Denis Bauer 编写，并且可以从 <a href="http://www.denisbauer.com/NETTools/ASPNETVersionSwitcher.aspx" target="_blank">http://www.denisbauer.com/NETTools/ASPNETVersionSwitcher.aspx</a> 下载。</p>
						<p>Visual Studio .NET 项目转换器（参见图 10）非常类似于 ASP.NET 版本转换器，区别在于它用于转换 Visual Studio 项目文件的版本。尽管在 .NET 框架的 1.0 版和 1.1 版之间只有很小的差异，但一旦将项目文件从 Visual Studio .NET 2002 转换到 Visual Studio .NET 2003，将无法再把它转换回去。虽然这在大多数时候可能不会成为问题（因为在 .NET 框架 1.0 版和 1.1 版之间几乎没有什么破坏性的更改），但在某些时刻您可能需要将项目转换回去。该转换器可以将任何解决方案或项目文件从 Visual Studio 7.1 (Visual Studio .NET 2003) 转换到 Visual Studio 7.0 (Visual Studio .NET 2002)，并在必要时进行反向转换。</p>
						<div style="WIDTH: 340px">
								<img height="251" alt="" src="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/art/TMHTEDSDN10.gif" width="340" border="0" />
								<br />
								<p class="figureCaption">
										<b>图</b>
										<b> 10</b> Visual Studio .NET 项目转换器</p>
								<div class="figureRule">
								</div>
						</div>
						<p>Visual Studio .NET 项目转换器由 Dacris Software 编写。该工具可以从 <a href="http://www.codeproject.com/macro/vsconvert.asp" target="_blank">http://www.codeproject.com/macro/vsconvert.asp</a> 下载。</p>
						<div style="MARGIN-TOP: 3px; MARGIN-BOTTOM: 10px">
								<a href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/TenMHToolEDevShouDN.mspx#top">
										<img height="9" alt="返回页首" src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_up.gif" width="7" border="0" />
								</a>
								<a class="topOfPage" href="http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/TenMHToolEDevShouDN.mspx#top">返回页首</a>
						</div>
						<a name="XSLTsection134121120120">
						</a>
						<h2>小结</h2>
						<p>本文采用走马观花的方式介绍了上述工具，但我已经试图起码向您提供足够的信息以激起您的好奇心。我相信本文已经让您在某种程度上领悟了几个免费工具，您可以立即开始使用这些工具来编写更好的项目。同时，我还要敦促您确保自己拥有所有其他可以获得的合适工具，无论是最新版本的 Visual Studio、功能强大的计算机还是免费的实用工具。拥有合适的工具将使一切变得大不相同。</p>
				</pre>
		</div>
<img src ="http://www.cppblog.com/phenix_jiang/aggbug/4408.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/phenix_jiang/" target="_blank">拼命流血</a> 2006-03-21 12:49 <a href="http://www.cppblog.com/phenix_jiang/articles/4408.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++获取系统当前的登录帐号</title><link>http://www.cppblog.com/phenix_jiang/articles/3415.html</link><dc:creator>拼命流血</dc:creator><author>拼命流血</author><pubDate>Wed, 22 Feb 2006 08:31:00 GMT</pubDate><guid>http://www.cppblog.com/phenix_jiang/articles/3415.html</guid><wfw:comment>http://www.cppblog.com/phenix_jiang/comments/3415.html</wfw:comment><comments>http://www.cppblog.com/phenix_jiang/articles/3415.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/phenix_jiang/comments/commentRss/3415.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/phenix_jiang/services/trackbacks/3415.html</trackback:ping><description><![CDATA[<P>#include &lt;windows.h&gt;</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"><FONT face=Verdana><SPAN style="COLOR: #000000">unsigned&nbsp;</SPAN><SPAN style="COLOR: #0000ff">long</SPAN><SPAN style="COLOR: #000000">&nbsp;Get_System_LoginName(</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">*</SPAN></FONT><FONT face=Verdana><SPAN style="COLOR: #000000">&nbsp;strUserName){<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">&nbsp;szUserName[</SPAN><SPAN style="COLOR: #000000">50</SPAN></FONT><FONT face=Verdana><SPAN style="COLOR: #000000">];<BR>&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;nUserName</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #0000ff">sizeof</SPAN></FONT><FONT face=Verdana><SPAN style="COLOR: #000000">(szUserName);<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">(GetUserName(szUserName,</SPAN><SPAN style="COLOR: #000000">&amp;</SPAN><SPAN style="COLOR: #000000">nUserName)</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">0</SPAN></FONT><FONT face=Verdana><SPAN style="COLOR: #000000">){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">false</SPAN></FONT><FONT face=Verdana><SPAN style="COLOR: #000000">;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN><SPAN style="COLOR: #0000ff">else</SPAN></FONT><FONT face=Verdana><SPAN style="COLOR: #000000">{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strcpy(strUserName,szUserName);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">true</SPAN></FONT><SPAN style="COLOR: #000000"><FONT face=Verdana>;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>}</FONT></SPAN></DIV><img src ="http://www.cppblog.com/phenix_jiang/aggbug/3415.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/phenix_jiang/" target="_blank">拼命流血</a> 2006-02-22 16:31 <a href="http://www.cppblog.com/phenix_jiang/articles/3415.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C/C++动态改写ini文件配置的函数</title><link>http://www.cppblog.com/phenix_jiang/articles/3414.html</link><dc:creator>拼命流血</dc:creator><author>拼命流血</author><pubDate>Wed, 22 Feb 2006 08:28:00 GMT</pubDate><guid>http://www.cppblog.com/phenix_jiang/articles/3414.html</guid><wfw:comment>http://www.cppblog.com/phenix_jiang/comments/3414.html</wfw:comment><comments>http://www.cppblog.com/phenix_jiang/articles/3414.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/phenix_jiang/comments/commentRss/3414.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/phenix_jiang/services/trackbacks/3414.html</trackback:ping><description><![CDATA[<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">unsigned&nbsp;</SPAN><SPAN style="COLOR: #0000ff">long</SPAN><SPAN style="COLOR: #000000">&nbsp;Write_Ini_Value(</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">&nbsp;strFileName,</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">&nbsp;strKey,</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">&nbsp;strValue){<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">using</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">namespace</SPAN><SPAN style="COLOR: #000000">&nbsp;std;<BR>&nbsp;&nbsp;&nbsp;&nbsp;std::list</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">std::</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">&nbsp;text;<BR>&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;</SPAN><SPAN style="COLOR: #0000ff">long</SPAN><SPAN style="COLOR: #000000">&nbsp;ret_code</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">const</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;READ_BUFFER_SIZE</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">1024</SPAN><SPAN style="COLOR: #000000">;<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">&nbsp;readBuffer[READ_BUFFER_SIZE]</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">{</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">};<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">bool</SPAN><SPAN style="COLOR: #000000">&nbsp;bFindKey</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #0000ff">false</SPAN><SPAN style="COLOR: #000000">;<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">&nbsp;line;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">Find&nbsp;ini&nbsp;key&nbsp;and&nbsp;value</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;fstream&nbsp;rcFile(strFileName.c_str(),&nbsp;ios::</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000">);<BR>&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">rcFile){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret_code</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #0000ff">false</SPAN><SPAN style="COLOR: #000000">;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">goto</SPAN><SPAN style="COLOR: #000000">&nbsp;EXIT_FUNCTION;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">while</SPAN><SPAN style="COLOR: #000000">(rcFile.getline(readBuffer,READ_BUFFER_SIZE,</SPAN><SPAN style="COLOR: #000000">'</SPAN><SPAN style="COLOR: #000000">\n</SPAN><SPAN style="COLOR: #000000">'</SPAN><SPAN style="COLOR: #000000">)){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;line</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">readBuffer;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">(line.empty())&nbsp;</SPAN><SPAN style="COLOR: #0000ff">continue</SPAN><SPAN style="COLOR: #000000">;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">(line.length()</SPAN><SPAN style="COLOR: #000000">&lt;=</SPAN><SPAN style="COLOR: #000000">strKey.length()){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;text.push_back(line);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">continue</SPAN><SPAN style="COLOR: #000000">;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">(line.substr(</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">,strKey.length())</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">strKey){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;text.push_back(strKey</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">strValue);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bFindKey</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #0000ff">true</SPAN><SPAN style="COLOR: #000000">;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN><SPAN style="COLOR: #0000ff">else</SPAN><SPAN style="COLOR: #000000">{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;text.push_back(line);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">continue</SPAN><SPAN style="COLOR: #000000">;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;rcFile.close();<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">(bFindKey){<BR>&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ofstream&nbsp;iniFile(strFileName.c_str());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&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">iniFile){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret_code</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #0000ff">false</SPAN><SPAN style="COLOR: #000000">;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN><SPAN style="COLOR: #0000ff">else</SPAN><SPAN style="COLOR: #000000">{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">for</SPAN><SPAN style="COLOR: #000000">(list</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::iterator&nbsp;iter</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">text.begin();iter</SPAN><SPAN style="COLOR: #000000">!=</SPAN><SPAN style="COLOR: #000000">text.end();</SPAN><SPAN style="COLOR: #000000">++</SPAN><SPAN style="COLOR: #000000">iter){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iniFile&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;(</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">iter).c_str()&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;endl;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret_code</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #0000ff">true</SPAN><SPAN style="COLOR: #000000">;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iniFile.close();<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR><BR><BR><BR>EXIT_FUNCTION:<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;ret_code;<BR><BR>}</SPAN></DIV><img src ="http://www.cppblog.com/phenix_jiang/aggbug/3414.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/phenix_jiang/" target="_blank">拼命流血</a> 2006-02-22 16:28 <a href="http://www.cppblog.com/phenix_jiang/articles/3414.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>几个C下面的日期大小比较函数</title><link>http://www.cppblog.com/phenix_jiang/articles/3413.html</link><dc:creator>拼命流血</dc:creator><author>拼命流血</author><pubDate>Wed, 22 Feb 2006 08:24:00 GMT</pubDate><guid>http://www.cppblog.com/phenix_jiang/articles/3413.html</guid><wfw:comment>http://www.cppblog.com/phenix_jiang/comments/3413.html</wfw:comment><comments>http://www.cppblog.com/phenix_jiang/articles/3413.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/phenix_jiang/comments/commentRss/3413.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/phenix_jiang/services/trackbacks/3413.html</trackback:ping><description><![CDATA[<P>比较日期:<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 id=Codehighlighter1_62_603_Open_Image onclick="this.style.display='none'; Codehighlighter1_62_603_Open_Text.style.display='none'; Codehighlighter1_62_603_Closed_Image.style.display='inline'; Codehighlighter1_62_603_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_62_603_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_62_603_Closed_Text.style.display='none'; Codehighlighter1_62_603_Open_Image.style.display='inline'; Codehighlighter1_62_603_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align=top><SPAN style="COLOR: #000000">unsigned&nbsp;</SPAN><SPAN style="COLOR: #0000ff">long</SPAN><SPAN style="COLOR: #000000">&nbsp;Compare_To_Date(</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">&nbsp;datetime1,</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">&nbsp;datetime2)</SPAN><SPAN id=Codehighlighter1_62_603_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_62_603_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;</SPAN><SPAN style="COLOR: #0000ff">short</SPAN><SPAN style="COLOR: #000000">&nbsp;year1;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;</SPAN><SPAN style="COLOR: #0000ff">short</SPAN><SPAN style="COLOR: #000000">&nbsp;month1;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;</SPAN><SPAN style="COLOR: #0000ff">short</SPAN><SPAN style="COLOR: #000000">&nbsp;day1;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;</SPAN><SPAN style="COLOR: #0000ff">short</SPAN><SPAN style="COLOR: #000000">&nbsp;year2;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;</SPAN><SPAN style="COLOR: #0000ff">short</SPAN><SPAN style="COLOR: #000000">&nbsp;month2;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;</SPAN><SPAN style="COLOR: #0000ff">short</SPAN><SPAN style="COLOR: #000000">&nbsp;day2;<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;unsigned&nbsp;</SPAN><SPAN style="COLOR: #0000ff">long</SPAN><SPAN style="COLOR: #000000">&nbsp;bValidate;<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;bValidate</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">Validate_Date(datetime1,</SPAN><SPAN style="COLOR: #000000">&amp;</SPAN><SPAN style="COLOR: #000000">year1,</SPAN><SPAN style="COLOR: #000000">&amp;</SPAN><SPAN style="COLOR: #000000">month1,</SPAN><SPAN style="COLOR: #000000">&amp;</SPAN><SPAN style="COLOR: #000000">day1);<BR><IMG id=Codehighlighter1_311_326_Open_Image onclick="this.style.display='none'; Codehighlighter1_311_326_Open_Text.style.display='none'; Codehighlighter1_311_326_Closed_Image.style.display='inline'; Codehighlighter1_311_326_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_311_326_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_311_326_Closed_Text.style.display='none'; Codehighlighter1_311_326_Open_Image.style.display='inline'; Codehighlighter1_311_326_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">(bValidate</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #0000ff">false</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN id=Codehighlighter1_311_326_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_311_326_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: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">3</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;bValidate</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">Validate_Date(datetime2,</SPAN><SPAN style="COLOR: #000000">&amp;</SPAN><SPAN style="COLOR: #000000">year2,</SPAN><SPAN style="COLOR: #000000">&amp;</SPAN><SPAN style="COLOR: #000000">month2,</SPAN><SPAN style="COLOR: #000000">&amp;</SPAN><SPAN style="COLOR: #000000">day2);<BR><IMG id=Codehighlighter1_408_423_Open_Image onclick="this.style.display='none'; Codehighlighter1_408_423_Open_Text.style.display='none'; Codehighlighter1_408_423_Closed_Image.style.display='inline'; Codehighlighter1_408_423_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_408_423_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_408_423_Closed_Text.style.display='none'; Codehighlighter1_408_423_Open_Image.style.display='inline'; Codehighlighter1_408_423_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">(bValidate</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #0000ff">false</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN id=Codehighlighter1_408_423_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_408_423_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: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">3</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">(year1</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">year2)&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">(year1</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">year2)&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">2</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">(month1</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">month2)&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">(month1</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">month2)&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">2</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">(day1</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">day2)&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">(day1</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">day2)&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">2</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">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</SPAN></SPAN></DIV>
<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"><SPAN style="COLOR: #000000">unsigned&nbsp;</SPAN><SPAN style="COLOR: #0000ff">long</SPAN><SPAN style="COLOR: #000000">&nbsp;Compare_To_Current_Date(</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">&nbsp;datetime){<BR>&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;</SPAN><SPAN style="COLOR: #0000ff">short</SPAN><SPAN style="COLOR: #000000">&nbsp;year;<BR>&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;</SPAN><SPAN style="COLOR: #0000ff">short</SPAN><SPAN style="COLOR: #000000">&nbsp;month;<BR>&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;</SPAN><SPAN style="COLOR: #0000ff">short</SPAN><SPAN style="COLOR: #000000">&nbsp;day;<BR>&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;</SPAN><SPAN style="COLOR: #0000ff">long</SPAN><SPAN style="COLOR: #000000">&nbsp;bValidate</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">Validate_Date(datetime,</SPAN><SPAN style="COLOR: #000000">&amp;</SPAN><SPAN style="COLOR: #000000">year,</SPAN><SPAN style="COLOR: #000000">&amp;</SPAN><SPAN style="COLOR: #000000">month,</SPAN><SPAN style="COLOR: #000000">&amp;</SPAN><SPAN style="COLOR: #000000">day);<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">(bValidate</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #0000ff">false</SPAN><SPAN style="COLOR: #000000">){<BR>&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">3</SPAN><SPAN style="COLOR: #000000">;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;SYSTEMTIME&nbsp;CurTime;<BR>&nbsp;&nbsp;&nbsp;&nbsp;GetLocalTime(</SPAN><SPAN style="COLOR: #000000">&amp;</SPAN><SPAN style="COLOR: #000000">CurTime);<BR>&nbsp;&nbsp;&nbsp;&nbsp;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">(CurTime.wYear</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">year)<BR>&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">2</SPAN><SPAN style="COLOR: #000000">;<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">else</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">(CurTime.wYear</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">year)<BR>&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">0</SPAN><SPAN style="COLOR: #000000">;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">(CurTime.wMonth</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">month)<BR>&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">2</SPAN><SPAN style="COLOR: #000000">;<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">else</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">(CurTime.wMonth</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">month)<BR>&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">0</SPAN><SPAN style="COLOR: #000000">;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">(CurTime.wDay</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">day)<BR>&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">2</SPAN><SPAN style="COLOR: #000000">;<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">else</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">(CurTime.wDay</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">day)<BR>&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">0</SPAN><SPAN style="COLOR: #000000">;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">;<BR><BR>}</SPAN></DIV>
<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 id=Codehighlighter1_105_709_Open_Image onclick="this.style.display='none'; Codehighlighter1_105_709_Open_Text.style.display='none'; Codehighlighter1_105_709_Closed_Image.style.display='inline'; Codehighlighter1_105_709_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_105_709_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_105_709_Closed_Text.style.display='none'; Codehighlighter1_105_709_Open_Image.style.display='inline'; Codehighlighter1_105_709_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align=top><SPAN style="COLOR: #000000">unsigned&nbsp;</SPAN><SPAN style="COLOR: #0000ff">long</SPAN><SPAN style="COLOR: #000000">&nbsp;Validate_Date(</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">&nbsp;date,unsigned&nbsp;</SPAN><SPAN style="COLOR: #0000ff">short</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">&nbsp;year,unsigned&nbsp;</SPAN><SPAN style="COLOR: #0000ff">short</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">&nbsp;month,unsigned&nbsp;</SPAN><SPAN style="COLOR: #0000ff">short</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">&nbsp;day)</SPAN><SPAN id=Codehighlighter1_105_709_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_105_709_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: #0000ff">if</SPAN><SPAN style="COLOR: #000000">(strlen(date)</SPAN><SPAN style="COLOR: #000000">!=</SPAN><SPAN style="COLOR: #000000">10</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">false</SPAN><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">&nbsp;s(date);<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">(s.substr(</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">,</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">!=</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">/</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">false</SPAN><SPAN style="COLOR: #000000">;<BR><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">(s.substr(</SPAN><SPAN style="COLOR: #000000">5</SPAN><SPAN style="COLOR: #000000">,</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">!=</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">/</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">false</SPAN><SPAN style="COLOR: #000000">;<BR><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">string</SPAN><SPAN style="COLOR: #000000">&nbsp;szyear</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">s.substr(</SPAN><SPAN style="COLOR: #000000">6</SPAN><SPAN style="COLOR: #000000">,</SPAN><SPAN style="COLOR: #000000">4</SPAN><SPAN style="COLOR: #000000">);</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">dd/mm/yyyy</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">string</SPAN><SPAN style="COLOR: #000000">&nbsp;szmonth</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">s.substr(</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">,</SPAN><SPAN style="COLOR: #000000">2</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">string</SPAN><SPAN style="COLOR: #000000">&nbsp;szday</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">s.substr(</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">,</SPAN><SPAN style="COLOR: #000000">2</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">(IsNumber(szyear)</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #0000ff">false</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">false</SPAN><SPAN style="COLOR: #000000">;<BR><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">(IsNumber(szmonth)</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #0000ff">false</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">false</SPAN><SPAN style="COLOR: #000000">;<BR><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">(IsNumber(szday)</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #0000ff">false</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">false</SPAN><SPAN style="COLOR: #000000">;<BR><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;unsigned&nbsp;</SPAN><SPAN style="COLOR: #0000ff">long</SPAN><SPAN style="COLOR: #000000">&nbsp;bResult;<BR><IMG id=Codehighlighter1_499_658_Open_Image onclick="this.style.display='none'; Codehighlighter1_499_658_Open_Text.style.display='none'; Codehighlighter1_499_658_Closed_Image.style.display='inline'; Codehighlighter1_499_658_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_499_658_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_499_658_Closed_Text.style.display='none'; Codehighlighter1_499_658_Open_Image.style.display='inline'; Codehighlighter1_499_658_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">try</SPAN><SPAN id=Codehighlighter1_499_658_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_499_658_Open_Text><SPAN style="COLOR: #000000">{&nbsp;&nbsp;&nbsp;&nbsp;<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: #000000">*</SPAN><SPAN style="COLOR: #000000">year</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">(unsigned&nbsp;</SPAN><SPAN style="COLOR: #0000ff">short</SPAN><SPAN style="COLOR: #000000">)atol(szyear.c_str());<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: #000000">*</SPAN><SPAN style="COLOR: #000000">month</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">(unsigned&nbsp;</SPAN><SPAN style="COLOR: #0000ff">short</SPAN><SPAN style="COLOR: #000000">)atol(szmonth.c_str());<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: #000000">*</SPAN><SPAN style="COLOR: #000000">day</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">(unsigned&nbsp;</SPAN><SPAN style="COLOR: #0000ff">short</SPAN><SPAN style="COLOR: #000000">)atol(szday.c_str());<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bResult</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">true</SPAN><SPAN style="COLOR: #000000">;<BR><IMG id=Codehighlighter1_669_689_Open_Image onclick="this.style.display='none'; Codehighlighter1_669_689_Open_Text.style.display='none'; Codehighlighter1_669_689_Closed_Image.style.display='inline'; Codehighlighter1_669_689_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_669_689_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_669_689_Closed_Text.style.display='none'; Codehighlighter1_669_689_Open_Image.style.display='inline'; Codehighlighter1_669_689_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #0000ff">catch</SPAN><SPAN style="COLOR: #000000">(<IMG src="http://www.cppblog.com/images/dot.gif">)</SPAN><SPAN id=Codehighlighter1_669_689_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_669_689_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;bResult</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #0000ff">false</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>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;bResult;&nbsp;&nbsp;&nbsp;&nbsp;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</SPAN></SPAN></DIV><img src ="http://www.cppblog.com/phenix_jiang/aggbug/3413.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/phenix_jiang/" target="_blank">拼命流血</a> 2006-02-22 16:24 <a href="http://www.cppblog.com/phenix_jiang/articles/3413.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SDL(Simple DirectMedia Layer)</title><link>http://www.cppblog.com/phenix_jiang/articles/3379.html</link><dc:creator>拼命流血</dc:creator><author>拼命流血</author><pubDate>Tue, 21 Feb 2006 07:44:00 GMT</pubDate><guid>http://www.cppblog.com/phenix_jiang/articles/3379.html</guid><wfw:comment>http://www.cppblog.com/phenix_jiang/comments/3379.html</wfw:comment><comments>http://www.cppblog.com/phenix_jiang/articles/3379.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/phenix_jiang/comments/commentRss/3379.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/phenix_jiang/services/trackbacks/3379.html</trackback:ping><description><![CDATA[<strong>SDL(</strong><font face="Verdana"><strong>Simple DirectMedia Layer)是</strong>一个跨平台的multimedia library ,包含了对video,audio,keyboard,mouse的支持。<br>它的接口比较简洁，你甚至不需要知道Win32 API,就可以写出游戏来。它封装了跟<br>平台相关的部分。它使我想起了TC下面的graphics BGI<br><br>官方地址:&nbsp;&nbsp;&nbsp;<a href="http://www.libsdl.org/">http://www.libsdl.org/</a><br><br>下面是我用SDL写的一个小游戏<br><img alt="run.jpg" src="../../images/cppblog_com/sandy/run.jpg" border="0" height="505" width="406"><br><br><br><strong>1.骨架程序</strong><br><br>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238);"><span style="color: rgb(0, 0, 0);">#include&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">sdl.h</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"><br>#pragma&nbsp;comment(lib,</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">sdl.lib</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">)<br>#pragma&nbsp;comment(lib,</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">sdlmain.lib</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">)<br><br></span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">&nbsp;main(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">&nbsp;argc,</span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">**</span><span style="color: rgb(0, 0, 0);">&nbsp;argv)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">Init&nbsp;SDL</span><span style="color: rgb(0, 128, 0);"><br></span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;SDL_Init(&nbsp;SDL_INIT_VIDEO&nbsp;);<br>&nbsp;&nbsp;&nbsp;&nbsp;atexit(SDL_Quit);<br>&nbsp;&nbsp;&nbsp;&nbsp;screen&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;SDL_SetVideoMode(</span><span style="color: rgb(0, 0, 0);">400</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);">480</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">,SDL_SWSURFACE);<br>&nbsp;&nbsp;&nbsp;&nbsp;SDL_WM_SetCaption(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">RUN</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,NULL);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">load&nbsp;resource<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"><img src="../../Images/dot.gif"></span><span style="color: rgb(0, 128, 0);"><br></span><span style="color: rgb(0, 0, 0);"><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">bool</span><span style="color: rgb(0, 0, 0);">&nbsp;pause&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">false</span><span style="color: rgb(0, 0, 0);">;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">bool</span><span style="color: rgb(0, 0, 0);">&nbsp;gone&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">true</span><span style="color: rgb(0, 0, 0);">;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;SDL_Event&nbsp;</span><span style="color: rgb(0, 0, 255);">event</span><span style="color: rgb(0, 0, 0);">;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">while</span><span style="color: rgb(0, 0, 0);">(gone)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">(SDL_PollEvent(</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 255);">event</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 255);">event</span><span style="color: rgb(0, 0, 0);">.type&nbsp;</span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);">&nbsp;SDL_QUIT)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">break</span><span style="color: rgb(0, 0, 0);">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">else</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 255);">event</span><span style="color: rgb(0, 0, 0);">.type&nbsp;</span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);">&nbsp;SDL_KEYDOWN)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">handle&nbsp;event<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"><img src="../../Images/dot.gif"></span><span style="color: rgb(0, 128, 0);"><br></span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">else</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 255);">event</span><span style="color: rgb(0, 0, 0);">.type&nbsp;</span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);">&nbsp;SDL_KEYUP)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">handle&nbsp;event<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"><img src="../../Images/dot.gif"></span><span style="color: rgb(0, 128, 0);"><br></span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">else</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">!</span><span style="color: rgb(0, 0, 0);">pause)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;run();&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">release&nbsp;resource<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"><img src="../../Images/dot.gif"></span><span style="color: rgb(0, 128, 0);"><br></span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">;<br>}<br><br></span></div></font><br>
SDL_Init : 初始化子系统<br>
SDL_SetVideoMode：设置分辨率<br>
SDL_WM_SetCaption: 设置窗口标题<br>
SDL_PollEvent：查询事件，用户的输入<br>
<br>
<strong>2.表面的概念</strong><br>
<br>
表面(SDL_Surface)是SDL中一个重要的概念，精灵都是保存在表面中<br>
<br>

<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238);"><span style="color: rgb(0, 0, 0);">SDL_Surface&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">&nbsp;temp&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;SDL_CreateRGBSurface(SDL_SRCCOLORKEY,&nbsp;w,&nbsp;h,&nbsp;</span><span style="color: rgb(0, 0, 0);">32</span><span style="color: rgb(0, 0, 0);">,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">,&nbsp;</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">,&nbsp;</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">,&nbsp;</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>rc.x&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;x&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">&nbsp;w&nbsp;;<br>rc.y&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;y&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">&nbsp;h;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>SDL_BlitSurface(surf,</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">rc,temp,</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>SDL_SetColorKey(temp,SDL_SRCCOLORKEY,transcolor);</span></div>
<br>
SDL_CreateRGBSurface 创建一个表面<br>
SDL_BlitSurface 表面之间的copy<br>
SDL_SetColorKey 设定表面的透明色<br>
<br>
ps:主表面是由SDL_SetVideoMode返回的，也可以通过<a href="file:///D:/SDL-1.2.8/docs/html/sdlgetvideosurface.html">SDL_GetVideoSurface</a>查询到<br>
<br>
<strong>3. 声音的使用</strong><br>
<br>
游戏离不开声音,SDL也提供了支持<br>
<br>

<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238);"><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">&nbsp;play_sound(</span><span style="color: rgb(0, 0, 255);">const</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">file)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">&nbsp;index;<br>&nbsp;&nbsp;&nbsp;&nbsp;SDL_AudioSpec&nbsp;wave;<br>&nbsp;&nbsp;&nbsp;&nbsp;Uint8&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">data;<br>&nbsp;&nbsp;&nbsp;&nbsp;Uint32&nbsp;dlen;<br>&nbsp;&nbsp;&nbsp;&nbsp;SDL_AudioCVT&nbsp;cvt;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 128, 0);">/*</span><span style="color: rgb(0, 128, 0);">&nbsp;寻找一个空的（或者完成了的）音频口&nbsp;</span><span style="color: rgb(0, 128, 0);">*/</span><span style="color: rgb(0, 0, 0);"><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">for</span><span style="color: rgb(0, 0, 0);">&nbsp;(&nbsp;index</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">;&nbsp;index</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">NUM_SOUNDS;&nbsp;</span><span style="color: rgb(0, 0, 0);">++</span><span style="color: rgb(0, 0, 0);">index&nbsp;)&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">&nbsp;(&nbsp;sounds[index].dpos&nbsp;</span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);">&nbsp;sounds[index].dlen&nbsp;)&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">break</span><span style="color: rgb(0, 0, 0);">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">&nbsp;(&nbsp;index&nbsp;</span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);">&nbsp;NUM_SOUNDS&nbsp;)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 128, 0);">/*</span><span style="color: rgb(0, 128, 0);">&nbsp;加载声音文件，并转换成16位、立体声、22kHz格式&nbsp;</span><span style="color: rgb(0, 128, 0);">*/</span><span style="color: rgb(0, 0, 0);"><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">&nbsp;(&nbsp;SDL_LoadWAV(file,&nbsp;</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">wave,&nbsp;</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">data,&nbsp;</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">dlen)&nbsp;</span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);">&nbsp;NULL&nbsp;)&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fprintf(stderr,&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">无法加载&nbsp;%s:&nbsp;%s\n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,&nbsp;file,&nbsp;SDL_GetError());<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;SDL_BuildAudioCVT(</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">cvt,&nbsp;wave.format,&nbsp;wave.channels,&nbsp;wave.freq,<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;AUDIO_S16,&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 0);">22050</span><span style="color: rgb(0, 0, 0);">);<br>&nbsp;&nbsp;&nbsp;&nbsp;cvt.buf&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;(unsigned&nbsp;</span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">)malloc(dlen</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">cvt.len_mult);<br>&nbsp;&nbsp;&nbsp;&nbsp;memcpy(cvt.buf,&nbsp;data,&nbsp;dlen);<br>&nbsp;&nbsp;&nbsp;&nbsp;cvt.len&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;dlen;<br>&nbsp;&nbsp;&nbsp;&nbsp;SDL_ConvertAudio(</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">cvt);<br>&nbsp;&nbsp;&nbsp;&nbsp;SDL_FreeWAV(data);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 128, 0);">/*</span><span style="color: rgb(0, 128, 0);">&nbsp;将音频数据放入音频口（立刻开始回放了）&nbsp;</span><span style="color: rgb(0, 128, 0);">*/</span><span style="color: rgb(0, 0, 0);"><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">&nbsp;(&nbsp;sounds[index].data&nbsp;)&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;free(sounds[index].data);<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;SDL_LockAudio();<br>&nbsp;&nbsp;&nbsp;&nbsp;sounds[index].data&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;cvt.buf;<br>&nbsp;&nbsp;&nbsp;&nbsp;sounds[index].dlen&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;cvt.len_cvt;<br>&nbsp;&nbsp;&nbsp;&nbsp;sounds[index].dpos&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">;<br>&nbsp;&nbsp;&nbsp;&nbsp;SDL_UnlockAudio();<br>}</span></div>
<br>
<strong>4.一些有用的模块</strong><br>
<br>

<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238);"><span style="color: rgb(0, 0, 0);">#include&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">sdl_image.h</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"><br><br></span><span style="color: rgb(0, 128, 0);">/*</span><span style="color: rgb(0, 128, 0);"><br>&nbsp;*&nbsp;Return&nbsp;the&nbsp;pixel&nbsp;value&nbsp;at&nbsp;(x,&nbsp;y)<br>&nbsp;*&nbsp;NOTE:&nbsp;The&nbsp;surface&nbsp;must&nbsp;be&nbsp;locked&nbsp;before&nbsp;calling&nbsp;this!<br>&nbsp;</span><span style="color: rgb(0, 128, 0);">*/</span><span style="color: rgb(0, 0, 0);"><br>Uint32&nbsp;getpixel(SDL_Surface&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">surface,&nbsp;</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">&nbsp;x,&nbsp;</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">&nbsp;y)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">&nbsp;bpp&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;surface</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">format</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">BytesPerPixel;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 128, 0);">/*</span><span style="color: rgb(0, 128, 0);">&nbsp;Here&nbsp;p&nbsp;is&nbsp;the&nbsp;address&nbsp;to&nbsp;the&nbsp;pixel&nbsp;we&nbsp;want&nbsp;to&nbsp;retrieve&nbsp;</span><span style="color: rgb(0, 128, 0);">*/</span><span style="color: rgb(0, 0, 0);"><br>&nbsp;&nbsp;&nbsp;&nbsp;Uint8&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">p&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;(Uint8&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">)surface</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">pixels&nbsp;</span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);">&nbsp;y&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">&nbsp;surface</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">pitch&nbsp;</span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);">&nbsp;x&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">&nbsp;bpp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">switch</span><span style="color: rgb(0, 0, 0);">(bpp)&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">case</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">p;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">case</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">(Uint16&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">)p;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">case</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">3</span><span style="color: rgb(0, 0, 0);">:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">(SDL_BYTEORDER&nbsp;</span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);">&nbsp;SDL_BIG_ENDIAN)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">&nbsp;p[</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">]&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">16</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">|</span><span style="color: rgb(0, 0, 0);">&nbsp;p[</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">]&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">8</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">|</span><span style="color: rgb(0, 0, 0);">&nbsp;p[</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">else</span><span style="color: rgb(0, 0, 0);"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">&nbsp;p[</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">]&nbsp;</span><span style="color: rgb(0, 0, 0);">|</span><span style="color: rgb(0, 0, 0);">&nbsp;p[</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">]&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">8</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">|</span><span style="color: rgb(0, 0, 0);">&nbsp;p[</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">]&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">16</span><span style="color: rgb(0, 0, 0);">;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">case</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">4</span><span style="color: rgb(0, 0, 0);">:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">(Uint32&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">)p;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">default</span><span style="color: rgb(0, 0, 0);">:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 128, 0);">/*</span><span style="color: rgb(0, 128, 0);">&nbsp;shouldn't&nbsp;happen,&nbsp;but&nbsp;avoids&nbsp;warnings&nbsp;</span><span style="color: rgb(0, 128, 0);">*/</span><span style="color: rgb(0, 0, 0);"><br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>}<br><br><br></span><span style="color: rgb(0, 128, 0);">/*</span><span style="color: rgb(0, 128, 0);"><br>&nbsp;*&nbsp;Set&nbsp;the&nbsp;pixel&nbsp;at&nbsp;(x,&nbsp;y)&nbsp;to&nbsp;the&nbsp;given&nbsp;value<br>&nbsp;*&nbsp;NOTE:&nbsp;The&nbsp;surface&nbsp;must&nbsp;be&nbsp;locked&nbsp;before&nbsp;calling&nbsp;this!<br>&nbsp;</span><span style="color: rgb(0, 128, 0);">*/</span><span style="color: rgb(0, 0, 0);"><br></span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">&nbsp;putpixel(SDL_Surface&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">surface,&nbsp;</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">&nbsp;x,&nbsp;</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">&nbsp;y,&nbsp;Uint32&nbsp;pixel)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">&nbsp;bpp&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;surface</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">format</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">BytesPerPixel;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 128, 0);">/*</span><span style="color: rgb(0, 128, 0);">&nbsp;Here&nbsp;p&nbsp;is&nbsp;the&nbsp;address&nbsp;to&nbsp;the&nbsp;pixel&nbsp;we&nbsp;want&nbsp;to&nbsp;set&nbsp;</span><span style="color: rgb(0, 128, 0);">*/</span><span style="color: rgb(0, 0, 0);"><br>&nbsp;&nbsp;&nbsp;&nbsp;Uint8&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">p&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;(Uint8&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">)surface</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">pixels&nbsp;</span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);">&nbsp;y&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">&nbsp;surface</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">pitch&nbsp;</span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);">&nbsp;x&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">&nbsp;bpp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">switch</span><span style="color: rgb(0, 0, 0);">(bpp)&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">case</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">p&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;pixel;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">break</span><span style="color: rgb(0, 0, 0);">;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">case</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">(Uint16&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">)p&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;pixel;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">break</span><span style="color: rgb(0, 0, 0);">;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">case</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">3</span><span style="color: rgb(0, 0, 0);">:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">(SDL_BYTEORDER&nbsp;</span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);">&nbsp;SDL_BIG_ENDIAN)&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p[</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">]&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;(pixel&nbsp;</span><span style="color: rgb(0, 0, 0);">&gt;&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">16</span><span style="color: rgb(0, 0, 0);">)&nbsp;</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">0xff</span><span style="color: rgb(0, 0, 0);">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p[</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">]&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;(pixel&nbsp;</span><span style="color: rgb(0, 0, 0);">&gt;&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">8</span><span style="color: rgb(0, 0, 0);">)&nbsp;</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">0xff</span><span style="color: rgb(0, 0, 0);">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p[</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">]&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;pixel&nbsp;</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">0xff</span><span style="color: rgb(0, 0, 0);">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: rgb(0, 0, 255);">else</span><span style="color: rgb(0, 0, 0);">&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p[</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">]&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;pixel&nbsp;</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">0xff</span><span style="color: rgb(0, 0, 0);">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p[</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">]&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;(pixel&nbsp;</span><span style="color: rgb(0, 0, 0);">&gt;&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">8</span><span style="color: rgb(0, 0, 0);">)&nbsp;</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">0xff</span><span style="color: rgb(0, 0, 0);">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p[</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">]&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;(pixel&nbsp;</span><span style="color: rgb(0, 0, 0);">&gt;&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">16</span><span style="color: rgb(0, 0, 0);">)&nbsp;</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">0xff</span><span style="color: rgb(0, 0, 0);">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">break</span><span style="color: rgb(0, 0, 0);">;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">case</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">4</span><span style="color: rgb(0, 0, 0);">:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">(Uint32&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">)p&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;pixel;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">break</span><span style="color: rgb(0, 0, 0);">;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>}<br><br></span><span style="color: rgb(0, 0, 255);">bool</span><span style="color: rgb(0, 0, 0);">&nbsp;showpic(SDL_Surface&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">surface,</span><span style="color: rgb(0, 0, 255);">const</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">filename)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;SDL_Surface&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">image;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 128, 0);">/*</span><span style="color: rgb(0, 128, 0);">&nbsp;Load&nbsp;the&nbsp;BMP&nbsp;file&nbsp;into&nbsp;a&nbsp;surface&nbsp;</span><span style="color: rgb(0, 128, 0);">*/</span><span style="color: rgb(0, 0, 0);"><br>&nbsp;&nbsp;&nbsp;&nbsp;image&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;IMG_Load(filename);<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">&nbsp;(image&nbsp;</span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);">&nbsp;NULL)&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fprintf(stderr,&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Couldn't&nbsp;load&nbsp;%s:&nbsp;%s\n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,filename,SDL_GetError());<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">false</span><span style="color: rgb(0, 0, 0);">;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 128, 0);">/*</span><span style="color: rgb(0, 128, 0);">&nbsp;Blit&nbsp;onto&nbsp;the&nbsp;screen&nbsp;surface&nbsp;</span><span style="color: rgb(0, 128, 0);">*/</span><span style="color: rgb(0, 0, 0);"><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">(SDL_BlitSurface(image,&nbsp;NULL,&nbsp;surface,&nbsp;NULL)&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fprintf(stderr,&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">BlitSurface&nbsp;error:&nbsp;%s\n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,&nbsp;SDL_GetError());<br><br>&nbsp;&nbsp;&nbsp;&nbsp;SDL_UpdateRect(surface,&nbsp;</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">,&nbsp;</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">,&nbsp;image</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">w,&nbsp;image</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">h);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 128, 0);">/*</span><span style="color: rgb(0, 128, 0);">&nbsp;Free&nbsp;the&nbsp;allocated&nbsp;BMP&nbsp;surface&nbsp;</span><span style="color: rgb(0, 128, 0);">*/</span><span style="color: rgb(0, 0, 0);"><br>&nbsp;&nbsp;&nbsp;&nbsp;SDL_FreeSurface(image);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">true</span><span style="color: rgb(0, 0, 0);">;<br>}<br><br>SDL_Surface</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">&nbsp;createsurf(</span><span style="color: rgb(0, 0, 255);">const</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">&nbsp;filename)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;SDL_Surface&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">image;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 128, 0);">/*</span><span style="color: rgb(0, 128, 0);">&nbsp;Load&nbsp;the&nbsp;BMP&nbsp;file&nbsp;into&nbsp;a&nbsp;surface&nbsp;</span><span style="color: rgb(0, 128, 0);">*/</span><span style="color: rgb(0, 0, 0);"><br>&nbsp;&nbsp;&nbsp;&nbsp;image&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;IMG_Load(filename);<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">&nbsp;(image&nbsp;</span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);">&nbsp;NULL)&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fprintf(stderr,&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Couldn't&nbsp;load&nbsp;%s:&nbsp;%s\n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,filename,SDL_GetError());<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">&nbsp;image;<br>}</span></div>
<br>
getpixel 取得像素的颜色<br>
putpixel 画点<br>
showpic 加载一个图片到某个表面<br>
createsurf 从文件中创造表面<br>
<br>
SDL有大量的示例和第三方库可以使用，非常的不错<br>
最后推荐一个SDL写的超级玛丽游戏<br>
<a href="http://smclone.sourceforge.net/">http://smclone.sourceforge.net/</a><img src ="http://www.cppblog.com/phenix_jiang/aggbug/3379.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/phenix_jiang/" target="_blank">拼命流血</a> 2006-02-21 15:44 <a href="http://www.cppblog.com/phenix_jiang/articles/3379.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ACE示例----Time Server</title><link>http://www.cppblog.com/phenix_jiang/articles/3378.html</link><dc:creator>拼命流血</dc:creator><author>拼命流血</author><pubDate>Tue, 21 Feb 2006 07:33:00 GMT</pubDate><guid>http://www.cppblog.com/phenix_jiang/articles/3378.html</guid><wfw:comment>http://www.cppblog.com/phenix_jiang/comments/3378.html</wfw:comment><comments>http://www.cppblog.com/phenix_jiang/articles/3378.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/phenix_jiang/comments/commentRss/3378.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/phenix_jiang/services/trackbacks/3378.html</trackback:ping><description><![CDATA[这个系列，我将把我学ACE写的一些小程序，放上来跟大家share.<br>
<br>
所谓Time Server，很简单，就是用户连上来的时候，返回系统时间。这可能是最简单的server端程序了。<br>
<br>
代码:<br>
<br>

<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238);"><span style="color: rgb(0, 0, 0);">#ifdef&nbsp;_DEBUG<br>#pragma&nbsp;comment(lib,</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">ACED.lib</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">)<br></span><span style="color: rgb(0, 0, 255);">#else</span><span style="color: rgb(0, 0, 0);"><br>#pragma&nbsp;comment(lib,</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">ACE.lib</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">)<br></span><span style="color: rgb(0, 0, 255);">#endif</span><span style="color: rgb(0, 0, 0);"><br><br>#include&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">ace</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">OS_main.h</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br>#include&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">ace</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">ACE.h</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br>#include&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">ace</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">Log_Msg.h</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br>#include&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">ace</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">SOCK_Acceptor.h</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br>#include&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">ctime</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br><br></span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">&nbsp;main(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">&nbsp;argc,&nbsp;</span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">argv[])<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;ACE_INET_Addr&nbsp;addr(</span><span style="color: rgb(0, 0, 0);">1500</span><span style="color: rgb(0, 0, 0);">);<br>&nbsp;&nbsp;&nbsp;&nbsp;ACE_SOCK_Acceptor&nbsp;server;<br>&nbsp;&nbsp;&nbsp;&nbsp;ACE_SOCK_Stream&nbsp;stream;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">(server.open(addr)</span><span style="color: rgb(0, 0, 0);">==-</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ACE_DEBUG&nbsp;((LM_DEBUG,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ACE_TEXT&nbsp;(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">(%P|%t)&nbsp;%p\n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">),<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ACE_TEXT&nbsp;(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">bind&nbsp;failed</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">)));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);">&nbsp;msg[</span><span style="color: rgb(0, 0, 0);">15</span><span style="color: rgb(0, 0, 0);">];<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">while</span><span style="color: rgb(0, 0, 0);">(server.accept(stream)</span><span style="color: rgb(0, 0, 0);">!=-</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ACE_INET_Addr&nbsp;raddr;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stream.get_remote_addr(raddr);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ACE_DEBUG&nbsp;((LM_DEBUG,ACE_TEXT&nbsp;(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">(%P|%t)&nbsp;connect:%s&nbsp;%d\n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">),raddr.get_host_addr(),raddr.get_port_number()));<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">get&nbsp;current&nbsp;time</span><span style="color: rgb(0, 128, 0);"><br></span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time_t&nbsp;nTime</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time(&nbsp;</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">nTime&nbsp;)&nbsp;;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tm&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">tm1&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;localtime(&nbsp;</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">nTime&nbsp;)&nbsp;;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sprintf(msg,</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">%04d%02d%02d%02d%02d%02d</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,tm1</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">tm_year</span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);">1900</span><span style="color: rgb(0, 0, 0);">,tm1</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">tm_mon</span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">,tm1</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">tm_mday,tm1</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">tm_hour,tm1</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">tm_min,tm1</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">tm_sec);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stream.send_n(msg,</span><span style="color: rgb(0, 0, 255);">sizeof</span><span style="color: rgb(0, 0, 0);">(msg));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stream.close();<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;server.close();<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">;<br>}</span></div>

<p><br>简单的说明一下:<br><br>ACE_INET_Addr相当于socket中的sockaddr_in的封装.</p>

ACE_SOCK_Acceptor是服务器端socket操作的封装，相对于客户端的ACE_SOCK_Connector<br>
<br>
ACE_SOCK_Stream是对Socket数据的封装，可以把它想象成一个在网络上的数据流。发送数据，接收数据就靠它了。<br>
<br>
ACE_DEBUG是ACE提供的Debug机制，会打印信息到控制台<br>
<br>
这个程序使用的是单线程，简单的返回时间，然后关闭连接，这对于Time Server是足够的。<br>
<br>
至于客户端程序的写法，参见我以前写的: <a href="../../sandy/archive/2005/11/24/1281.html">http://www.cppblog.com/sandy/archive/2005/11/24/1281.html</a><img src ="http://www.cppblog.com/phenix_jiang/aggbug/3378.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/phenix_jiang/" target="_blank">拼命流血</a> 2006-02-21 15:33 <a href="http://www.cppblog.com/phenix_jiang/articles/3378.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ACE 示例 --- Echo Server</title><link>http://www.cppblog.com/phenix_jiang/articles/3377.html</link><dc:creator>拼命流血</dc:creator><author>拼命流血</author><pubDate>Tue, 21 Feb 2006 07:21:00 GMT</pubDate><guid>http://www.cppblog.com/phenix_jiang/articles/3377.html</guid><wfw:comment>http://www.cppblog.com/phenix_jiang/comments/3377.html</wfw:comment><comments>http://www.cppblog.com/phenix_jiang/articles/3377.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/phenix_jiang/comments/commentRss/3377.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/phenix_jiang/services/trackbacks/3377.html</trackback:ping><description><![CDATA[<font size="2">Echo server就是那种提供回显服务的程序，就是收到什么，然后就发送什么的程序。<br>
<br>
两种实现方法<br>
<br>
1.<strong>Per&nbsp;client Per Thread</strong> (每个连接每个线程来处理)<br>
<br>
这种方式比较简单，易于实现。缺点是如果有大量的连接，必然占用过量的系统资源。<br>
<br>
代码:<br>
</font><br>

<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238);"><font face="Verdana"><span style="color: rgb(0, 0, 0);">#ifdef&nbsp;_DEBUG<br>#pragma&nbsp;comment(lib,</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">ACED.lib</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">)<br></span><span style="color: rgb(0, 0, 255);">#else</span><span style="color: rgb(0, 0, 0);"><br>#pragma&nbsp;comment(lib,</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">ACE.lib</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">)<br></span><span style="color: rgb(0, 0, 255);">#endif</span><span style="color: rgb(0, 0, 0);"><br><br>#include&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">ace</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">OS_main.h</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br>#include&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">ace</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">ACE.h</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br>#include&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">ace</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">Log_Msg.h</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br>#include&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">ace</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">SOCK_Acceptor.h</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br>#include&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">ace</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">Thread.h</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br><br>DWORD&nbsp;worker(</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">arg)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;ACE_SOCK_Stream&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">pStream&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">(ACE_SOCK_Stream&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">)&nbsp;arg;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);">&nbsp;buffer[</span><span style="color: rgb(0, 0, 0);">32</span><span style="color: rgb(0, 0, 0);">]&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;{</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">};<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">&nbsp;len;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">while</span><span style="color: rgb(0, 0, 0);">(&nbsp;(len&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;pStream</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">recv(buffer,</span><span style="color: rgb(0, 0, 255);">sizeof</span><span style="color: rgb(0, 0, 0);">(buffer)</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">))&nbsp;</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">(pStream</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">send_n(buffer,len)</span><span style="color: rgb(0, 0, 0);">&lt;=</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ACE_DEBUG&nbsp;((LM_DEBUG,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ACE_TEXT&nbsp;(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">(%P|%t)&nbsp;%p\n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">),<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ACE_TEXT&nbsp;(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">send&nbsp;failed</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">)));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">break</span><span style="color: rgb(0, 0, 0);">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;ACE_INET_Addr&nbsp;raddr;<br>&nbsp;&nbsp;&nbsp;&nbsp;pStream</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">get_remote_addr(raddr);<br>&nbsp;&nbsp;&nbsp;&nbsp;ACE_DEBUG&nbsp;((LM_DEBUG,ACE_TEXT&nbsp;(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">(%P|%t)&nbsp;close:%s&nbsp;%d\n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">),raddr.get_host_addr(),raddr.get_port_number()));<br><br>&nbsp;&nbsp;&nbsp;&nbsp;pStream</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">close();<br>&nbsp;&nbsp;&nbsp;&nbsp;delete&nbsp;pStream;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">;<br>}<br><br></span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">&nbsp;main(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">&nbsp;argc,&nbsp;</span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">argv[])<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;ACE_INET_Addr&nbsp;addr(</span><span style="color: rgb(0, 0, 0);">1500</span><span style="color: rgb(0, 0, 0);">);<br>&nbsp;&nbsp;&nbsp;&nbsp;ACE_SOCK_Acceptor&nbsp;server;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">(server.open(addr)</span><span style="color: rgb(0, 0, 0);">==-</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ACE_DEBUG&nbsp;((LM_DEBUG,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ACE_TEXT&nbsp;(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">(%P|%t)&nbsp;%p\n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">),<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ACE_TEXT&nbsp;(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">bind&nbsp;failed</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">)));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;ACE_SOCK_Stream&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">pStream&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">while</span><span style="color: rgb(0, 0, 0);">((pStream&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;ACE_SOCK_Stream())&nbsp;</span><span style="color: rgb(0, 0, 0);">&amp;&amp;</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;server.accept(</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">pStream)</span><span style="color: rgb(0, 0, 0);">!=-</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ACE_INET_Addr&nbsp;raddr;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pStream</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">get_remote_addr(raddr);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ACE_DEBUG&nbsp;((LM_DEBUG,ACE_TEXT&nbsp;(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">(%P|%t)&nbsp;connect:%s&nbsp;%d\n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">),raddr.get_host_addr(),raddr.get_port_number()));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ACE_Thread::spawn(worker,pStream);<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;server.close();<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">;<br>}</span></font></div>
<font face="Verdana"><br>
<font size="2">说明:<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ACE_Thread用来启动thread，当有client连上来的时候，启动worker thread来处理。<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>
<br>
2.<strong>事件模型</strong><br>
socket里面是有select机制，ACE也提供了这种方式。<br>
概念:<br>
Event_Handler:有事件来临的时候的处理器<br>
Reactor:事件管理，负责管理Event_Hanlde和分发事件<br>
Acceptor负责连接Event_Handle,Reactor和Sock_Acceptor<br>
<br>
代码:</font><br>
<br>
</font>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238);"><font face="Verdana"><span style="color: rgb(0, 0, 0);">#ifdef&nbsp;_DEBUG<br>#pragma&nbsp;comment(lib,</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">ACED.lib</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">)<br></span><span style="color: rgb(0, 0, 255);">#else</span><span style="color: rgb(0, 0, 0);"><br>#pragma&nbsp;comment(lib,</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">ACE.lib</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">)<br></span><span style="color: rgb(0, 0, 255);">#endif</span><span style="color: rgb(0, 0, 0);"><br><br>#include&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">ace</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">OS_main.h</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br>#include&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">ace</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">ACE.h</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br>#include&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">ace</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">Svc_Handler.h</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br>#include&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">ace</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">Acceptor.h</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br>#include&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">ace</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">Log_Msg.h</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br>#include&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">ace</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">SOCK_Acceptor.h</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br>#include&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">ace</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">Thread.h</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br><br></span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);">&nbsp;My_Svc_Handler:<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);">&nbsp;ACE_Svc_Handler&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">ACE_SOCK_STREAM,ACE_NULL_SYNCH</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br>{<br></span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);">:<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">&nbsp;open(</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ACE_INET_Addr&nbsp;raddr;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;peer().get_remote_addr(raddr);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ACE_DEBUG&nbsp;((LM_DEBUG,ACE_TEXT&nbsp;(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">(%P|%t)&nbsp;connect:%s&nbsp;%d&nbsp;%d\n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">),raddr.get_host_addr(),raddr.get_port_number(),</span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">));<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reactor()</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">register_handler(</span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">,ACE_Event_Handler::READ_MASK);&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">&nbsp;handle_input(ACE_HANDLE)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);">&nbsp;buffer[</span><span style="color: rgb(0, 0, 0);">32</span><span style="color: rgb(0, 0, 0);">]&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;{</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">};<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">&nbsp;len&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;peer().recv(buffer,</span><span style="color: rgb(0, 0, 255);">sizeof</span><span style="color: rgb(0, 0, 0);">(buffer)</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">(len</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">(peer().send_n(buffer,len)</span><span style="color: rgb(0, 0, 0);">&lt;=</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ACE_DEBUG&nbsp;((LM_DEBUG,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ACE_TEXT&nbsp;(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">(%P|%t)&nbsp;%p\n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">),<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ACE_TEXT&nbsp;(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">send&nbsp;failed</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">)));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">;&nbsp;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">must&nbsp;return&nbsp;-1&nbsp;to&nbsp;call&nbsp;handle_close</span><span style="color: rgb(0, 128, 0);"><br></span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">else</span><span style="color: rgb(0, 0, 0);"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">;&nbsp;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">must&nbsp;return&nbsp;-1&nbsp;to&nbsp;call&nbsp;handle_close</span><span style="color: rgb(0, 128, 0);"><br></span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">&nbsp;handle_close(ACE_HANDLE&nbsp;handle,ACE_Reactor_Mask&nbsp;close_mask)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ACE_INET_Addr&nbsp;raddr;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;peer().get_remote_addr(raddr);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ACE_DEBUG&nbsp;((LM_DEBUG,ACE_TEXT&nbsp;(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">(%P|%t)&nbsp;close:%s&nbsp;%d\n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">),raddr.get_host_addr(),raddr.get_port_number()));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; peer().close();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>};<br><br>typedef&nbsp;ACE_Acceptor</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">My_Svc_Handler,ACE_SOCK_ACCEPTOR</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;MyAcceptor;<br></span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">&nbsp;main(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">&nbsp;argc,&nbsp;</span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">argv[])<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;ACE_INET_Addr&nbsp;addr(</span><span style="color: rgb(0, 0, 0);">1500</span><span style="color: rgb(0, 0, 0);">);<br>&nbsp;&nbsp;&nbsp;&nbsp;MyAcceptor&nbsp;server;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">(server.open(addr)</span><span style="color: rgb(0, 0, 0);">==-</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ACE_DEBUG&nbsp;((LM_DEBUG,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ACE_TEXT&nbsp;(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">(%P|%t)&nbsp;%p\n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">),<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ACE_TEXT&nbsp;(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">bind&nbsp;failed</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">)));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">while</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">){<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ACE_Reactor::instance()</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">handle_events();<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;server.close();<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">;<br>}</span></font></div>
<br>
说明：<br>
1.使用ACE_Acceptor模板类来定义自己的Acceptor<br>
2.ACE_Reactor::instance()-&gt;handle_events()来实现事件分发<br>
3.在Event_Handle里面使用reactor()-&gt;register_handler(this,ACE_Event_Handler::READ_MASK);来注册要关心的事件<br>
4.在Event_Handle中使用peer()来获得Sock_Stream来发送接受数据。<img src ="http://www.cppblog.com/phenix_jiang/aggbug/3377.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/phenix_jiang/" target="_blank">拼命流血</a> 2006-02-21 15:21 <a href="http://www.cppblog.com/phenix_jiang/articles/3377.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>