<rss version="2.0"><channel><title><![CDATA[飞龙山庄]]></title><link>http://blog.chinayes.com/iexapl</link><description><![CDATA[The first template of our Blog..]]></description><item><title><![CDATA[给FreeTextBox增加自己的按钮]]></title><link>http://blog.chinayes.com:80/UserBlog/Article_Details,1.htm</link> <description><![CDATA[<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">大家都知道</span><span lang="EN-US">FreeTextBox</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">现在的版本是不开放源代码的，如果你想给它增加一些自己的东西，<br />看起来会比较麻烦一些，至少没有那些开源版本那样直观，但这并不能妨碍我们给</span><span lang="EN-US">FreeTextBox<br /></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">添加我们自己的按钮。</span></p>
<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">那么究竟怎么做才可以把我们需要的按钮制作成像其他按钮一样安静的放在那里，等待我们<br />去使用它呢？下面就介绍我的实现过程。</span></p>
<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">我的初步想法是，</span><span lang="EN-US">FreeTextBox</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">应该支持我们这样做，所以它可能已经给我们留了一些属性或<br />者</span><span lang="EN-US">Button</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">集合类似的东西，让我们轻松把我们自己的按钮加到它的这个大家庭中。如果推断正确<br />的话，很明显，我们需要做的工作为：</span></p>
<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l1 level1 lfo1; tab-stops: list 18.0pt"><span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'"><span style="mso-list: Ignore">1）<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">制作我们自己的按钮</span></p>
<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l1 level1 lfo1; tab-stops: list 18.0pt"><span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'"><span style="mso-list: Ignore">2）<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">把我们的按钮添加到</span><span lang="EN-US">FreeTextBox</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的</span><span lang="EN-US">Button</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">集合当中</span></p>
<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">那么就让我们去验证一下我们的想法吧。这个验证的过程，就是我们认知和熟悉</span><span lang="EN-US">FreeTextBox</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的一<br />个过程，我想最快的路无疑是看控件的作者留给我们的一些文档啦，</span><span lang="EN-US">FreeTextBox</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的作者很理解他<br />的客户的想法，所以我很快在下载的该控件的一些文件中找到了很需要的东西，那就是</span><span lang="EN-US">readme.txt<br /></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">文本文件，打开，就可以看到作者对关于怎样使用</span><span lang="EN-US">FreeTextBox</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">控件的一个很简单，但很有用的叙述，<br />阅读完后我已经觉得我当初的想法是正确的。在这里我们可以了解到，我们可以自定义我们的工<br />具栏的按钮（指增减已存在的按钮），方法有三种：</span></p>
<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo2; tab-stops: list 18.0pt"><span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'"><span style="mso-list: Ignore">1）<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span lang="EN-US">ToolbarLayout String</span></p>
<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo2; tab-stops: list 18.0pt"><span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'"><span style="mso-list: Ignore">2）<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span lang="EN-US">Procedurally</span></p>
<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo2; tab-stops: list 18.0pt"><span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'"><span style="mso-list: Ignore">3）<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span lang="EN-US">Code (Page_Load or Code Behind)</span></p>
<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这里我只简单列举一下，具体的可参考</span><span lang="EN-US">readme</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">文本文件</span></p>
<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">接下来的事情，就让我们动手制作我们的按钮吧。这一次，我添加的是</span><span lang="EN-US">QQ</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">表情图片，希望做到<br />的效果是点击工具栏上我自己的按钮，然后打开一个页面，选择表情，然后把表情图片返回到</span><span lang="EN-US">Free<br />TextBox</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中，就像其他按钮一样，我不希望我的按钮在工具栏上受到不平等的待遇。如何了解其他按<br />钮的工作原理呢？在没有源代码的情况下，这个可能会是一个麻烦事，但并不能阻挡我们探索事物<br />原理的好奇心，拿出我们的利器：</span><span lang="EN-US">Reflector</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">吧，在这个时候他可以带给我们光明，我想反编译在这个<br />时候也该发挥一点力量了吧！用</span><span lang="EN-US">Reflector</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">打开</span><span lang="EN-US">FreeTextBox DLL</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">文件，展现在你面前的是该控件的类层<br />次结构，当然了，你可能会说，直接在</span><span lang="EN-US">vs.net</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的对象浏览器里就直接可以看到类层次结构，对，是这<br />样的。在这里我们不仅是查看</span><span lang="EN-US">FreeTextBox</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的类层次结构更为重要的是我们需要了解他自己的按钮是<br />如何实现的，因为</span><span lang="EN-US">Reflector</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">可同时帮我们做这两件事情。打开</span><span lang="EN-US">FreeTextBoxControls</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">你会发现他自己的<br />按钮类都在这里静静的等你呢，我找到了跟我需要制作的</span><span lang="EN-US">QQ</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">表情类似的按钮：</span><span lang="EN-US">InsertImageFromGallery</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，<br />查看他的实现，你就会找到你需要的东西，首先，它是继承了</span><span lang="EN-US" style="FONT-FAMILY: 宋体; mso-bidi-font-weight: bold">ToolbarButton</span><span style="FONT-FAMILY: 宋体; mso-bidi-font-weight: bold">，查看他的构造函数，</span></p>]]></description><pubDate>Wed, 10 Jan 2007 18:16:08 GMT</pubDate></item><item><title><![CDATA[正则表达式]]></title><link>http://blog.chinayes.com:80/UserBlog/Article_Details,2.htm</link> <description><![CDATA[以下是例子：<br />利用正则表达式限制网页表单里的文本框输入内容：
<p>用正则表达式限制只能输入中文：onkeyup=&quot;value=value.replace(/[^\u4E00-\u9FA5]/g,'')&quot; onbeforepaste=&quot;clipboardData.setData('text',clipboardData.getData('text').replace(/[^\u4E00-\u9FA5]/g,''))&quot;</p>
<p>1.用正则表达式限制只能输入全角字符： ')&quot; onbeforepaste=&quot;clipboardData.setData('text',clipboardData.getData('text').replace(/[^\uFF00-\uFFFF]/g,''))&quot;</p>
<p>2.用正则表达式限制只能输入数字：onkeyup=&quot;value=value.replace(/[^\d]/g,'') &quot;onbeforepaste=&quot;clipboardData.setData('text',clipboardData.getData('text').replace(/[^\d]/g,''))&quot;</p>
<p>3.用正则表达式限制只能输入数字和英文：onkeyup=&quot;value=value.replace(/[\W]/g,'') &quot;onbeforepaste=&quot;clipboardData.setData('text',clipboardData.getData('text').replace(/[^\d]/g,''))&quot;</p>
<p>4.计算字符串的长度（一个双字节字符长度计2，ASCII字符计1）</p>
<p>String.prototype.len=function(){return this.replace([^\x00-\xff]/g,&quot;aa&quot;).length;}</p>
<p>5.javascript中没有像vbscript那样的trim函数，我们就可以利用这个表达式来实现，如下：</p>
<p>String.prototype.trim = function()<br />{<br />return this.replace(/(^\s*)|(\s*$)/g, &quot;&quot;);<br />}</p>
<p>利用正则表达式分解和转换IP地址：</p>
<p>6.下面是利用正则表达式匹配IP地址，并将IP地址转换成对应数值的Javascript程序：</p>
<p>function IP2V(ip)<br />{<br />re=/(\d+)\.(\d+)\.(\d+)\.(\d+)/g //匹配IP地址的正则表达式<br />if(re.test(ip))<br />{<br />return RegExp.$1*Math.pow(255,3))+RegExp.$2*Math.pow(255,2))+RegExp.$3*255+RegExp.$4*1<br />}<br />else<br />{<br />throw new Error(&quot;不是一个正确的IP地址!&quot;)<br />}<br />}</p>
<p>不过上面的程序如果不用正则表达式，而直接用split函数来分解可能更简单，程序如下：</p>
<p>var ip=&quot;10.100.20.168&quot;<br />ip=ip.split(&quot;.&quot;)<br />alert(&quot;IP值是：&quot;+(ip[0]*255*255*255+ip[1]*255*255+ip[2]*255+ip[3]*1))<br />正则表达式用于字符串处理、表单验证等场合，实用高效。现将一些常用的表达式收集于此，以备不时之需。</p>
<p><br />匹配中文字符的正则表达式： [\u4e00-\u9fa5]<br />评注：匹配中文还真是个头疼的事，有了这个表达式就好办了</p>
<p>匹配双字节字符(包括汉字在内)：[^\x00-\xff]<br />评注：可以用来计算字符串的长度（一个双字节字符长度计2，ASCII字符计1）</p>
<p>匹配空白行的正则表达式：\n\s*\r<br />评注：可以用来删除空白行</p>
<p>匹配HTML标记的正则表达式：&lt;(\S*?)[^&gt;]*&gt;.*?&lt;/\1&gt;|&lt;.*? /&gt;<br />评注：网上流传的版本太糟糕，上面这个也仅仅能匹配部分，对于复杂的嵌套标记依旧无能为力</p>
<p>匹配首尾空白字符的正则表达式：^\s*|\s*$<br />评注：可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等)，非常有用的表达式</p>
<p>匹配Email地址的正则表达式：\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*<br />评注：表单验证时很实用</p>
<p>匹配网址URL的正则表达式：[a-zA-z]+://[^\s]*<br />评注：网上流传的版本功能很有限，上面这个基本可以满足需求</p>
<p>匹配帐号是否合法(字母开头，允许5-16字节，允许字母数字下划线)：^[a-zA-Z][a-zA-Z0-9_]{4,15}$<br />评注：表单验证时很实用</p>
<p>匹配国内电话号码：\d{3}-\d{8}|\d{4}-\d{7}<br />评注：匹配形式如 0511-4405222 或 021-87888822</p>
<p>匹配腾讯QQ号：[1-9][0-9]{4,}<br />评注：腾讯QQ号从10000开始</p>
<p>匹配中国邮政编码：[1-9]\d{5}(?!\d)<br />评注：中国邮政编码为6位数字</p>
<p>匹配身份证：\d{15}|\d{18}<br />评注：中国的身份证为15位或18位</p>
<p>匹配ip地址：\d+\.\d+\.\d+\.\d+<br />评注：提取ip地址时有用</p>
<p>匹配特定数字：<br />^[1-9]\d*$　 　 //匹配正整数<br />^-[1-9]\d*$ 　 //匹配负整数<br />^-?[1-9]\d*$　　 //匹配整数<br />^[1-9]\d*|0$　 //匹配非负整数（正整数 + 0）<br />^-[1-9]\d*|0$　　 //匹配非正整数（负整数 + 0）<br />^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$　　 //匹配正浮点数<br />^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$　 //匹配负浮点数<br />^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$　 //匹配浮点数<br />^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$　　 //匹配非负浮点数（正浮点数 + 0）<br />^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$　　//匹配非正浮点数（负浮点数 + 0）<br />评注：处理大量数据时有用，具体应用时注意修正</p>
<p>匹配特定字符串：<br />^[A-Za-z]+$　　//匹配由26个英文字母组成的字符串<br />^[A-Z]+$　　//匹配由26个英文字母的大写组成的字符串<br />^[a-z]+$　　//匹配由26个英文字母的小写组成的字符串<br />^[A-Za-z0-9]+$　　//匹配由数字和26个英文字母组成的字符串<br />^\w+$　　//匹配由数字、26个英文字母或者下划线组成的字符串<br />评注：最基本也是最常用的一些表达式</p>
<p>匹配中文字符的正则表达式： [\u4e00-\u9fa5]</p>
<p>匹配双字节字符(包括汉字在内)：[^\x00-\xff]</p>
<p>匹配空行的正则表达式：\n[\s| ]*\r</p>
<p>匹配HTML标记的正则表达式：/&lt;(.*)&gt;.*&lt;\/\1&gt;|&lt;(.*) \/&gt;/ </p>
<p>匹配首尾空格的正则表达式：(^\s*)|(\s*$)</p>
<p>匹配Email地址的正则表达式：\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*</p>
<p>匹配网址URL的正则表达式：<a href="http://([/w-]+/.)+[/w-]+(/[/w">http://([\w-]+\.)+[\w-]+(/[\w</a>- ./?%&amp;=]*)?</p>
<p><br />^\d+$　　//匹配非负整数（正整数 + 0） <br />^[0-9]*[1-9][0-9]*$　　//匹配正整数 <br />^((-\d+)|(0+))$　　//匹配非正整数（负整数 + 0） <br />^-[0-9]*[1-9][0-9]*$　　//匹配负整数 <br />^-?\d+$　　　　//匹配整数 <br />^\d+(\.\d+)?$　　//匹配非负浮点数（正浮点数 + 0） <br />^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$　　//匹配正浮点数 <br />^((-\d+(\.\d+)?)|(0+(\.0+)?))$　　//匹配非正浮点数（负浮点数 + 0） <br />^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$　　//匹配负浮点数 <br />^(-?\d+)(\.\d+)?$　　//匹配浮点数 <br />^[A-Za-z]+$　　//匹配由26个英文字母组成的字符串 <br />^[A-Z]+$　　//匹配由26个英文字母的大写组成的字符串 <br />^[a-z]+$　　//匹配由26个英文字母的小写组成的字符串 <br />^[A-Za-z0-9]+$　　//匹配由数字和26个英文字母组成的字符串 <br />^\w+$　　//匹配由数字、26个英文字母或者下划线组成的字符串 <br />^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$</p>]]></description><pubDate>Wed, 10 Jan 2007 18:24:47 GMT</pubDate></item><item><title><![CDATA[Trackback spambot的特征分布 － 2006年12月份]]></title><link>http://blog.chinayes.com:80/UserBlog/Article_Details,3.htm</link> <description><![CDATA[<div class="entry-body">
<p>用一些简单的脚本和接口对MT spambot做了一些统计，网站上已经没有mt-tb.cgi这个文件了，来访问这个地址的都是spammer。</p>
<p>结论如下：spam的运行时间分布很均匀，来源IP以国外为主，一般是对MT已有文章地毯式的ping。<br />基本上如果通过特征的方法来识别，不如全部过滤。所以动态修改trackback地址/文件名是必须的可以过滤掉95%以上的spam，动态trackback地址/参数则过滤掉将剩余的5%中的90%。</p>
<p>详细数据附后。</p>
</div>
<div class="entry-more" id="more">
<p>时间分布：<br /></p>
<blockquote>4049 00<br />4039 01<br />3305 02<br />4932 03<br />4269 04<br />4039 05<br />5574 06<br />4468 07<br />4249 08<br />4784 09<br />3823 10<br />3584 11<br />4522 12<br />3216 13<br />2533 14<br />3180 15<br />1826 16<br />2235 17<br />2489 18<br />1946 19<br />2613 20<br />2971 21<br />2863 22<br />2858 23<br /></blockquote><br />比较均匀，一天24小时都有，下午16点（北京时间）是个低谷：和后面的来源地址分布像对应：应该是美国的凌晨。
<p>&nbsp;</p>
<p>IP分布：<br /></p>
<blockquote>58.247.2.108#上海市网通<br />59.42.210.176#广东省广州市电信ADSL<br />61.189.240.196#贵州省毕节市电信<br />61.238.244.86#香港九龙半岛酒店<br />62.225.15.58#德国EMUCH.NET<br />64.124.182.119#美国加洲<br />66.14.200.170#美国德州GTE.net公司用户<br />66.132.158.88#美国EMUCH.NET<br />66.139.102.2#美国Global University<br />66.165.172.163#美国EMUCH.NET<br />66.192.59.18#美国Time Warner Telecom<br />66.204.165.81#美国阿肯色州<br />66.220.26.133#美国EMUCH.NET<br />66.228.143.9#美国EMUCH.NET<br />72.32.59.213#美国EMUCH.NET<br />80.237.140.233#英国德文郡 普里茅斯<br />84.14.52.34#法国EMUCH.NET<br />85.214.67.230#欧洲及北非,西亚<br />129.41.250.20#美国IBM公司<br />140.115.117.143#台湾省中央大学<br />193.69.180.120#挪威<br />193.194.84.198#阿尔及利亚<br />194.64.227.16#德国EMUCH.NET<br />195.159.8.28#挪威<br />196.46.249.34#南非<br />200.29.137.217#巴西<br />200.31.42.3#巴西<br />200.88.223.98#巴西<br />200.208.102.17#巴西<br />201.211.46.149#美国中部/南部(IANA)<br />202.83.206.37#香港<br />202.123.234.188#印度尼西亚EMUCH.NET<br />203.144.144.163#泰国EMUCH.NET<br />203.144.144.164#泰国EMUCH.NET<br />203.158.221.227#泰国Rajamangala Institute of Technology<br />208.138.31.88#美国/加拿大<br />210.17.149.157#香港<br />212.227.80.22#德国EMUCH.NET<br />213.167.111.10#挪威<br />217.9.235.73#保加利亚<br /></blockquote><br />明显来自国外的比较多，集中在TOP 100个IP上（以上使用<a href="http://emuch.net/ip.php"><font color="#0082ff">小木虫批量IP地址查询</font></a>）。
<p>&nbsp;</p>
<p>ID分布：很均匀，基本上是地毯式的从1－999轮循ping<br /></p>
<blockquote>494 606<br />478 636<br />465 685<br />457 612<br />435 692<br />429 837<br />400 526<br />388 688<br />382 622<br />375 781<br />371 554<br />369 541<br />368 476<br />365 700<br />364 875<br />364 572<br />363 77<br />363 623<br />361 655<br />361 407<br />360 689<br />360 551<br />359 663<br />359 228<br />358 442<br />357 705<br />357 630<br />356 733<br />355 880<br />355 716<br />354 867<br />354 375<br />353 883<br />353 882<br />353 651<br />353 278<br />352 779<br />352 767<br />352 697<br />352 659</blockquote>
<p>&nbsp;</p>
<p>HTTP的头：HTTP 1.1为主<br />63108 HTTP/1.1&quot;<br />21394 HTTP/1.0&quot;</p>
<p>浏览器分布：大量spambot模拟Opera？<br /></p>
<blockquote>28544 &quot;Mozilla/4.0 (compatible; MSIE<br />25686 &quot;Mozilla/5.0 (Windows; U;<br />2608 &quot;Opera/6.04 (Windows 2000;<br />2566 &quot;Opera/7.0 (Windows NT<br />2562 &quot;Opera/6.01 (Windows 98;<br />2549 &quot;Opera/6.04 (Windows XP;<br />2544 &quot;Opera/6.04 (Windows 98;<br />2509 &quot;Opera/7.0 (Windows 2000;<br />2508 &quot;Opera/6.02 (Windows 2000;<br />2495 &quot;Opera/6.03 (Windows 2000;<br />2490 &quot;Opera/6.01 (Windows ME;<br />2480 &quot;Opera/5.02 (Windows 98;<br />1871 &quot;Opera/7.02 Bork-edition (Windows</blockquote>
<p>&nbsp;</p>
<p>而本月的404错误统计：也完全被SPAMBOT的trackback所淹没：<br /></p>
<blockquote>找不到的网址连结 (HTTP 错误码 404) <br />URL (4316) 错误次数 反相链接<br />/cgi-bin/mt/mt-comments.cgi 9009 -<br />/phpman.php/man/bn_add/3ssl/ 8645 -<br />/qq.txt 1240 -<br />/phpman.php/man/post/1/ 1205 -<br />/cgi-bin/mt/mt-tb.cgi/606 1180 -<br />/cgi-bin/mt/mt-tb.cgi/636 1127 -<br />/cgi-bin/mt/mt-tb.cgi/612 1088 -<br />/cgi-bin/mt/mt-tb.cgi/685 1086 -<br />/cgi-bin/mt/mt-tb.cgi/837 1081 -<br />/phpman.php/man/ldap_add/3/ 1038 -<br />/cgi-bin/mt/mt-tb.cgi/526 1026 -<br />/s8qq.txt 966 -<br />/cgi-bin/mt/mt-tb.cgi/692 953 -<br />/cgi-bin/mt/mt-tb.cgi/622 834 -<br />/cgi-bin/mt/mt-tb.cgi/572 825 -<br />/cgi-bin/mt/mt-tb.cgi/551 817 -<br />/cgi-bin/mt/mt-tb.cgi/541 815 -<br />/cgi-bin/mt/mt-tb.cgi/688 808 -<br />/cgi-bin/mt/mt-tb.cgi/457 808 -<br />/cgi-bin/mt/mt-tb.cgi/781 806 -<br />/cgi-bin/mt/mt-tb.cgi/705 805 -<br />/cgi-bin/mt/mt-tb.cgi/375 803 -<br />/cgi-bin/mt/mt-tb.cgi/827 803 -<br />/cgi-bin/mt/mt-tb.cgi/168 799 -</blockquote>
<p>&nbsp;</p>
<p>从<a href="http://www.chedong.com/blog/archives/001156.html"><font color="#0082ff">SPAM的内容</font></a>来看：赌博、色情和各种暴利医药类行业为主。</p>
</div>]]></description><pubDate>Thu, 11 Jan 2007 10:17:59 GMT</pubDate></item><item><title><![CDATA[年终小结+IBM求职记]]></title><link>http://blog.chinayes.com:80/UserBlog/Article_Details,4.htm</link> <description><![CDATA[<p>眼看又到年终，小结一下，呵呵，2006算得上是十分忙碌的一年，回过头来看看发现自己倒是做了不少事情：发布了两个X2Blog版本；发布了我的web控件集；和bood一起完成<a href="http://www.jjwenxue.com/">www.jjwenxue.com</a> 这个项目；完成了《征服Ajax：web2.0开发技术详解》一书；拿到了驾照；拿到了IBM的offer。期间还一直在写着我的Ajax类库（未完成），唯一失败的地方是发表一篇论文的计划没有达成，这个一月份必须得搞定了！</p>
<p>前面的事情以前Blog都有记录，下面主要记述IBM求职经历，基本是流水帐了，呵呵，也希望对后来人有所帮助。<br />IBM的笔试是在十月下旬，之前有过微软和google的笔试，可惜直接挂笔，也没什么可提了，都考的是算法，我优势不大，我一直在想为啥不靠DotNet或者JavaScript呢，呵呵。IBM的笔试内容分为两部分，智力测试和专业综合知识。其中智力测试比较变态，时间很短，题量却很大，做出来大概每个人都觉得很惨。综合知识可选Java或者C++，我当然是选C++了，对Java是一无所知。做的感觉还可以。</p>
<p>之后过了1个星期，连续接到两个电话面试，第一个北京电话开始就让我用英文自我介绍，当时我还没做任何准备，有点慌乱的说，就提议让他用英文问问题，我来用英文回答，否则真不知道从何说起了。谁知道面试官还真幽默，来了一句：Can you introduce yourself in English?。。。暴寒，差点翻倒过去&hellip;&hellip;无奈只好吞吞吐吐的来了几句中国式英语，就这么蒙混过去了，也没被刁难，呵呵。第二天又收到了上海来的第二个电话面试，问题基本上和第一个差不多，问了些技术专长，做过哪些项目等等，因为我不会Java，也没问到什么技术难题，都是些open question。</p>
<p>又过一个星期，收到通知去参加一面，也没做什么特殊的准备，我相信just be yourself,that's ok. 总的感觉这次面试比较顺利，内容也比较多，考官很nice，会一直跟着你的思路来问问题，期间我说到x2blog是开源的，符合web2.0的，他就追问我对web2.0有什么看法，什么是web2.0，它有什么特征，我就按照通常的理解说了一遍，比如以个人为中心，良好的用户体验等等，感觉说的还行。但问到对开源组织有什么认识，有多少了解，我就一头雾水了，只知道个Apache，他之后又说了几个，我都不懂，然后又问到如果让我做世界开源组织的领导者，该怎么去管理（晕，果然问题够open，看来自己一知半解的东西还是少提为妙，呵呵），硬着头皮说了一些，比如保护开源软件开发者利益，保证最终用户利益等等。之后他让我挑一个项目介绍了下，并在白版上画一下项目结构等等，我选了ImagineCup那个项目，应该讲的还不错，bt的是讲完之后太让我用英文再介绍一遍这个项目，很郁闷，最怕考你口语了 （心里想：自我介绍的英文我背熟了你不问，真是狡猾阿&hellip;&hellip;）。面试最后让我说说对IBM的认识，问的一个问题再次让我暴寒：问我如果微软和IBM同时给我offer，而且是同样的职位，我会选哪个&hellip;&hellip;在当时的情况下，微软的拒信都收到了，我当然说选IBM，随后自然把IBM的优势说了一遍&hellip;&hellip;随后面试就结束了，呵呵，一身冷汗&hellip;&hellip;</p>
<p>之后又1星期，收到通知去上海二面，两个面试官，一直面带笑容，感觉仍然很nice，问问题也都是open的，因为一直稳定的笑容，我也不知道究竟自己答得好还是坏，这是唯一郁闷的地方，或许这就是专业的面试官素质吧，面试过程看不到任何反馈信息。差不多半个小时面完，或许还是因为他们都是做Java开发的，我仍然没有被问到很深的技术问题，寒，面完后继续等消息&hellip;&hellip;</p>
<p>又1星期，通知final面，继续兴奋的奔去上海，这次好像是部门的大boss，依然nice的man，问题却都非常bt。&ldquo;了解哪些操作系统？对操作系统底层结构有多少了解？&rdquo;，&ldquo;哦？你数据库经验比较多，那你对数据库底层存储结构有多少了解？&rdquo;，&ldquo;你本科不是学计算机的，那你的基础知识你认为够扎实吗？&rdquo; ，&ldquo;你认为你的c++水平是多少&rdquo;，&ldquo;你们课程应该有java的，说说applet和servelet的区别&rdquo;，寒的很啊，都是我不懂的东西，我基本都是老实回答：&ldquo;我最多停留在教科书水平，没有实际经验&rdquo;。就这么，他就让偶回来等通知了，虽然一直很友善的笑着，我却感觉心里凉了一大截，这回希望渺茫了。</p>
<p>又过1星期，又1星期，又1星期，又1星期&hellip;&hellip;就在我早就放弃时，一个月之后意外收到IBM offer！呵呵，看来RP真的是要积累的阿！由此也可见，IBM面试的流程真的挺折磨人的！不过可惜的是，或许以后接触.net的机会要少了，转投Java的怀抱了&hellip;&hellip;</p>
<p>在此期间，也参加过一些笔试，但都成了挂笔，比较郁闷的是一些公司，比如EMC和SAP简历关都过不去，其实都是ChinaHR搞的，真是够烂的，草菅人命。唯一通过笔试给面试的是群硕，之后连续两面，先是问技术，主要是dotnet，问题不大，随后是HR面，并当场给了offer，但因为它的期限实在太短，就没有签。不过群硕的HR mm也是很赞的，基本没有问我什么问题，倒是一直在给我一些人生发展的建议，感觉说的很对，也许在推销自己的公司吧，呵呵。</p>]]></description><pubDate>Thu, 11 Jan 2007 10:26:04 GMT</pubDate></item><item><title><![CDATA[为什么框架(frame)页面之间无法使用appendChild()？]]></title><link>http://blog.chinayes.com:80/UserBlog/Article_Details,5.htm</link> <description><![CDATA[今天在写程序时遇到一个需求，是需要在一个页面中使用程序改变其中的一个框架页面的DOM结构，于是自然会用到appendChild这样的方法，例如：
<div class="codeArea js">
<div style="COLOR: #000000"><font color="#0000ff">var</font>&nbsp;<font color="#000000">div</font><font color="#000000">=</font><font color="#000000">document</font><font color="#000000">.</font><font color="#000000">createElement</font><font color="#000000">(</font><font color="#ff00ff">'div'</font><font color="#000000">);</font><br /><font color="#000000">window</font><font color="#000000">.</font><font color="#000000">frames</font><font color="#000000">[</font><font color="#ff00ff">'frameName1'</font><font color="#000000">].</font><font color="#000000">contentWindow</font><font color="#000000">.</font><font color="#000000">document</font><font color="#000000">.</font><font color="#000000">body</font><font color="#000000">.</font><font color="#000000">appendChild</font><font color="#000000">(</font><font color="#000000">div</font><font color="#000000">);</font></div>
</div>
<p>尽管看上去没有任何问题，实际上在Firefox下它也能正常工作，但在IE下却偏偏不能正确运行，着实很郁闷。第一想法就是是：唉，该死的IE bug还真多！<br />无奈的开始google：frame+appendChild，希望能找到一些hack方法，倒有很多人建议用innerHTML，这个我也想过，太不方便，很多事件都无法绑定。<br />继续搜寻&hellip;&hellip;，终于找到一篇文章解决了这个问题，基本意思是这样的：<br /><strong>document表示一个页面DOM结构的根节点，而document.createElement()方法是在document本身的结构中创建一个节点，因此想把一个文档的节点移动到另外一个文档的节点当中去，是不可行的。</strong><br />呵呵，原来如此啊！这样的解释的确很合乎道理的，上面代码是有点问题，应该用子框架的文档（document）来创建节点：</p>
<div class="codeArea js">
<div style="COLOR: #000000"><font color="#0000ff">var</font>&nbsp;<font color="#000000">doc</font><font color="#000000">=</font><font color="#000000">window</font><font color="#000000">.</font><font color="#000000">frames</font><font color="#000000">[</font><font color="#ff00ff">'frameName1'</font><font color="#000000">].</font><font color="#000000">contentWindow</font><font color="#000000">.</font><font color="#000000">document</font><font color="#000000">;</font><br /><font color="#0000ff">var</font>&nbsp;<font color="#000000">div</font><font color="#000000">=</font><font color="#000000">doc</font><font color="#000000">.</font><font color="#000000">createElement</font><font color="#000000">(</font><font color="#ff00ff">'div'</font><font color="#000000">);</font><br /><font color="#000000">doc</font><font color="#000000">.</font><font color="#000000">body</font><font color="#000000">.</font><font color="#000000">appendChild</font><font color="#000000">(</font><font color="#000000">div</font><font color="#000000">);</font></div>
</div>
<p>这样在FF和IE下都能正确运行了！<br /><br />但之前FF下为什么也能运行呢？有两种解释：<br />1。FF有自己的容错性，就像IE就有很多讨厌的容错性。<br />2。因为iframe是当前页面的节点，而iframe中的文档自然也认为是父页面的子节点了，只不过具有父页面根结点的所有特征，于是既然框架页面和父页面是在一个根下面，那么节点的互相移动也合乎道理了，呵呵，即使有点勉强，倒也能说的通的！<br /><br />于是在这个问题上FF和IE孰是孰非也就很难说清楚了，只是辛苦了我们这些写程序的，现在大家明白怎么回事儿也就行了。</p>]]></description><pubDate>Thu, 11 Jan 2007 10:37:37 GMT</pubDate></item><item><title><![CDATA[试试用wbeditor发布Blog (哎,前面发出来是乱码)]]></title><link>http://blog.chinayes.com:80/UserBlog/Article_Details,7.htm</link> <description><![CDATA[版终究烦人来的.后来却因为SharpReader很占内存的样子,打开比较慢,有一次居然因为它出了什么错令我突然当机,555,手头做了半天的东东没保存.擦干眼泪便改用FeedDemon了(有人发布了Crack呀).早前也试过wbloggar那个工具写Blog,不过不行,今天呢??^^]]></description><pubDate>Thu, 11 Jan 2007 11:37:03 GMT</pubDate></item><item><title><![CDATA[利用正则表达式限制网页表单里的文本框输入内容]]></title><link>http://blog.chinayes.com:80/UserBlog/Article_Details,12.htm</link> <description><![CDATA[以下是例子：<br />利用正则表达式限制网页表单里的文本框输入内容：
<p>用正则表达式限制只能输入中文：onkeyup=&quot;value=value.replace(/[^\u4E00-\u9FA5]/g,'')&quot; onbeforepaste=&quot;clipboardData.setData('text',clipboardData.getData('text').replace(/[^\u4E00-\u9FA5]/g,''))&quot;</p>
<p>1.用正则表达式限制只能输入全角字符： ')&quot; onbeforepaste=&quot;clipboardData.setData('text',clipboardData.getData('text').replace(/[^\uFF00-\uFFFF]/g,''))&quot;</p>
<p>2.用正则表达式限制只能输入数字：onkeyup=&quot;value=value.replace(/[^\d]/g,'') &quot;onbeforepaste=&quot;clipboardData.setData('text',clipboardData.getData('text').replace(/[^\d]/g,''))&quot;</p>
<p>3.用正则表达式限制只能输入数字和英文：onkeyup=&quot;value=value.replace(/[\W]/g,'') &quot;onbeforepaste=&quot;clipboardData.setData('text',clipboardData.getData('text').replace(/[^\d]/g,''))&quot;</p>
<p>4.计算字符串的长度（一个双字节字符长度计2，ASCII字符计1）</p>
<p>String.prototype.len=function(){return this.replace([^\x00-\xff]/g,&quot;aa&quot;).length;}</p>
<p>5.javascript中没有像vbscript那样的trim函数，我们就可以利用这个表达式来实现，如下：</p>
<p>String.prototype.trim = function()<br />{<br />return this.replace(/(^\s*)|(\s*$)/g, &quot;&quot;);<br />}</p>
<p>利用正则表达式分解和转换IP地址：</p>
<p>6.下面是利用正则表达式匹配IP地址，并将IP地址转换成对应数值的Javascript程序：</p>
<p>function IP2V(ip)<br />{<br />re=/(\d+)\.(\d+)\.(\d+)\.(\d+)/g //匹配IP地址的正则表达式<br />if(re.test(ip))<br />{<br />return RegExp.$1*Math.pow(255,3))+RegExp.$2*Math.pow(255,2))+RegExp.$3*255+RegExp.$4*1<br />}<br />else<br />{<br />throw new Error(&quot;不是一个正确的IP地址!&quot;)<br />}<br />}</p>
<p>不过上面的程序如果不用正则表达式，而直接用split函数来分解可能更简单，程序如下：</p>
<p>var ip=&quot;10.100.20.168&quot;<br />ip=ip.split(&quot;.&quot;)<br />alert(&quot;IP值是：&quot;+(ip[0]*255*255*255+ip[1]*255*255+ip[2]*255+ip[3]*1))<br />正则表达式用于字符串处理、表单验证等场合，实用高效。现将一些常用的表达式收集于此，以备不时之需。</p>
<p><br />匹配中文字符的正则表达式： [\u4e00-\u9fa5]<br />评注：匹配中文还真是个头疼的事，有了这个表达式就好办了</p>
<p>匹配双字节字符(包括汉字在内)：[^\x00-\xff]<br />评注：可以用来计算字符串的长度（一个双字节字符长度计2，ASCII字符计1）</p>
<p>匹配空白行的正则表达式：\n\s*\r<br />评注：可以用来删除空白行</p>
<p>匹配HTML标记的正则表达式：&lt;(\S*?)[^&gt;]*&gt;.*?&lt;/\1&gt;|&lt;.*? /&gt;<br />评注：网上流传的版本太糟糕，上面这个也仅仅能匹配部分，对于复杂的嵌套标记依旧无能为力</p>
<p>匹配首尾空白字符的正则表达式：^\s*|\s*$<br />评注：可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等)，非常有用的表达式</p>
<p>匹配Email地址的正则表达式：\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*<br />评注：表单验证时很实用</p>
<p>匹配网址URL的正则表达式：[a-zA-z]+://[^\s]*<br />评注：网上流传的版本功能很有限，上面这个基本可以满足需求</p>
<p>匹配帐号是否合法(字母开头，允许5-16字节，允许字母数字下划线)：^[a-zA-Z][a-zA-Z0-9_]{4,15}$<br />评注：表单验证时很实用</p>
<p>匹配国内电话号码：\d{3}-\d{8}|\d{4}-\d{7}<br />评注：匹配形式如 0511-4405222 或 021-87888822</p>
<p>匹配腾讯QQ号：[1-9][0-9]{4,}<br />评注：腾讯QQ号从10000开始</p>
<p>匹配中国邮政编码：[1-9]\d{5}(?!\d)<br />评注：中国邮政编码为6位数字</p>
<p>匹配身份证：\d{15}|\d{18}<br />评注：中国的身份证为15位或18位</p>
<p>匹配ip地址：\d+\.\d+\.\d+\.\d+<br />评注：提取ip地址时有用</p>
<p>匹配特定数字：<br />^[1-9]\d*$　 　 //匹配正整数<br />^-[1-9]\d*$ 　 //匹配负整数<br />^-?[1-9]\d*$　　 //匹配整数<br />^[1-9]\d*|0$　 //匹配非负整数（正整数 + 0）<br />^-[1-9]\d*|0$　　 //匹配非正整数（负整数 + 0）<br />^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$　　 //匹配正浮点数<br />^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$　 //匹配负浮点数<br />^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$　 //匹配浮点数<br />^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$　　 //匹配非负浮点数（正浮点数 + 0）<br />^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$　　//匹配非正浮点数（负浮点数 + 0）<br />评注：处理大量数据时有用，具体应用时注意修正</p>
<p>匹配特定字符串：<br />^[A-Za-z]+$　　//匹配由26个英文字母组成的字符串<br />^[A-Z]+$　　//匹配由26个英文字母的大写组成的字符串<br />^[a-z]+$　　//匹配由26个英文字母的小写组成的字符串<br />^[A-Za-z0-9]+$　　//匹配由数字和26个英文字母组成的字符串<br />^\w+$　　//匹配由数字、26个英文字母或者下划线组成的字符串<br />评注：最基本也是最常用的一些表达式</p>
<p>匹配中文字符的正则表达式： [\u4e00-\u9fa5]</p>
<p>匹配双字节字符(包括汉字在内)：[^\x00-\xff]</p>
<p>匹配空行的正则表达式：\n[\s| ]*\r</p>
<p>匹配HTML标记的正则表达式：/&lt;(.*)&gt;.*&lt;\/\1&gt;|&lt;(.*) \/&gt;/ </p>
<p>匹配首尾空格的正则表达式：(^\s*)|(\s*$)</p>
<p>匹配Email地址的正则表达式：\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*</p>
<p>匹配网址URL的正则表达式：<a href="http://([/w-]+/.)+[/w-]+(/[/w">http://([\w-]+\.)+[\w-]+(/[\w</a>- ./?%&amp;=]*)?</p>
<p><br />^\d+$　　//匹配非负整数（正整数 + 0） <br />^[0-9]*[1-9][0-9]*$　　//匹配正整数 <br />^((-\d+)|(0+))$　　//匹配非正整数（负整数 + 0） <br />^-[0-9]*[1-9][0-9]*$　　//匹配负整数 <br />^-?\d+$　　　　//匹配整数 <br />^\d+(\.\d+)?$　　//匹配非负浮点数（正浮点数 + 0） <br />^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$　　//匹配正浮点数 <br />^((-\d+(\.\d+)?)|(0+(\.0+)?))$　　//匹配非正浮点数（负浮点数 + 0） <br />^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$　　//匹配负浮点数 <br />^(-?\d+)(\.\d+)?$　　//匹配浮点数 <br />^[A-Za-z]+$　　//匹配由26个英文字母组成的字符串 <br />^[A-Z]+$　　//匹配由26个英文字母的大写组成的字符串 <br />^[a-z]+$　　//匹配由26个英文字母的小写组成的字符串 <br />^[A-Za-z0-9]+$　　//匹配由数字和26个英文字母组成的字符串 <br />^\w+$　　//匹配由数字、26个英文字母或者下划线组成的字符串 <br />^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$</p>]]></description><pubDate>Thu, 11 Jan 2007 13:09:30 GMT</pubDate></item><item><title><![CDATA[我们的网页要指定一个编码字符集]]></title><link>http://blog.chinayes.com:80/UserBlog/Article_Details,27.htm</link> <description><![CDATA[<p>通常情况下，我们的网页要指定一个编码字符集，如 GB2312、UTF-8、ISO-8859-1 等，这样我们就可以在网页上显示我们指定编码的文字了。但是我们很可能会遇到这种情况，那就是我们可能希望在 ISO-8859-1 编码的网页上显示汉字，或者在 GB2312 编码的网页上显示韩文等。当然一种解决办法就是我们不用 ISO-8859-1 或者 GB2312 编码，而统统都采用 UTF-8 编码，这样我们只要在这种编码下，就可以混合显示各国文字了，这是现在很多网站采用的方法。 <br /><br />而我这里所说的并非上面这种方法，因为上面这种方法必须要指定字符集为 UTF-8 才可以，一旦用户手工指定为其他字符集，或者可能因为某些原因，那个字符集设置没起作用，而浏览器又没有正确自动识别的话，我们看到的网页还是乱码，尤其是在某些用框架作的网页中，某个框架中的页面如果字符集设置没起作用，在 firefox 中显示乱码而且还没法改变（我是说在不装RightEncode插件的情况下）。 <br /><br />而我这里介绍的方法即使是把网页指定为 ISO-8859-1 字符集，也能够正确显示汉字、日文等。原理很简单，就是把除了 ISO-8859-1 编码中前128个字符以外的所有其他的编码都用 NCR(Numeric character reference) 来表示。比如&ldquo;汉字&rdquo;这两个字，如果我们写成&ldquo;&amp;#27721;&amp;#23383;&rdquo;这种形式，那么它在任意字符集下都可以正确显示。根据这个原理，我写了下面这个程序，它可以把现有的网页转化为在任意字符集下都能显示的网页。你只需要指定源网页的字符集和源网页，点提交按钮，就可以得到目标网页了。你也可以只转化某些文字，只需要把文字填写到文本框中，并指定这些文字原来的字符集，点提交按钮，就会在页面上面显示编码后的文字了。另外我还编写了 WordPress 的插件，现在我的 Blog 已经可以在任意字符集下都能正确显示了。 <br /><br />实现方法： <br /><br />首先第一步是要把源字符集的字符串转化为UTF-16字符集，做这一步是因为UTF-16字符集中的每个字符都是两个字节，后面处理起来很容易，而如果在源字符集上直接做处理则很复杂。源字符集可以从原网页中的meta标签中获得，也可以单独指定，我的程序是让用户在表单中指定源字符集，因为我不能保证用户提交的文件就一定是HTML文件（其他文件也是可以的，比如这个WordPress的汉化包源文件是个po文件，它里面的内容也可以这样处理），而且即使是HTML文件，里面也不一定就有用于指定字符集的meta标签，所以通过表单单独指定字符集比较保险。你可能会觉得将一种字符集转化为另一种字符集很复杂，确实如此，如果自己来实现的话，确实非常麻烦，但是用PHP来做却很容易，因为它里面已经包含这样的函数了，你可以通过iconv函数很容易的来实现各种字符集之间的转化，如果你的机器上没有安装iconv扩展，你也可以使用mb_convert_encoding函数，如果Multibyte String扩展也没有安装，那就没办法了，因为你要自己实现那么多种编码的转化基本上是不可能的，除非你是顶级大牛！推荐使用iconv，因为这个效率高，支持的字符集也更多。 <br /><br />做完上面那一步之后，接下来是以每两个字节为单位对字符串进行处理。这两个字节直接转化为数字就是&amp;#xxxxx;中的xxxxx，如果这个数字小于128就直接使用这个字符（注意这里就变成单字节了），否则就使用&amp;#xxxxx;的形式。这里有一点要注意，就是当这个数字是65279（16进制的0xFEFF）时，请把它忽略掉，因为这个是Unicode编码中的传输控制字符，而我们现在的字符串已经只有iso-8859-1编码中的前128个字符了，所以我们不需要它了。 <br /><br />好了，基本思路就是这样，下面是实现的程序： </p>
<div>
<p>PHP程序版本函数：<br />&lt;?php <br />function nochaoscode($encode, $str) { <br />&nbsp;&nbsp;&nbsp; $str = iconv($encode, &quot;UTF-16BE&quot;, $str); <br />&nbsp;&nbsp;&nbsp; for ($i = 0; $i &lt; strlen($str); $i++,$i++) { <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $code = ord($str{$i}) * 256 + ord($str{$i + 1}); <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ($code &lt; 128) { <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $output .= chr($code); <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if ($code != 65279) { <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $output .= &quot;&amp;#&quot;.$code.&quot;;&quot;; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br />&nbsp;&nbsp;&nbsp; } <br />&nbsp;&nbsp;&nbsp; return $output; <br />} <br />?&gt; </p>
</div>
<p>函数的参数中，$encode是源字符集，$str是需要进行转化的字符串。返回结果是转化以后字符串。</p>
<div>
<p>CFM程序版本函数：<br />&lt;cfscript&gt;<br />function nochaoscode(str) {<br />&nbsp;var new_str = &quot;&quot;;<br />&nbsp;for(i=1; i lte len(str);i=i+1) {<br />&nbsp;&nbsp;if(asc(mid(str,i,1)) lt 128) {<br />&nbsp;&nbsp;new_str = new_str &amp; mid(str,i,1);<br />&nbsp;&nbsp;}else{<br />&nbsp;&nbsp;new_str = new_str &amp; &quot;&amp;##&quot; &amp; asc(mid(str,i,1));<br />&nbsp;&nbsp;}<br />&nbsp;}<br />return new_str;<br />}<br />&lt;/cfscript&gt;</p>
</div>]]></description><pubDate>Thu, 11 Jan 2007 14:15:45 GMT</pubDate></item><item><title><![CDATA[trackback的原理与实现 trackback扫盲]]></title><link>http://blog.chinayes.com:80/UserBlog/Article_Details,28.htm</link> <description><![CDATA[[一]通俗的介绍&nbsp; <br />Trackback大部分人刚接触到肯定会觉得很迷惑，不知道怎么用。其实它也没有那么神秘，以下介绍一下我对Trackback的理解。&nbsp; <br />简单说trackback是一个点对点通信和网站间互相通告的框架。这句话也讲不明白.&nbsp; <br />那就拿实例来说:&nbsp; <br />]]></description><pubDate>Thu, 11 Jan 2007 14:21:00 GMT</pubDate></item><item><title><![CDATA[袁崇焕之死与“民心可用”]]></title><link>http://blog.chinayes.com:80/UserBlog/Article_Details,37.htm</link> <description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 最近看了&lt;百家讲坛&gt;阎崇年的讲座,略有感想特记如下:<br />&nbsp;&nbsp;&nbsp;&nbsp; 明末时期的兵部尚书兼蓟辽督师袁崇焕,（他的官衔相当于如今的国防部长兼沈阳军区司令），他带兵打仗很厉害.著名的宁远大捷、宁锦大捷、还有后来的北京保卫战都是在他亲自己率领下获得的。<br />&nbsp;&nbsp;&nbsp; 但是，在北京保卫战时，明崇祯皇帝中了皇太极的反间计，把这位英勇善战的袁崇焕捉拿入狱。<br />&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp; 皇太极退兵以后，北京解围，袁崇焕被崇祯帝判为&ldquo;寸磔&rdquo;处死，&ldquo;寸磔&rdquo;也叫凌迟，这大概可算是中国最残酷的刑罚之一。&ldquo;寸磔&rdquo;在民间称千刀万剐，是一刀一刀地行刑，据说整个行刑过程甚至可以长达数天。不过袁崇焕的死没有用那么长时间，因为他最后被北京城的老百姓活吃了。正史只是一句&ldquo;遂磔崇焕于市&rdquo;轻轻带过。在野史里却有这样的记录：<br />&nbsp;&nbsp; &ldquo;遂于镇抚司绑发西市，寸寸脔割之。割肉一块，京师百姓从刽子手争取生啖之 。刽子乱扑，百姓以钱争买其肉，顷刻立尽。开腔出其肠胃，百姓群起抢之，得其一节者， 和烧酒生啮，血流齿颊间，犹唾地骂不已。拾得其骨者，以刀斧碎磔之，骨肉俱尽，止剩一首，传视九边。&rdquo;
<p style="FONT-SIZE: 12pt">&mdash;&mdash;&mdash;这段文字写出了当时北京老百姓对袁崇焕的恨！</p>
<p style="FONT-SIZE: 12pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;为什么老百姓这样恨这位英勇善战的将军呢？</p>
<p style="FONT-SIZE: 12pt"><br />&nbsp;&nbsp;&nbsp; 崇祯皇上说，袁崇焕暗中通敌，把满清八旗兵引到北京，使一百多年没有战争的北京遭到战火的摧残！这太让人们恨之入骨了。人们不可能也不愿去了解真相，排山倒海般的怨恨一下子冲向这位袁督师，所以就有了在行刑时吃他的肉啃他骨头的景象！</p>
<p style="FONT-SIZE: 12pt">&nbsp;&nbsp;&nbsp; 关于袁崇焕的死因，梁启超和金庸都作过很好的分析，特别是金庸，除了当时的政治气候外，他还提及了袁崇焕和崇祯帝朱由检两人之间的性格冲突。<br />&nbsp;&nbsp;&nbsp; 阎崇年也说:崇祯的刚愎自用与袁崇焕的孤迂耿僻正是一对矛盾.<br />&nbsp;&nbsp;&nbsp; 崇祯在位十七年间，换了五十个大学士，十四个兵部尚书，杀死或逼得自杀的督师或总督有十一人，杀死巡抚十一人。他个人性格上的缺陷，却也暴露无疑。 　 </p>
<p style="FONT-SIZE: 12pt">&nbsp;&nbsp;&nbsp; 崇祯杀袁崇焕不仅是中了皇太极的反间计，也是他本身性格所决定，更是他政治上的需要&mdash;&mdash;&mdash;&mdash;他本夸下海口要中兴大明的，可是不仅没有中兴反而让满清八旗兵打到了皇城根！我一国之君怎么向老百姓交待？杀了袁崇焕，百姓就把满腔怨恨转向这位负责国家安全的兵部尚书（国防部长）！这就证明了&ldquo;圣上英明&rdquo;，为民除害！</p>
<p style="FONT-SIZE: 12pt">&nbsp;&nbsp;&nbsp;&nbsp; 由此可见，有时候不明真相的民众是很可怕的，那种愚蛮可以被任何人利用。而自古以来，许多政治家是很善于利用民众的这种盲目的情绪的。</p>
<p style="FONT-SIZE: 12pt">&nbsp;&nbsp;&nbsp; 东汉末年张角造反的时候，说过一段很有名的话，&ldquo;至难得者，民心也。今民心已顺，若不乘势取天下，诚为可惜。&rdquo;张角是个想当皇帝的人，他牢牢记得&ldquo;民心可用&rdquo;这四个字。但所谓民心，是大势所趋，这个势的核心正是利。<br />&nbsp;&nbsp; 许多所谓的革命之所以成功，很大程度上是因为许多民众得到了现实的好处，虽然他们得到的关于将来的种种许诺以后大都未能实现。也正是因为利之所趋，仁义道德所塑造的民心显得那么不可靠，以至于它随时有反噬的可能性。 </p>
<p style="FONT-SIZE: 12pt"><br />&nbsp;&nbsp;&nbsp; 同是在明代，面对杨涟左光斗，面对袁崇焕，民众作出了完全不同的两种回答，避害趋利作为一种本能再次得到了体现。鲁迅在中所记录的那种民众的麻木，还有代表真理的人与民众的隔离以及不被后者所理解的状况，在这里都反映了出来。一个比较残酷的解释是，北京城的民众给予左光斗和杨涟的是事不关己的廉价同情，一旦涉及到自身利益的时候，他们甚至蒙蔽到可以把自己的守护者生吞活剥。 </p>
<p style="FONT-SIZE: 12pt">　　满清八旗兵打到北京，北京及北京周边的老百姓遭受到严重的洗劫烧掠。金口玉牙的皇上说袁崇焕是汉奸，说这位负责保卫国家安全的兵部尚书不仅没有保卫国家反而通敌引狼入室！想想看，老百姓该岂能不对袁崇焕恨之入骨？！<br />&nbsp;&nbsp;&nbsp; 崇祯皇帝治国再无能也是个政治家，任何政治家没有不会利用群众的，&ldquo;人民&rdquo;是任何政治家嘴上常用词。&mdash;&mdash;&mdash;当然，有人是真的为人民，更多的只是拿&ldquo;人民&rdquo;当旗帜当晃子！可怕的是人民很难了解真相！</p>]]></description><pubDate>Thu, 11 Jan 2007 14:58:13 GMT</pubDate></item><item><title><![CDATA[CSS知识小结]]></title><link>http://blog.chinayes.com:80/UserBlog/Article_Details,38.htm</link> <description><![CDATA[Cascading Style Sheets（简称CSS），翻译为&ldquo;层叠样式单&rdquo;或&ldquo;级联样式单&rdquo;，又简称&ldquo;样式表&rdquo;。<br /><br />CSS的引入是用来扩展HTML的，而不是用来替代HTML的。也就是说CSS离不开HTML，它只是一项辅助工具，是对HTML功能的一种补充。<br /><br /><strong>CSS的优势</strong><br /><br />在CSS标准里，不仅重新定义了HTML原有的样式，如文字的大小、颜色等；更加入了重叠文字、区块变化及任意位置放置等多项新属性。通过CSS可以使用更丰富、更灵活的样式，更简单地设计出更美观的网页。同时，也让网页的设计与维护更有效率。<br /><br />减少图像文件的使用：很多网页为求设计效果，而大量使用图像，以致网页的下载速度变慢。CSS提供了很多文字样式的设定，且再加上IE内建的滤镜特效，因此可轻松取代原来图像才能表现的视觉效果。这样的设计方式让修改网页内容变得更方便，也大大提高了下载速度；<br /><br />集中管理样式信息：CSS的基本概念在于可将网页要展示的内容与其表现的样式设定分开，也就是将网页的外观设定信息从网页的内容中独立出来，并集中管理。这样，当要改变网页外观时，只需更改样式设定的部分，HTML文件本身并不需要任何的更改；<br /><br />共享样式设定：网页的样式设定和内容分离的好处，除了可集中管理外，如果进一步将CSS样式的信息存储成独立的文件，还可让多个网页文件共同使用它。这样，可省却在每一个网页文件中都要重复设定样式的麻烦；<br /><br />将样式分类使用：相对于多份HTML文件可套用同一个CSS样式文件，也可以在一份HTML网页文件上套用多个CSS样式文件。<br /><br /><strong>CSS的规则</strong><br /><br />CSS的样式规则由两部分组成：选择器和声明。<br /><br />选择器就是样式的名称，包括自定义的类，HTML标签和CSS选择器样式。比如&ldquo;.mycss&rdquo;为自定义的类，&ldquo;td&rdquo;为标准HTML标签，而&ldquo;a:link&rdquo;则是CSS选择器样式；<br /><br />声明则是用于定义样式元素的。声明由分两部分：属性（如font-size）和值（如12px）。对于一个选择器而言，可以有多个声明。比如一个声明是表示颜色，一个声明是表示大小等。<br /><br />以下为CSS样式的代码片段：<br /><br />
<table cellspacing="1" width="100%" bgcolor="#cccccc" border="0">
    <tbody>
        <tr>
            <td bgcolor="#efefef"><br />td {<br />&nbsp;&nbsp;&nbsp;&nbsp;font-size: 12px;<br />&nbsp;&nbsp;&nbsp;&nbsp;color: #666666;<br />}<br />.cnbruce {<br />&nbsp;&nbsp;&nbsp;&nbsp;background-color: #000033;<br />}<br /><br /></td>
        </tr>
    </tbody>
</table>
<br />其中&ldquo;td&rdquo;和&ldquo;.cnbruce&rdquo;都属于选择器，&ldquo;font-size&rdquo;、&ldquo;color&rdquo;以及&ldquo;background-color&rdquo;都属于声明中的属性，而&ldquo;12px&rdquo;、&ldquo;#666666&rdquo;及&ldquo;#000033&rdquo;即为属性对应的值。每个选择器的声明都采用{&hellip;}包含。<br /><br /><strong>CSS的形式</strong><br /><br />从CSS代码的标签形式来看，分如下3种CSS样式：<br /><br />1，自定义CSS样式，又称类样式。可应用于任何标签，名称必须带有句点&ldquo;.&rdquo;，比如&ldquo;.cnbruce&rdquo;；<br /><br />2，HTML标签样式。虽说自定义CSS样式可应用任何标签，但对于HTML固有的标签，每次都要选用自定义的样式就显得比较麻烦。所以HTML标签样式的出现就是为了扩展HTML标签的；<br /><br />3，CSS选择器样式。此为高级选项，可用来定义标签的组合，比如&ldquo;a&rdquo;表示对超级链接样式的选择，&ldquo;td&rdquo;表示对单元格样式的选择，而如果对单元格中超级链接样式的选择则使用&ldquo;td a&rdquo;。<br /><br />
<table cellspacing="1" width="100%" bgcolor="#cccccc" border="0">
    <tbody>
        <tr>
            <td bgcolor="#efefef">a {<br />&nbsp;&nbsp;&nbsp;&nbsp;color: #3366CC;<br />}<br />td a{<br />&nbsp;&nbsp;&nbsp;&nbsp;color: #FF0000;<br />}<br /></td>
        </tr>
    </tbody>
</table>
<br />如上代码的定义，对于普通插入的超级链接的颜色，和在单元格中使用的超级链接的颜色，将进行不同的显示。<br /><br /><strong>CSS的应用范围</strong><br /><br />CSS无处不在，它可以分为以下两种。<br /><br />外部CSS样式表：以扩展名为.css的文件而存在，文件中内容即是所有样式的选择和声明。该文件可做为共享文件，让多个文档共同引用并应用，达到站点文件样式的一致性。同时，如果修改该样式表文件，所有引用的文档都将改变其样式，达到网站迅速改版的目的。<br /><br />内部CSS样式表：只存在于当前文档中，并只针对当前页进行样式应用的方法。一般存在于文档head部分的style标签内。<br /><br />外部CSS样式表和内部CSS样式表可同时作用于一个页面，但当两种样式表出现对同一选择对象进行样式修饰时，浏览器将按照如下规则来应用样式效果：<br /><br />若两者所声明的属性不相冲突，则显示为该两种样式的全部属性；<br />若两者所声明的属性直接相冲突，则采用内部样式表的样式。<br />所谓&ldquo;求同存异，内部优先&rdquo;。<br />]]></description><pubDate>Thu, 11 Jan 2007 15:40:33 GMT</pubDate></item><item><title><![CDATA[XHTML+CSS布局之XHTML应用小结]]></title><link>http://blog.chinayes.com:80/UserBlog/Article_Details,39.htm</link> <description><![CDATA[笼统来说，&ldquo;标准网页&rdquo;的文件组织就是XHTML+CSS。其中XHTML主要用来表示网页结构和显示内容，而CSS则是定义结构布局和修饰内容样式。<br /><br />常用于布局的XHTML一般有：<br /><br /><font size="3"><strong>DIV：</strong></font>主要用于页面内容逻辑上的分块，比如一张网页一般包括头部、导航、侧栏、内容和版权等责任分区。此时即可使用DIV标签分割。<br /><br />同时对各区块建议这样的命名：<br /><br />
<table cellspacing="1" width="100%" bgcolor="#cccccc" border="0">
    <tbody>
        <tr>
            <td bgcolor="#efefef"><br />头部：&lt;div id=&quot;masthead&quot;&gt;&lt;/div&gt;<br />导航：&lt;div id=&quot;globalnav&quot;&gt;&lt;/div&gt;<br />侧栏：&lt;div id=&quot;navbar&quot;&gt;&lt;/div&gt;<br />内容：&lt;div id=&quot;content&quot;&gt;&lt;/div&gt;<br />版权：&lt;div id=&quot;copyright&quot;&gt;&lt;/div&gt;<br /><br /></td>
        </tr>
    </tbody>
</table>
<br /><em>注：id具有唯一性，即在同一页面中不得重复出现该ID两次以上。否则使用class。</em><br /><br /><font size="3"><strong>ul：</strong></font>其原本是无序列表，在XHTML+CSS的应用中常用来表示非结构类的同等元素。需要和UL的子元素LI配合使用。<br /><br />
<table cellspacing="1" width="100%" bgcolor="#cccccc" border="0">
    <tbody>
        <tr>
            <td bgcolor="#efefef"><br />&lt;div&gt;<br />&lt;ul&gt;<br />&lt;li&gt;&lt;a href=&quot;#&quot;&gt;Link1&lt;/a&gt;&lt;/li&gt;<br />&lt;li&gt;&lt;a href=&quot;#&quot;&gt;Link2&lt;/a&gt;&lt;/li&gt;<br />&lt;li&gt;&lt;a href=&quot;#&quot;&gt;Link3&lt;/a&gt;&lt;/li&gt;<br />&lt;/ul&gt;<br />&lt;/div&gt;<br /><br /></td>
        </tr>
    </tbody>
</table>
<br /><em>注：与ul同类的还有ol、ul，使用情况较少，详细参看</em><br /><a class="blog_content" href="http://www.cnbruce.com/blog/showlog.asp?cat_id=5&amp;log_id=866" target="_blank">http://www.cnbruce.com/blog/showlog.asp?cat_id=5&amp;log_id=866</a> <br /><br /><font size="3"><strong>span：</strong></font>如果拿这个元素和DIV进行比较，那么span是个袋子而div则是个箱子（语出<a class="blog_content" href="http://andymao.com/andy/post/62.html" target="_blank">小毅：XHTML代码的基本应用</a>）。其实div是个块级元素，而span是个行内元素（参见<a class="blog_content" href="http://www.cnbruce.com/blog/showlog.asp?cat_id=5&amp;log_id=1017" target="_blank">有关内联（行内）元素、块级元素</a>），通过span就可对一段或一行元素集中的某片断元素进行单独定义。<br /><br />比如：<br /><br />
<table cellspacing="1" width="100%" bgcolor="#cccccc" border="0">
    <tbody>
        <tr>
            <td bgcolor="#efefef"><br />&lt;ul&gt;<br />&lt;li&gt;&lt;span&gt;(2006-11-13)&lt;/span&gt;XHML+CSS布局之XHTML应用小结&lt;/li&gt;<br />&lt;/ul&gt;<br /><br /></td>
        </tr>
    </tbody>
</table>
<br />在css中定义span为左/右浮动，就能实现日期和标题的分两侧显示。这相对使用<br /><br />
<table cellspacing="1" width="100%" bgcolor="#cccccc" border="0">
    <tbody>
        <tr>
            <td bgcolor="#efefef"><br />&lt;ul&gt;<br />&lt;li&gt;2006-11-13&lt;/li&gt;<br />&lt;li&gt;XHML+CSS布局小结&lt;/li&gt;<br />&lt;/ul&gt;<br /><br /></td>
        </tr>
    </tbody>
</table>
<br />要简单得多。<br /><br />=======================================<br /><br />在说完了常见的用于布局的XHTML标签后，还有的XHTML标签则是用来显示网页内容的。比如：<br /><br />&lt;img src=&quot;&quot; alt=&quot;&quot; title=&quot;&quot; /&gt;表示图像<br /><br />&lt;a href=&quot;&quot; title=&quot;&quot;&gt;&lt;/a&gt;表示超级链接<br /><br />&lt;hn&gt;&lt;/hn&gt;(n=1,2,...,6)表示页内容标题<br />其中建议h1-h6根据重要性依次递减，h1为最重要的标题（参见<a class="blog_content" href="http://www.jluvip.com/blog/article.asp?id=40" target="_blank">greengnn：div+css命名参考</a>）<br /><br />原本使用&lt;b&gt;&lt;/b&gt;和&lt;i&gt;&lt;/i&gt;表示粗体和斜体的标签，选择使用&lt;strong&gt;&lt;/strong&gt;和&lt;em&gt;&lt;/em&gt;代替。<br /><br />其他更多的有关中文排版CSS心得参看：<br /><a class="blog_content" href="http://www.cnbruce.com/blog/showlog.asp?cat_id=5&amp;log_id=975" target="_blank">http://www.cnbruce.com/blog/showlog.asp?cat_id=5&amp;log_id=975</a> <br /><br />XHTML中推荐和不推荐的内容标签：<br /><a class="blog_content" href="http://www.cnbruce.com/blog/showlog.asp?cat_id=5&amp;log_id=864" target="_blank">http://www.cnbruce.com/blog/showlog.asp?cat_id=5&amp;log_id=864</a> <br />]]></description><pubDate>Thu, 11 Jan 2007 15:44:56 GMT</pubDate></item><item><title><![CDATA[trackback的原理与实现 trackback扫盲]]></title><link>http://blog.chinayes.com:80/UserBlog/Article_Details,41.htm</link> <description><![CDATA[[一]通俗的介绍&nbsp; <br />Trackback大部分人刚接触到肯定会觉得很迷惑，不知道怎么用。其实它也没有那么神秘，以下介绍一下我对Trackback的理解。&nbsp; <br />简单说trackback是一个点对点通信和网站间互相通告的框架。这句话也讲不明白.&nbsp; <br />那就拿实例来说:&nbsp; <br /><br />A在他的博客A.com上写了一篇文章&nbsp;支持Trackback&nbsp;引用地址为:http://a.com/trackback.php?id=1&nbsp; <br />B想写一篇文章回复A,惯用方法是我在A文章的下面写评论,但是Trackback带来了新的革命:B可以把文章写在自己的blog上,而同时又能在A的文章下面显示B这篇文章的部分内容。 <br /><br />这就是利用了Trackback,那么A想要看别人评论的全文就要到B的网站上去，这样就带来了网站之间的互通,这才是Blog的精髓。虽然在国内大部分还习惯用comment的方式。&nbsp; <br />Trackback与comment不同的地方在于,你可以更好的控制自己的文章,按规定当你在你网站修改文章的时候,A网站上的你的内容同步改动.甚至删除&nbsp; <br /><br />[二]trackback的使用方法&nbsp; <br />也很简单,一般A发表的文章下面会有类似这样的引用地址:&nbsp; <br /><br /><br />引用通告地址:&nbsp; <br />GB2312&nbsp;http://www.znzt.net/blog/trackback.php?id=86&amp;encode=gb2312&nbsp; <br />UTF-8&nbsp;http://www.znzt.net/blog/trackback.php?id=86&amp;encode=utf-8&nbsp; <br /><br /><br />那么B在发表文章的时候有个地方填写trackback地址的,如果我想引用gb2312的那么把http://www.znzt.net/blog/trackback.php?id=86&amp;encode=gb2312这个地址拷贝填写进去,然后发表日志,那么A网站将会出现你日志的内容。同样当你修改文章的时候，A网站上你的内容也会随着更改。&nbsp; <br /><br />[三]更深入研究,程序之间互通方式&nbsp; <br />这个就是trackback的技术规范了&nbsp;简单的说就是发送的时候假造了一个POST方式的HTTP&nbsp;Request&nbsp;其中含有title/excerpt/url/blog_name&nbsp;除url以为均为可选&nbsp;而Content-Type信息为application/x-www-form-URLencoded&nbsp;charset信息是以上四部分所使用的编码.&nbsp;最后形成类似这么一段HTTP请求发送出去:&nbsp; <br /><br />
<div style="PADDING-RIGHT: 8px; PADDING-LEFT: 8px; FONT-SIZE: 12px; PADDING-BOTTOM: 8px; MARGIN: 10px; BORDER-LEFT: #cccccc 5px solid; WIDTH: 90%; PADDING-TOP: 8px; FONT-FAMILY: Courier New">代码:<br />POST&nbsp;/blog/trackback.php?id=181&amp;encode=gb2312&nbsp;HTTP/1.1&nbsp; <br />Host:&nbsp;127.0.0.1&nbsp; <br />Connection:&nbsp;close&nbsp; <br />Content-Length:&nbsp;165&nbsp; <br />Content-Type:&nbsp;application/x-www-form-urlencoded;&nbsp;charset=iso-8859-1&nbsp; <br />title=test%20trackback&amp;url=http%3A%2F%2F127.0.0.1%2Fcblog2%2Findex.php%3Fid%3D183&amp;excerpt=hello%2Cthis%20is%20a%&nbsp; <br /><br />20trackback%20test%21&amp;blog_name=Coolsky%27%27s%20Blog&nbsp; <br /></div>
&nbsp; <br />注意发送的内容必须经过URL编码后发送，否则中文就会显示错误&nbsp; <br />对方服务器收到请求后,将会发送一段XML格式的应答&nbsp;很简单&nbsp;没错的话&lt;error&gt;字段是0&nbsp;否则是1&nbsp;并附带一段&lt;message&gt;来说明错误信息.&nbsp; <br />类似这样:&nbsp; <br />成功的应答:&nbsp; <br />
<div style="PADDING-RIGHT: 8px; PADDING-LEFT: 8px; FONT-SIZE: 12px; PADDING-BOTTOM: 8px; MARGIN: 10px; BORDER-LEFT: #cccccc 5px solid; WIDTH: 90%; PADDING-TOP: 8px; FONT-FAMILY: Courier New">代码:<br />&nbsp; <br />&lt;?xml&nbsp;version=&quot;1.0&Prime;&nbsp;encoding=&quot;utf-8&Prime;?&gt;&nbsp; <br />&lt;response&gt;&nbsp; <br />&lt;error&gt;0&lt;/error&gt;&nbsp; <br />&lt;/response&gt;&nbsp; <br /></div>
<br /><br />失败的应答:&nbsp; <br /><br />
<div style="PADDING-RIGHT: 8px; PADDING-LEFT: 8px; FONT-SIZE: 12px; PADDING-BOTTOM: 8px; MARGIN: 10px; BORDER-LEFT: #cccccc 5px solid; WIDTH: 90%; PADDING-TOP: 8px; FONT-FAMILY: Courier New">代码:<br />&lt;?xml&nbsp;version=&quot;1.0&Prime;&nbsp;encoding=&quot;utf-8&Prime;?&gt;&nbsp; <br />&lt;response&gt;&nbsp; <br />&lt;error&gt;1&lt;/error&gt;&nbsp; <br />&lt;message&gt;The&nbsp;error&nbsp;message&lt;/message&gt;&nbsp; <br />&lt;/response&gt;&nbsp; <br /></div>
<br /><br />同时发送成功的话，您发送的所有内容将会被对方记入数据库。如此就显示在对方网站上了&nbsp; <br /><br />[三]PHP中Trackback的具体实现&nbsp; <br />1.发送Trackback&nbsp; <br />当你发表文章的时候填写了trackback地址，提交以后，程序就会自动发送一个构造的POST方式的HTTP&nbsp;Request&nbsp; <br />笔者以本站程序为例:&nbsp; <br />我定义一个发送程序:&nbsp; <br /><br /><br />
<div style="PADDING-RIGHT: 8px; PADDING-LEFT: 8px; FONT-SIZE: 12px; PADDING-BOTTOM: 8px; MARGIN: 10px; BORDER-LEFT: #cccccc 5px solid; WIDTH: 90%; PADDING-TOP: 8px; FONT-FAMILY: Courier New">代码:<br /><br />function&nbsp;sendTrackback($host,$title,$url,$excerpt,$blog_name)&nbsp;{&nbsp; <br />$buf=&quot;&quot;;&nbsp; <br />$host&nbsp;=&nbsp;str_replace('http://',&nbsp;'',&nbsp;$host);&nbsp; <br />$path&nbsp;=&nbsp;explode('/',&nbsp;$host);&nbsp; <br />$host&nbsp;=&nbsp;$path[0];&nbsp; <br />unset($path[0]);&nbsp; <br />$path&nbsp;=&nbsp;'/'&nbsp;.&nbsp;implode('/',&nbsp;$path);&nbsp; <br />$excerpt&nbsp;=&nbsp;cn_substr($excerpt,252);&nbsp; <br />$fp&nbsp;=&nbsp;@fsockopen($host,&nbsp;80,&nbsp;$errno,&nbsp;$errstr,&nbsp;30);&nbsp; <br />if(!$fp)&nbsp;{&nbsp; <br />Return&nbsp;flase;&nbsp; <br />}&nbsp; <br />$blog_name=str_replace(&quot;'&quot;,&nbsp;&quot;''&quot;,&nbsp;$blog_name);;&nbsp; <br />$query&nbsp;=&nbsp;'title='&nbsp;.&nbsp;rawurlencode($title);&nbsp; <br />$query&nbsp;.=&nbsp;'&amp;url='&nbsp;.&nbsp;rawurlencode($url);&nbsp; <br />$query&nbsp;.=&nbsp;'&amp;excerpt='&nbsp;.&nbsp;rawurlencode($excerpt);&nbsp; <br />$query&nbsp;.=&nbsp;'&amp;blog_name='&nbsp;.&nbsp;rawurlencode($blog_name);&nbsp; <br /><br />$out&nbsp;=&nbsp;'POST&nbsp;'&nbsp;.&nbsp;$path&nbsp;.&nbsp;'&nbsp;HTTP/1.1'&nbsp;.&nbsp;&quot;\r\n&quot;;&nbsp; <br />$out&nbsp;.=&nbsp;'Host:&nbsp;'&nbsp;.&nbsp;$host&nbsp;.&nbsp;&quot;\r\n&quot;;&nbsp; <br />$out&nbsp;.=&nbsp;'Connection:&nbsp;close'&nbsp;.&nbsp;&quot;\r\n&quot;;&nbsp; <br />$out&nbsp;.=&nbsp;'Content-Length:&nbsp;'&nbsp;.&nbsp;strlen($query)&nbsp;.&nbsp;&quot;\r\n&quot;;&nbsp; <br />$out&nbsp;.=&nbsp;'Content-Type:&nbsp;application/x-www-form-urlencoded;&nbsp;charset=iso-8859-1'&nbsp;.&nbsp;&quot;\r\n\r\n&quot;;&nbsp; <br />$out&nbsp;.=&nbsp;$query&nbsp;.&nbsp;&quot;\r\n&quot;;&nbsp; <br />fwrite($fp,&nbsp;$out);&nbsp; <br />while&nbsp;(!feof($fp))&nbsp; <br />$buf&nbsp;.=&nbsp;fgets($fp,128);&nbsp; <br />fclose($fp);&nbsp; <br />$arr=explode(&quot;&lt;error&gt;&quot;,$buf);&nbsp; <br />$return_num=intval(substr($arr[1],&nbsp;1,&nbsp;0));&nbsp; <br />if($return_num==0){&nbsp; <br />return&nbsp;true;&nbsp; <br />}else{&nbsp; <br />$arr2=explode(&quot;message&quot;,$buf);&nbsp; <br />$return_msg=str_replace(&quot;&gt;&quot;,&nbsp;&quot;&quot;,&nbsp;$arr2[1]);&nbsp; <br />$return_msg=str_replace(&quot;&lt;/&quot;,&nbsp;&quot;&quot;,&nbsp;$return_msg);&nbsp; <br />admin_info(&quot;日志添加成功&lt;br&gt;Trackback&nbsp;发送失败,服务器返回信息:$return_msg&quot;,&quot;main.php?&nbsp; <br /><br />do=blogManager&quot;);&nbsp; <br />}&nbsp; <br />}&nbsp; <br /></div>
<br /><br />函数介绍:&nbsp; <br />本函数通过trackback的规范规定的5个参数,标题,主机,引用地址,我发表的内容,我的站点名称&nbsp;函数首先通过字符串处理得到主机&nbsp; <br /><br />ip或域名,然后通过fsockopen()函数打开socket连接,这个函数的使用方法类似fopen()打开连接成功后，把处理完的模拟POST表单的&nbsp; <br /><br />HTTP&nbsp;REQUEST数据$out&nbsp;发送给对方，通过fwrite()实现。&nbsp; <br />发送完后我们用fgets()函数获得服务器返回值,然后存到$buf这个变量之中，然后对返回值进行处理,如果返回含有&nbsp; <br /><br />&lt;error&gt;0&lt;/error&gt;则发送成功并接受成功,如果返回含有&lt;error&gt;1&lt;/error&gt;则接受失败，我们取出服务器返回错误信息&nbsp; <br /><br />&lt;message&gt;&lt;/message&gt;之间的内容，并输出错误提示。（其中admin_info()是我自定义的输出错误信息的函数,你可以用简单的echo输&nbsp; <br /><br />出错误信息）&nbsp; <br /><br />2.接收Trackback&nbsp; <br />我们用Trackback.php来实现接收。比发送更简单。&nbsp; <br />因为我们基于XML通讯，所以首先在PHP文件开头加上&nbsp; <br />header('Content-type:&nbsp;text/xml');&nbsp; <br />然后用一般处理表单提交的方法获得POST过来的五个参数&nbsp; <br />然后将这5个参数存入数据库,建立一个trackback表，包含五个参数的字段和自增ID就可以了,你还可以添加时间以记录&nbsp; <br />如果存入成功，那么设置$error=0,如果失败则设置$error=1;&nbsp; <br />并给出错误信息$msg='引用出现错误,可能数据库存在问题!';&nbsp; <br />然后输出页面给发送方获得&nbsp; <br /><br />
<div style="PADDING-RIGHT: 8px; PADDING-LEFT: 8px; FONT-SIZE: 12px; PADDING-BOTTOM: 8px; MARGIN: 10px; BORDER-LEFT: #cccccc 5px solid; WIDTH: 90%; PADDING-TOP: 8px; FONT-FAMILY: Courier New">代码:<br />echo&nbsp;'&lt;?xml&nbsp;version=&quot;1.0&quot;&nbsp;encoding=&quot;gb2312&quot;?&gt;';&nbsp; <br />if($error)&nbsp;{&nbsp; <br />echo&nbsp;'&lt;response&gt;&lt;error&gt;1&lt;/error&gt;&lt;message&gt;'.$msg.'&lt;/message&gt;&lt;/response&gt;';&nbsp; <br />}&nbsp;else&nbsp;{&nbsp; <br />echo&nbsp;'&lt;response&gt;&lt;error&gt;0&lt;/error&gt;&lt;/response&gt;';&nbsp; <br />}&nbsp; <br /></div>
<br />如此则完成Trackback全部发送接收过程！&nbsp; <br />ps:如果要判断对方是修改文章，还是第一次提交trackback要求,只需要判断自己的trackback表中是否已经存在该url，如果不存在则&nbsp; <br /><br />insert&nbsp;一条数据，如果已经存在则update这条数据&nbsp; <br />如果想进一步了解，可以参考程序代码！]]></description><pubDate>Thu, 11 Jan 2007 15:56:32 GMT</pubDate></item><item><title><![CDATA[任意字符集下正常显示网页]]></title><link>http://blog.chinayes.com:80/UserBlog/Article_Details,49.htm</link> <description><![CDATA[<p>通常情况下，我们的网页要指定一个编码字符集，如 GB2312、UTF-8、ISO-8859-1 等，这样我们就可以在网页上显示我们指定编码的文字了。但是我们很可能会遇到这种情况，那就是我们可能希望在 ISO-8859-1 编码的网页上显示汉字，或者在 GB2312 编码的网页上显示韩文等。当然一种解决办法就是我们不用 ISO-8859-1 或者 GB2312 编码，而统统都采用 UTF-8 编码，这样我们只要在这种编码下，就可以混合显示各国文字了，这是现在很多网站采用的方法。 <br /><br />而我这里所说的并非上面这种方法，因为上面这种方法必须要指定字符集为 UTF-8 才可以，一旦用户手工指定为其他字符集，或者可能因为某些原因，那个字符集设置没起作用，而浏览器又没有正确自动识别的话，我们看到的网页还是乱码，尤其是在某些用框架作的网页中，某个框架中的页面如果字符集设置没起作用，在 firefox 中显示乱码而且还没法改变（我是说在不装RightEncode插件的情况下）。 <br /><br />而我这里介绍的方法即使是把网页指定为 ISO-8859-1 字符集，也能够正确显示汉字、日文等。原理很简单，就是把除了 ISO-8859-1 编码中前128个字符以外的所有其他的编码都用 NCR(Numeric character reference) 来表示。比如&ldquo;汉字&rdquo;这两个字，如果我们写成&ldquo;&amp;#27721;&amp;#23383;&rdquo;这种形式，那么它在任意字符集下都可以正确显示。根据这个原理，我写了下面这个程序，它可以把现有的网页转化为在任意字符集下都能显示的网页。你只需要指定源网页的字符集和源网页，点提交按钮，就可以得到目标网页了。你也可以只转化某些文字，只需要把文字填写到文本框中，并指定这些文字原来的字符集，点提交按钮，就会在页面上面显示编码后的文字了。另外我还编写了 WordPress 的插件，现在我的 Blog 已经可以在任意字符集下都能正确显示了。 <br /><br />实现方法： <br /><br />首先第一步是要把源字符集的字符串转化为UTF-16字符集，做这一步是因为UTF-16字符集中的每个字符都是两个字节，后面处理起来很容易，而如果在源字符集上直接做处理则很复杂。源字符集可以从原网页中的meta标签中获得，也可以单独指定，我的程序是让用户在表单中指定源字符集，因为我不能保证用户提交的文件就一定是HTML文件（其他文件也是可以的，比如这个WordPress的汉化包源文件是个po文件，它里面的内容也可以这样处理），而且即使是HTML文件，里面也不一定就有用于指定字符集的meta标签，所以通过表单单独指定字符集比较保险。你可能会觉得将一种字符集转化为另一种字符集很复杂，确实如此，如果自己来实现的话，确实非常麻烦，但是用PHP来做却很容易，因为它里面已经包含这样的函数了，你可以通过iconv函数很容易的来实现各种字符集之间的转化，如果你的机器上没有安装iconv扩展，你也可以使用mb_convert_encoding函数，如果Multibyte String扩展也没有安装，那就没办法了，因为你要自己实现那么多种编码的转化基本上是不可能的，除非你是顶级大牛！推荐使用iconv，因为这个效率高，支持的字符集也更多。 <br /><br />做完上面那一步之后，接下来是以每两个字节为单位对字符串进行处理。这两个字节直接转化为数字就是&amp;#xxxxx;中的xxxxx，如果这个数字小于128就直接使用这个字符（注意这里就变成单字节了），否则就使用&amp;#xxxxx;的形式。这里有一点要注意，就是当这个数字是65279（16进制的0xFEFF）时，请把它忽略掉，因为这个是Unicode编码中的传输控制字符，而我们现在的字符串已经只有iso-8859-1编码中的前128个字符了，所以我们不需要它了。 <br /><br />好了，基本思路就是这样，下面是实现的程序： </p>
<div>
<p>PHP程序版本函数：<br />&lt;?php <br />function nochaoscode($encode, $str) { <br />&nbsp;&nbsp;&nbsp; $str = iconv($encode, &quot;UTF-16BE&quot;, $str); <br />&nbsp;&nbsp;&nbsp; for ($i = 0; $i &lt; strlen($str); $i++,$i++) { <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $code = ord($str{$i}) * 256 + ord($str{$i + 1}); <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ($code &lt; 128) { <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $output .= chr($code); <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if ($code != 65279) { <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $output .= &quot;&amp;#&quot;.$code.&quot;;&quot;; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br />&nbsp;&nbsp;&nbsp; } <br />&nbsp;&nbsp;&nbsp; return $output; <br />} <br />?&gt; </p>
</div>
<p>函数的参数中，$encode是源字符集，$str是需要进行转化的字符串。返回结果是转化以后字符串。</p>
<div>
<p>CFM程序版本函数：<br />&lt;cfscript&gt;<br />function nochaoscode(str) {<br />&nbsp;var new_str = &quot;&quot;;<br />&nbsp;for(i=1; i lte len(str);i=i+1) {<br />&nbsp;&nbsp;if(asc(mid(str,i,1)) lt 128) {<br />&nbsp;&nbsp;new_str = new_str &amp; mid(str,i,1);<br />&nbsp;&nbsp;}else{<br />&nbsp;&nbsp;new_str = new_str &amp; &quot;&amp;##&quot; &amp; asc(mid(str,i,1));<br />&nbsp;&nbsp;}<br />&nbsp;}<br />return new_str;<br />}<br />&lt;/cfscript&gt;</p>
</div>]]></description><pubDate>Thu, 11 Jan 2007 16:41:25 GMT</pubDate></item><item><title><![CDATA[用C#写组件]]></title><link>http://blog.chinayes.com:80/UserBlog/Article_Details,50.htm</link> <description><![CDATA[这一章关于用C#写组件。你学到如何写一个组件，如何编译它，且如何在一个客户程序中使用它。更深入一步是运用<br />名字空间来组织你的应用程序。<br /><br />这章由两个主要大节构成：<br />。你的第一个组件<br />。使用名字空间工作<br /><br /><strong>8.1 你的第一个组件 </strong><br /><br />到目前为止，在本书中提到的例子都是在同一个应用程序中直接使用一个类。类和它的使用者被包含在同一个执行文<br />件中。现在我们将把类和使用者分离到组件和客户，它们分别位于不同的二进制文件中（可执行文件）。<br />尽管你仍然为组件创建一个 DLL，但其步骤与用C++写一个COM组件差别很大。你很少涉及到底层结构。以下小节说明<br />了如何构建一个组件以及使用到它的客户：<br /><br />。构建组件<br />。编译组件<br />。创建一个简单的客户应用程序<br /><br /><strong>8.1.1 构建组件</strong><br /><br />因为我是一个使用范例迷，我决定创建一个相关Web的类，以方便你们使用。它返回一个Web网页并储存在一个字符串<br />变量中，以供后来重用。所有这些编写都参考了.NET框架的帮助文档。<br /><br />类名为RequestWebPage；它有两个构造函数&mdash;&mdash; 一个属性和一个方法。属性被命名为URL，且它储存了网页的Web地<br />址，由方法GetContent返回。这个方法为你做了所有的工作（见清单8.1）。<br /><br />清单 8.1 用于从Web服务器返回HTML网页的RequestWebPage 类<br /><br />
<table cellspacing="1" width="100%" bgcolor="#cccccc" border="0">
    <tbody>
        <tr>
            <td bgcolor="#efefef"><br />1: using System;<br />2: using System.Net;<br />3: using System.IO;<br />4: using System.Text;<br />5: <br />6: public class RequestWebPage<br />7: {<br />8: private const int BUFFER_SIZE = 128;<br />9: private string m_strURL;<br />10: <br />11: public RequestWebPage()<br />12: {<br />13: }<br />14: <br />15: public RequestWebPage(string strURL)<br />16: {<br />17: m_strURL = strURL;<br />18: }<br />19: <br />20: public string URL<br />21: {<br />22: get { return m_strURL; }<br />23: set { m_strURL = value; }<br />24: }<br />25: public void GetContent(out string strContent)<br />26: {<br />27: // 检查 URL<br />28: if (m_strURL == &quot;&quot;)<br />29: throw new ArgumentException(&quot;URL must be provided.&quot;);<br />30: <br />31: WebRequest theRequest = (WebRequest) WebRequestFactory.Create(m_strURL);<br />32: WebResponse theResponse = theRequest.GetResponse();<br />33: <br />34: // 给回应设置字节缓冲区<br />35: int BytesRead = 0;<br />36: Byte[] Buffer = new Byte[BUFFER_SIZE];<br />37: <br />38: Stream ResponseStream = theResponse.GetResponseStream();<br />39: BytesRead = ResponseStream.Read(Buffer, 0, BUFFER_SIZE);<br />40: <br />41: //使用 StringBuilder 以加速分配过程<br />42: StringBuilder strResponse = new StringBuilder(&quot;&quot;);<br />43: while (BytesRead != 0 ) <br />44: {<br />45: strResponse.Append(Encoding.ASCII.GetString(Buffer,0,BytesRead));<br />46: BytesRead = ResponseStream.Read(Buffer, 0, BUFFER_SIZE);<br />47: }<br />48: <br />49: // 赋给输出参数<br />50: strContent = strResponse.ToString();<br />51: }<br />52: }<br /><br /></td>
        </tr>
    </tbody>
</table>
<br /><br />本应该利用无参数构造函数完成工作，但我决定在构造函数中初始化URL，这可能会很有用。当后来决定要改变URL<br />时&mdash;&mdash;为了返回第二个网页，例如，通过URL属性的get和set访问标志使它被公开了。<br /><br />有趣的事始于GetContent方法。首先，代码对URL实行十分简单的检查，如果它不适合，就会引发一个<br />ArgumentException 异常。之后，我请求WebRequestFactory ，以创建一个基于传递给它的URL的WebRequest对象。<br />因为我不想发送cookies、附加头和询问串等，所以立即访问WebResponse（第32行）。如果你需要请求上述任何的功<br />能，必须在这一行之前实现它们。<br /><br />第35和36行初始化一个字节缓冲区，它用于从返回流中读数据。暂时忽略StringBuilder 类，只要返回流中仍然有要<br />读的数据，while循环就会简单地重复。最后的读操作将返回零，因此结束了该循环。<br />现在我想回到StringBuilder类。为什么用这个类的实例而不是简单地把字节缓冲区合并到一个字符串变量？看下面这<br />个例子：<br /><br />
<table cellspacing="1" width="100%" bgcolor="#cccccc" border="0">
    <tbody>
        <tr>
            <td bgcolor="#efefef">strMyString = strMyString + &quot;some more text&quot;; <br /></td>
        </tr>
    </tbody>
</table>
<br />这里很清楚，你正在拷贝值。常量 &quot;some more text&quot; 以一个字符串变量类型被加框，且根据加法操作创建了一个新<br />的字符串变量。接着被赋给了 strMyString。有很多次拷贝，是吗？<br />但你可能引起争论<br /><br />
<table cellspacing="1" width="100%" bgcolor="#cccccc" border="0">
    <tbody>
        <tr>
            <td bgcolor="#efefef">strMyString += &quot;some more text&quot;;<br /></td>
        </tr>
    </tbody>
</table>
<br />不要炫耀这种行为。对不起，对于C#这是一个错误的答案。其操作完全与所描述的赋值操作相同。<br /><br />不涉及该问题的另外的途径是使用StringBuilder类。它利用一个缓冲区进行工作，接着，在没有发生我所描述的拷贝<br />行为的情况下，你进行追加、插入、删除和替换操作。这就是为什么我在类中使用它来合并那些读自缓冲区中的内容。<br />该缓冲区把我带进了这个类中最后重要的代码片段&mdash;&mdash;第45行的编码转换。它只不过涉及到我获得请求的字符集。<br /><br />最后，当所有的内容被读入且被转换时，我显式地从 StringBuilder请求一个字符串对象并把它赋给了输出变量。一<br />个返回值仍然会导致另外的拷贝操作。<br /><br /><strong>8.1.2 编译组件</strong><br /><br />到目前为止，你所做的工作与在正常应用程序的内部编写一个类没有什么区别。所不同的是编译过程。你必须创建一<br />个库而不是一个应用程序：<br />csc /r:System.Net.dll /t:library /out:wrq.dll webrequest.cs<br />编译开关/t:library 告诉C#编译，要创建一个库而不是搜寻一个静态 Main方法。同样，因为我正在使用 <br />System.Net名字空间，所以必须引用 (/r:)它的库，这个库就是System.Net.dll。<br />你的库命名为 wrq.dll，现在它准备用于一个客户应用程序。因为在这章中我仅使用私有组件工作，所以你不必把库<br />拷贝到一个特殊的位置，而是拷贝到客户应用程序目录。<br /><br /><strong>8.1.3 创建一个简单的客户应用程序</strong><br /><br />当一个组件被写成且被成功地编译时，你所要做的就是在客户应用程序中使用它。我再次创建了一个简单的命令行应<br />用程序，它返回了我维护的一个开发站点的首页（见清单8.2）。<br /><br />清单 8.2 用 RequestWebPage 类返回一个简单的网页<br /><br />
<table cellspacing="1" width="100%" bgcolor="#cccccc" border="0">
    <tbody>
        <tr>
            <td bgcolor="#efefef"><br />1: using System;<br />2: <br />3: class TestWebReq<br />4: {<br />5: public static void Main()<br />6: {<br />7: RequestWebPage wrq = new RequestWebPage();<br />8: wrq.URL = &quot;http://www.alphasierrapapa.com/iisdev/&quot;;<br />9: <br />10: string strResult;<br />11: try<br />12: {<br />13: wrq.GetContent(out strResult);<br />14: }<br />15: catch (Exception e)<br />16: {<br />17: Console.WriteLine(e);<br />18: return;<br />19: }<br />20: <br />21: Console.WriteLine(strResult);<br />22: }<br /><br /></td>
        </tr>
    </tbody>
</table>
<br /><br />注意，我已经在一个try catch语句中包含了对 GetContent的调用。其中的一个原因是GetContent可能引发一个 <br />ArgumentException异常。此外，我在组件内部调用的.NET框架类也可以引发异常。因为我不能在类的内部处理这些异常，所以我必须在这里处理它们。<br /><br />其余的代码只不过是简单的组件使用&mdash;&mdash;调用标准的构造函数，存取一个属性，并执行一个方法。但等一下：你需要<br />注意何时编译应用程序。一定要告诉编译器，让它引用你的新组件库DLL：csc /r:wrq.dll wrclient.cs<br /><br />现在万事俱备，你可以测试程序了。输出结果会滚屏，但你可以看到应用程序工作。使用了常规的表达式，你也可以<br />增加代码，以解析返回的HTML，并依据你个人的喜好，提取信息。我预想会使用到这个类新版本的SSL（安全套接字层），用于ASP+网页中的在线信用卡验证。<br /><br />你可能会注意到，没有特殊的using 语句用于你所创建的库。原因是你在组件的源文件中没有定义名字空间。<br /><br /><strong>8.2 使用名字空间工作</strong><br /><br />你经常使用到名字空间，例如System 和System.Net。C#利用名字空间来组织程序，而且分层的组织使一个程序的成员<br />传到另一个程序变得更容易。<br /><br />尽管不强制，但你总要创建名字空间，以清楚地识别应用程序的层次。.NET框架会给出构建这种分层的良好思想。<br />以下的代码片段显示了在C#原文件中简单的名字空间 My.Test（点号表示一个分层等级）的声明：<br /><br />
<table cellspacing="1" width="100%" bgcolor="#cccccc" border="0">
    <tbody>
        <tr>
            <td bgcolor="#efefef"><br />namespace My.Test<br />{<br />//这里的任何东西属于名字空间<br />}<br /><br /></td>
        </tr>
    </tbody>
</table>
<br />当你访问名字空间中的一个成员时，也有必要使用名字空间标识符完全地验证它，或者利用using标志把所有的成员引<br />入到你当前的名字空间。本书前面的例子演示了如何应用这些技术。<br /><br />在开始使用名字空间之前，只有少数有关存取安全的词。如果你不增加一个特定的存取修饰符，所有的类型将被默认<br />为internal 。当你想从外部访问该类型时，使用 public 。不允许其它的修饰符。<br /><br />这是关于名字空间充分的理论。让我们继续实现该理论&mdash;&mdash;以下小节说明了当构建组件应用程序时，如何使用名字空<br />间<br />。在名字空间中包装类<br />。在客户应用程序中使用名字空间<br />。为名字空间增加多个类<br /><br /><strong>8.2.1 在名字空间中包装类</strong><br />既然你知道了名字空间的理论含义，那么让我们在现实生活中实现它吧。在这个和即将讨论到的例子中，自然选择到<br />的名字空间是Presenting.CSharp。为了不使你厌烦，仅仅是把RequestWebPage包装到Presenting.CSharp中，我决定写一个类，用于 Whois查找（见清单8.3）。<br /><br />清单 8.3 在名字空间中实现 WhoisLookup类<br /><br />
<table cellspacing="1" width="100%" bgcolor="#cccccc" border="0">
    <tbody>
        <tr>
            <td bgcolor="#efefef"><br />1: using System;<br />2: using System.Net.Sockets;<br />3: using System.IO;<br />4: using System.Text;<br />5: <br />6: namespace Presenting.CSharp<br />7: {<br />8: public class WhoisLookup <br />9: {<br />10: public static bool Query(string strDomain, out string strWhoisInfo)<br />11: {<br />12: const int BUFFER_SIZE = 128;<br />13: <br />14: if (&quot;&quot; == strDomain)<br />15: throw new ArgumentException(&quot;You must specify a domain name.&quot;);<br />16: <br />17: TCPClient tcpc = new TCPClient();<br />18: strWhoisInfo = &quot;N/A&quot;;<br />19: <br />20: // 企图连接 whois 服务器<br />21: if (tcpc.Connect(&quot;whois.networksolutions.com&quot;, 43) != 0)<br />22: return false;<br />23: <br />24: // 获取流<br />25: Stream s = tcpc.GetStream();<br />26: <br />27: // 发送请求<br />28: strDomain += &quot;\r\n&quot;;<br />29: Byte[] bDomArr = Encoding.ASCII.GetBytes(strDomain.ToCharArray());<br />30: s.Write(bDomArr, 0, strDomain.Length); <br />31: <br />32: Byte[] Buffer = new Byte[BUFFER_SIZE];<br />33: StringBuilder strWhoisResponse = new StringBuilder(&quot;&quot;);<br />34: <br />35: int BytesRead = s.Read(Buffer, 0, BUFFER_SIZE);<br />36: while (BytesRead != 0 ) <br />37: {<br />38: strWhoisResponse.Append(Encoding.ASCII.GetString(Buffer,0,BytesRead));<br />39: BytesRead = s.Read(Buffer, 0, BUFFER_SIZE);<br />40: }<br />41: <br />42: tcpc.Close();<br />43: strWhoisInfo = strWhoisResponse.ToString();<br />44: return true;<br />45: }<br />46: }<br />47: }<br /><br /></td>
        </tr>
    </tbody>
</table>
<br />名字空间在第6行被声明，而且它用第7行和第47行的大括弧括住了WhoisLookup类。要声明自己新的名字空间，实际要<br />做的就是这些。<br /><br />在WhoisLookup类中当然具有一些有趣代码，特别是由于它说明了使用C#进行socket编程是多么的容易。在static <br />Query method中经过 not-so-stellar域名检查之后，我实例化了TCPClient类型的一个对象，它用来完成具有 Whois服务器的43端口上的所有通讯。<br />在第21行建立了服务器连接：<br />if (tcpc.Connect(&quot;whois.networksolutions.com&quot;, 43) != 0)<br />因为连接失败是预料到的结果，所以这个方法不能引发一个异常。（你还记住异常处理的&ldquo;要&rdquo;和&ldquo;不要&rdquo;吗？） 返<br />回值是一个错误代码，而返回零则说明连接成功。<br /><br />对于 Whois 查找，我必须首先发出一些信息给服务器&mdash;&mdash;我要查找的域名。要完成此项工作，首先获得一个引用给当<br />前TCP连接的双向流（第25行）。接着附加上一个回车/换行对 给域名，以表示询问结束。重新以字节数组打包，向Whois 服务器发送一个请求（第30行）。<br /><br />余下的代码和RequestWebPage类极其相似。在该类中，我再次利用一个缓冲区从远程服务器读入回应。当缓冲区完成<br />读入后，连接被断开。返回的回应被转给了调用者。我明确地调用 Close 方法的原因是我不想等待垃圾收集器毁坏连接。<br /><br />连接时间不要过长，以免占用TCP端口这种稀有资源。<br /><br />在可以使用.NET 组件中的类之前，你必须把它作为一个库来编译。尽管现在有了一个已定义的名字空间，该编译命令<br />仍然没有变：csc /r:System.Net.dll /t:library /out:whois.dll whois.cs<br /><br />注意，如果你想该库按与C#源文件相同的方法命名，就没有必要规定 /out:开关。规定该开关是一个良好的习惯，因<br />为很多项目不会只由单个源文件组成。如果你规定了多个源文件，该库以名单中的第一个命名。<br /><br /><strong>8.2.2 在客户应用程序中使用名字空间</strong><br /><br />由于你使用了名字空间开发组件，所以客户也要引入名字空间<br />using Presenting.CSharp;<br />或者给名字空间中的成员使用完全资格名（fully qualified name)，例如<br />Presenting.CSharp.WhoisLookup.Query(...);<br /><br />如果你不期望在名字空间中引入的成员之间出现冲突，using 标志（ directive）是首选，特别是由于你具有很少的<br />类型时。使用组件的客户程序样本在清单8.4中给出。<br /><br />清单 8.4 测试 WhoisLookup 组件<br /><br />
<table cellspacing="1" width="100%" bgcolor="#cccccc" border="0">
    <tbody>
        <tr>
            <td bgcolor="#efefef"><br />1: using System;<br />2: using Presenting.CSharp;<br />3: <br />4: class TestWhois<br />5: {<br />6: public static void Main()<br />7: {<br />8: string strResult;<br />9: bool bReturnValue;<br />10: <br />11: try<br />12: {<br />13: bReturnValue = WhoisLookup.Query(&quot;microsoft.com&quot;, out strResult);<br />14: }<br />15: catch (Exception e)<br />16: {<br />17: Console.WriteLine(e);<br />18: return;<br />19: }<br />20: if (bReturnValue)<br />21: Console.WriteLine(strResult);<br />22: else<br />23: Console.WriteLine(&quot;Could not obtain information from server.&quot;);<br />24: }<br />25: }<br /><br /></td>
        </tr>
    </tbody>
</table>
<br />第2行利用using 标志引入了Presenting.CSharp名字空间。现在，我无论什么时候引用WhoisLookup ，都可以忽略名<br />字空间的完全资格名了。<br /><br />该程序对 microsoft.com 域进行一次Whois 查找&mdash;&mdash;你也可以用自己的域名代替microsoft.com 。允许命令行参数传<br />递域名，可使客户的用途更广。清单8.5 实现了该功能，但它不能实现适当的异常处理（为了使程序更短）。<br /><br />清单 8.5 传递命令行参数给Query 方法<br /><br />
<table cellspacing="1" width="100%" bgcolor="#cccccc" border="0">
    <tbody>
        <tr>
            <td bgcolor="#efefef"><br />1: using System;<br />2: using Presenting.CSharp;<br />3: <br />4: class WhoisShort<br />5: {<br />6: public static void Main(string[] args)<br />7: {<br />8: string strResult;<br />9: bool bReturnValue;<br />10: <br />11: bReturnValue = WhoisLookup.Query(args[0], out strResult);<br />12: <br />13: if (bReturnValue)<br />14: Console.WriteLine(strResult);<br />15: else<br />16: Console.WriteLine(&quot;Lookup failed.&quot;);<br />17: }<br />18: }<br /><br /></td>
        </tr>
    </tbody>
</table>
<br /><br />你所必须做的就是编译这个应用程序：<br />csc /r:whois.dll whoisclnt.cs<br />接着可以使用命令行参数执行该应用程序。例如，以 microsoft.com参数执行<br />whoisclnt microsoft.com<br /><br />当查询运行成功时，就会出现 microsoft.com的注册信息。（清单8.6 显示了输出的简略版本） 这是一个很方便的<br />小程序，通过组件化的途径写成的，花不到一个小时。如果用C++编写，要花多长时间？很幸运，我再也想不起当第一次用C++这样做时，花了多长的时间。<br /><br />清单 8.6 有关 microsoft.com (简略) 的Whois 信息<br /><br />
<table cellspacing="1" width="100%" bgcolor="#cccccc" border="0">
    <tbody>
        <tr>
            <td bgcolor="#efefef"><br />D:\CSharp\Samples\Namespace&gt;whoisclient<br />...<br /><br />Registrant:<br />Microsoft Corporation (MICROSOFT-DOM)<br />1 microsoft way<br />redmond, WA 98052<br />US<br />Domain Name: MICROSOFT.COM<br /><br />Administrative Contact:<br />Microsoft Hostmaster (MH37-ORG) msnhst@MICROSOFT.COM<br />Technical Contact, Zone Contact:<br />MSN NOC (MN5-ORG) msnnoc@MICROSOFT.COM<br />Billing Contact:<br />Microsoft-Internic Billing Issues (MDB-ORG) msnbill@MICROSOFT.COM<br /><br />Record last updated on 20-May-2000.<br />Record expires on 03-May-2010.<br />Record created on 02-May-1991.<br />Database last updated on 9-Jun-2000 13:50:52 EDT.<br /><br />Domain servers in listed order:<br /><br />ATBD.MICROSOFT.COM 131.107.1.7<br />DNS1.MICROSOFT.COM 131.107.1.240<br />DNS4.CP.MSFT.NET 207.46.138.11<br />DNS5.CP.MSFT.NET 207.46.138.12<br /><br /></td>
        </tr>
    </tbody>
</table>
<br /><br /><strong>8.2.3 增加多个类到名字空间</strong><br /><br />使WhoisLookup和RequestWebPage 类共存于同一个名字空间是多么的美妙。既然WhoisLookup已是名字空间的一部分，<br />所以你只须使RequestWebPage 类也成为该名字空间的一部分。必要的改变很容易被应用。你只需使用名字空间封装RequestWebPage 类就可以了：<br /><br />
<table cellspacing="1" width="100%" bgcolor="#cccccc" border="0">
    <tbody>
        <tr>
            <td bgcolor="#efefef"><br />namespace Presenting.CSharp<br />{<br />public class RequestWebPage <br />{<br />...<br />}<br />}<br /><br /></td>
        </tr>
    </tbody>
</table>
<br />尽管两个类包含于两个不同的文件，但在编译后，它们都是相同名字空间的一部分：<br />csc /r:System.Net.dll /t:library /out:presenting.csharp.dll whois.cs webrequest.cs<br /><br />你不必要按照名字空间的名字给DLL命名。然而，这样做会有助你更容易你记住，当编译一个客户应用程序时要引用哪<br />一个库。<br /><br /><strong>8.3 小结</strong><br />在这一章中，你学到了如何构建一个可以在客户程序中使用的组件。最初，你不必关心名字空间，但后面第二个组件<br />中介绍了该特性。名字空间在内外部均是组织应用程序的好办法。<br />C#中的组件很容易被构建，而且只要库和应用程序共存于相同的目录，你甚至不必进行特殊的安装。当要创建必须被<br />多个客户使用的类库时，步骤就有所改变&mdash;&mdash;而下一章将会告诉你为什么。]]></description><pubDate>Thu, 11 Jan 2007 16:46:12 GMT</pubDate></item><item><title><![CDATA[第七章 异常处理]]></title><link>http://blog.chinayes.com:80/UserBlog/Article_Details,69.htm</link> <description><![CDATA[通用语言运行时（CLR）具有的一个很大的优势为，异常处理是跨语言被标准化的。一个在C#中所引发的异常可以在Visual Basic客户中得到处理。不再有 HRESULTs 或者 ISupportErrorInfo 接口。尽管跨语言异常处理的覆盖面很广，但这一章完全集中讨论C#异常处理。你稍为改变编译器的溢出处理行为，接着有趣的事情就开始了：你处理了该异常。]]></description><pubDate>Thu, 11 Jan 2007 17:21:49 GMT</pubDate></item><item><title><![CDATA[FreeTextBox现在的版本是不开放源代码现在的版本是不开放源代码]]></title><link>http://blog.chinayes.com:80/UserBlog/Article_Details,75.htm</link> <description><![CDATA[<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">大家都知道</span><span lang="EN-US">FreeTextBox</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">现在的版本是不开放源代码的，如果你想给它增加一些自己的东西，<br />看起来会比较麻烦一些，至少没有那些开源版本那样直观，但这并不能妨碍我们给</span><span lang="EN-US">FreeTextBox<br /></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">添加我们自己的按钮。</span></p>
<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">那么究竟怎么做才可以把我们需要的按钮制作成像其他按钮一样安静的放在那里，等待我们<br />去使用它呢？下面就介绍我的实现过程。</span></p>
<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">我的初步想法是，</span><span lang="EN-US">FreeTextBox</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">应该支持我们这样做，所以它可能已经给我们留了一些属性或<br />者</span><span lang="EN-US">Button</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">集合类似的东西，让我们轻松把我们自己的按钮加到它的这个大家庭中。如果推断正确<br />的话，很明显，我们需要做的工作为：</span></p>
<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l1 level1 lfo1; tab-stops: list 18.0pt"><span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'"><span style="mso-list: Ignore">1）<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">制作我们自己的按钮</span></p>
<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l1 level1 lfo1; tab-stops: list 18.0pt"><span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'"><span style="mso-list: Ignore">2）<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">把我们的按钮添加到</span><span lang="EN-US">FreeTextBox</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的</span><span lang="EN-US">Button</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">集合当中</span></p>
<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">那么就让我们去验证一下我们的想法吧。这个验证的过程，就是我们认知和熟悉</span><span lang="EN-US">FreeTextBox</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的一<br />个过程，我想最快的路无疑是看控件的作者留给我们的一些文档啦，</span><span lang="EN-US">FreeTextBox</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的作者很理解他<br />的客户的想法，所以我很快在下载的该控件的一些文件中找到了很需要的东西，那就是</span><span lang="EN-US">readme.txt<br /></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">文本文件，打开，就可以看到作者对关于怎样使用</span><span lang="EN-US">FreeTextBox</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">控件的一个很简单，但很有用的叙述，<br />阅读完后我已经觉得我当初的想法是正确的。在这里我们可以了解到，我们可以自定义我们的工<br />具栏的按钮（指增减已存在的按钮），方法有三种：</span></p>
<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo2; tab-stops: list 18.0pt"><span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'"><span style="mso-list: Ignore">1）<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span lang="EN-US">ToolbarLayout String</span></p>
<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo2; tab-stops: list 18.0pt"><span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'"><span style="mso-list: Ignore">2）<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span lang="EN-US">Procedurally</span></p>
<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo2; tab-stops: list 18.0pt"><span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'"><span style="mso-list: Ignore">3）<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span lang="EN-US">Code (Page_Load or Code Behind)</span></p>
<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这里我只简单列举一下，具体的可参考</span><span lang="EN-US">readme</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">文本文件</span></p>
<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; mso-char-indent-count: 2.0"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">接下来的事情，就让我们动手制作我们的按钮吧。这一次，我添加的是</span><span lang="EN-US">QQ</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">表情图片，希望做到<br />的效果是点击工具栏上我自己的按钮，然后打开一个页面，选择表情，然后把表情图片返回到</span><span lang="EN-US">Free<br />TextBox</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中，就像其他按钮一样，我不希望我的按钮在工具栏上受到不平等的待遇。如何了解其他按<br />钮的工作原理呢？在没有源代码的情况下，这个可能会是一个麻烦事，但并不能阻挡我们探索事物<br />原理的好奇心，拿出我们的利器：</span><span lang="EN-US">Reflector</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">吧，在这个时候他可以带给我们光明，我想反编译在这个<br />时候也该发挥一点力量了吧！用</span><span lang="EN-US">Reflector</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">打开</span><span lang="EN-US">FreeTextBox DLL</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">文件，展现在你面前的是该控件的类层<br />次结构，当然了，你可能会说，直接在</span><span lang="EN-US">vs.net</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的对象浏览器里就直接可以看到类层次结构，对，是这<br />样的。在这里我们不仅是查看</span><span lang="EN-US">FreeTextBox</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的类层次结构更为重要的是我们需要了解他自己的按钮是<br />如何实现的，因为</span><span lang="EN-US">Reflector</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">可同时帮我们做这两件事情。打开</span><span lang="EN-US">FreeTextBoxControls</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">你会发现他自己的<br />按钮类都在这里静静的等你呢，我找到了跟我需要制作的</span><span lang="EN-US">QQ</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">表情类似的按钮：</span><span lang="EN-US">InsertImageFromGallery</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，<br />查看他的实现，你就会找到你需要的东西，首先，它是继承了</span><span lang="EN-US" style="FONT-FAMILY: 宋体; mso-bidi-font-weight: bold">ToolbarButton</span><span style="FONT-FAMILY: 宋体; mso-bidi-font-weight: bold">，查看他的构造函数</span></p>]]></description><pubDate>Fri, 19 Jan 2007 15:35:52 GMT</pubDate></item><item><title><![CDATA[欢迎参加两岸台商网会议欢迎参加两岸台商网会议欢迎参加两岸台商网会议欢迎参加两岸台商网会议]]></title><link>http://blog.chinayes.com:80/UserBlog/Article_Details,77.htm</link> <description><![CDATA[<p>欢迎各位参加两岸台商网会议！</p>
<p>這裡是一個繁簡体共同呈現的頁面，我們力求于把兩岸的網民的生活記錄下來，建設一流的全球台商網路家園！</p>
<p>2007年是台商網最重要的一年，我們一起來加油！</p>
<p>&nbsp;</p>
<p align="center"><img align="center" border="0" alt="" src="http://218.242.131.100/web/User/iexapl/Photo/200703201651510469837.jpg" /></p>]]></description><pubDate>Tue, 20 Mar 2007 16:42:17 GMT</pubDate></item><item><title><![CDATA[ASP.NET如何將sessionState写到SQL Server中]]></title><link>http://blog.chinayes.com:80/UserBlog/Article_Details,79.htm</link> <description><![CDATA[<p>问：<br />ASP.NET如何將sessionState写到SQL Server中?</p>
<p>因为我是使用了Application Center的NLB(Network Loading Balanceb)有多台服务器,他们的Session状态都各在自己的内存,但是当一个服务器此时Set Offline的话,状态将丢失,看到ASP.NET好像有一个SQL Server保存Session的功能.<br />哪位知道, 给小弟指教指教.<br />谢谢.</p>
<p>MSN: <a href="mailto:emyx@msn.com">emyx@msn.com</a><br />Blog: <a href="http://cnblogs.com/dream/">http://cnblogs.com/dream/</a></p>
<p>______________________________________________________________________________________________<br />答1：<br />将Session值储存于SQL Server中 <br />------2002-11-4 14:13:58&nbsp; </p>
<p>一般情况下，我们喜欢使用Session储存我们的变量。Asp.Net提供了下面一些方法储存Session的值： <br />InProc </p>
<p>State Server </p>
<p>SQL Server </p>
<p>&ldquo;InProc&rdquo;表示我们使用传统ASP一样的方法储存Session的值，而且&ldquo;State Server&rdquo;则表示使用另外一台主机来储存Session的值。当然我们也能使用SQL Server储存值，我们这篇文章就专门用于讲解这种方法。 </p>
<p>运行InstallSqlState.sql文件 </p>
<p>首先需要在Winnt\Microsoft.Net中找到InstallSqlState.sql文件，然后在SQL Server 中执行它。在我的机器中，它存在于E:\WINNT\Microsoft.NET\Framework\v1.0.2914\目录中。这个文件是微软自己提供的，里面有很全的SQL语句，大家放心使用。下图就是生成的数据表。</p>
<p>图片地址:http://tech.enet.com.cn/document/images/200202261035530101.jpg</p>
<p>&nbsp;</p>
<p>修改你的web.config文件，指定Session的mode为SQL Server </p>
<p>将web.config的sessionState部分改成： </p>
<p><br />&lt;sessionState mode=&quot;SQLServer&quot; </p>
<p>sqlConnectionString=&quot;data source= </p>
<p>WIN2000;userid= </p>
<p>sa;password=&quot; cookieless= &quot;false&quot;timeout= </p>
<p>&quot;20&quot; /&gt; </p>
<p><br />创建Asp.Net Web Forms </p>
<p>下面就建立一个测试的ASP.net程序，使用Session程序这里就不用多说了，下面是我的程序的截图。这个程序只是简单的储存一个字符串数据于Session中，然后再显示这个数据在Label控件中。 </p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>现在所有的Session变量都储存在数据表中，而不是内存中了。你可打开ASPStateTempSessions表来查看这些Session数据了。 </p>
<p>图片地址:http://tech.enet.com.cn/document/images/200202261035530102.jpg</p>
<p>删除这些数据库和表 </p>
<p>如果你不喜欢这个数据储存方式，看得实在是不爽，那么你可以把这些表和数据库完全删除掉。这个也不要担心这种删除会影响数据库（因为害怕误删除一些数据），因为微软同样也得供给你们一个删除SQL 文件，名叫UnintallSQLState.sql。它与IntallSQLState.sql一样放在.Net的Config目录中。 </p>
<p>&nbsp;</p>
<p>______________________________________________________________________________________________<br />答2：<br />你可以改变Session的存储位置来试试．<br />１．存储在Windows服务中<br />　　启动asp.net state service 服务(net start aspnet_state)<br />&nbsp; 　修改Web.config<br />&nbsp;&nbsp;&nbsp;&nbsp; &lt;configuration&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;system.web&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;sessionState mode=&quot;StateServer&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stateConnectionString=&quot;tcpip=127.0.0.1:42424&quot; /&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/system.web&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp; &lt;/configuration&gt;<br />2.存储在数据库中<br />　　在microsoft sql server query analyzer 中运行installsqlstate.sql,这个文件在　　　　　＂C:\WINNT\Microsoft.NET\Framework\v1.1.4322＂下面找<br />　　修改Web.config<br />&nbsp;&nbsp;&nbsp;&nbsp; &lt;configuration&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;system.web&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;sessionState mode=&quot;SQLServer&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sqlConnectionString=&quot;server=127.0.0.1;UID=sa;PWD=secret&quot; /&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/system.web&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp; &lt;/configuration&gt;<br />&nbsp;&nbsp;&nbsp; 重启SQL server和SQL Server　Agent服务．<br />　　可以用下面的SQL 查询会话<br />　　　select * from AspStateTempSessions<br />'============================</p>
<p>______________________________________________________________________________________________<br />答3：<br />Underpinnings of the Session State Implementation in ASP.NET <br /><a href="http://msdn.microsoft.com/library/en-us/dnaspp/html/aspnetsessionstate.asp?frame=true">http://msdn.microsoft.com/library/en-us/dnaspp/html/aspnetsessionstate.asp?frame=true</a> </p>
<p>&nbsp;</p>
<p><br />HOW TO: Configure ASP.NET for Persistent SQL Server Session State Management <br /><a href="http://support.microsoft.com/default.aspx?scid=kb;en-us;311209">http://support.microsoft.com/default.aspx?scid=kb;en-us;311209</a> </p>
<p>______________________________________________________________________________________________<br />答4：<br />When you use the original SQL Server mode session state management script files (InstallSqlState.sql and UninstallSqlState.sql), the ASPStateTempApplications and the ASPStateTempSessions tables are created in the tempdb database to store the session data. However, the session state data is lost if you restart the computer that is running SQL Server.</p>
<p>The persisting versions of the scripts (InstallPersistSqlState.sql and UninstallPersistSqlState.sql) resolve this problem by creating these tables in the ASPState database instead. Therefore, the session data is retained after you restart the computer that is running SQL Server.</p>]]></description><pubDate>Wed, 04 Apr 2007 18:51:51 GMT</pubDate></item><item><title><![CDATA[通用语言运行时]]></title><link>http://blog.chinayes.com:80/UserBlog/Article_Details,80.htm</link> <description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 通用语言运行时（CLR）具有的一个很大的优势为，异常处理是跨语言被标准化的。一个在C#中所引发的异常可以在Visual Basic客户中得到处理。不再有 HRESULTs 或者 ISupportErrorInfo 接口。尽管跨语言异常处理的覆盖面很广，但这一章完全集中讨论C#异常处理。你稍为改变编译器的溢出处理行为，接着有趣的事情就开始了：你处理了该异常。]]></description><pubDate>Mon, 09 Apr 2007 16:58:22 GMT</pubDate></item><item><title><![CDATA[第七章 异常处理]]></title><link>http://blog.chinayes.com:80/UserBlog/Article_Details,81.htm</link> <description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 通用语言运行时（CLR）具有的一个很大的优势为，异常处理是跨语言被标准化的。一个在C#中所引发的异常可以在Visual Basic客户中得到处理。不再有 HRESULTs 或者 ISupportErrorInfo 接口。尽管跨语言异常处理的覆盖面很广，但这一章完全集中讨论C#异常处理。你稍为改变编译器的溢出处理行为，接着有趣的事情就开始了：你处理了该异常。]]></description><pubDate>Mon, 09 Apr 2007 17:04:56 GMT</pubDate></item><item><title><![CDATA[通用语言运行时（CLR）具有的一个很大的优势为]]></title><link>http://blog.chinayes.com:80/UserBlog/Article_Details,82.htm</link> <description><![CDATA[通用语言运行时（CLR）具有的一个很大的优势为，异常处理是跨语言被标准化的。一个在C#中所引发的异常可以在Visual Basic客户中得到处理。不再有 HRESULTs 或者 ISupportErrorInfo 接口。尽管跨语言异常处理的覆盖面很广，但这一章完全集中讨论C#异常处理。你稍为改变编译器的溢出处理行为，接着有趣的事情就开始了：你处理了该异常。通用语言运行时（CLR）具有的一个很大的优势为，异常处理是跨语言被标准化的。一个在C#中所引发的异常可以在Visual Basic客户中得到处理。不再有 HRESULTs 或者 ISupportErrorInfo 接口。尽管跨语言异常处理的覆盖面很广，但这一章完全集中讨论C#异常处理。你稍为改变编译器的溢出处理行为，接着有趣的事情就开始了：你处理了该异常。]]></description><pubDate>Mon, 09 Apr 2007 17:21:18 GMT</pubDate></item><item><title><![CDATA[通用语言运行时（CLR）具有的一个很大的优势为]]></title><link>http://blog.chinayes.com:80/UserBlog/Article_Details,83.htm</link> <description><![CDATA[通用语言运行时（CLR）具有的一个很大的优势为，异常处理是跨语言被标准化的。一个在C#中所引发的异常可以在Visual Basic客户中得到处理。不再有 HRESULTs 或者 ISupportErrorInfo 接口。尽管跨语言异常处理的覆盖面很广，但这一章完全集中讨论C#异常处理。你稍为改变编译器的溢出处理行为，接着有趣的事情就开始了：你处理了该异常。通用语言运行时（CLR）具有的一个很大的优势为，异常处理是跨语言被标准化的。一个在C#中所引发的异常可以在Visual Basic客户中得到处理。不再有 HRESULTs 或者 ISupportErrorInfo 接口。尽管跨语言异常处理的覆盖面很广，但这一章完全集中讨论C#异常处理。你稍为改变编译器的溢出处理行为，接着有趣的事情就开始了：你处理了该异常。]]></description><pubDate>Mon, 09 Apr 2007 17:38:17 GMT</pubDate></item><item><title><![CDATA[通用语言运行时（CLR）具有的一个]]></title><link>http://blog.chinayes.com:80/UserBlog/Article_Details,84.htm</link> <description><![CDATA[通用语言运行时（CLR）具有的一个很大的优势为，异常处理是跨语言被标准化的。一个在C#中所引发的异常可以在Visual Basic客户中得到处理。不再有 HRESULTs 或者 ISupportErrorInfo 接口。尽管跨语言异常处理的覆盖面很广，但这一章完全集中讨论C#异常处理。你稍为改变编译器的溢出处理行为，接着有趣的事情就开始了：你处理了该异常。]]></description><pubDate>Mon, 09 Apr 2007 17:41:59 GMT</pubDate></item><item><title><![CDATA[通用语言]]></title><link>http://blog.chinayes.com:80/UserBlog/Article_Details,85.htm</link> <description><![CDATA[通用语言运行时（CLR）具有的一个很大的优势为，异常处理是跨语言被标准化的。一个在C#中所引发的异常可以在Visual Basic客户中得到处理。不再有 HRESULTs 或者 ISupportErrorInfo 接口。尽管跨语言异常处理的覆盖面很广，但这一章完全集中讨论C#异常处理。你稍为改变编译器的溢出处理行为，接着有趣的事情就开始了：你处理了该异常。]]></description><pubDate>Mon, 09 Apr 2007 17:54:35 GMT</pubDate></item><item><title><![CDATA[你处理了该异常]]></title><link>http://blog.chinayes.com:80/UserBlog/Article_Details,86.htm</link> <description><![CDATA[通用语言运行时（CLR）具有的一个很大的优势为，异常处理是跨语言被标准化的。一个在C#中所引发的异常可以在Visual Basic客户中得到处理。不再有 HRESULTs 或者 ISupportErrorInfo 接口。尽管跨语言异常处理的覆盖面很广，但这一章完全集中讨论C#异常处理。你稍为改变编译器的溢出处理行为，接着有趣的事情就开始了：你处理了该异常。]]></description><pubDate>Mon, 09 Apr 2007 17:59:34 GMT</pubDate></item><item><title><![CDATA[土木工程]]></title><link>http://blog.chinayes.com:80/UserBlog/Article_Details,89.htm</link> <description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程土木工程]]></description><pubDate>Tue, 24 Apr 2007 13:30:03 GMT</pubDate></item><item><title><![CDATA[枯不求有功]]></title><link>http://blog.chinayes.com:80/UserBlog/Article_Details,90.htm</link> <description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 亚太地区亚太地区亚太地区亚太地区亚太地区亚太地区亚太地区亚太地区亚太地区亚太地区亚太地区亚太地区亚太地区枯不求有功枯不求有功枯不求有功枯不求有功枯不求有功枯不求有功枯不求有功枯不求有功枯不求有功枯不求有功枯不求有功枯不求有功枯不求有功枯不求有功枯不求有功枯不求有功枯不求有功枯不求有功枯不求有功枯不求有功枯不求有功枯不求有功枯不求有功枯不求有功枯不求有功枯不求有功枯不求有功枯不求有功枯不求有功枯不求有功枯不求有功枯不求有功枯不求有功枯不求有功枯不求有功枯不求有功枯不求有功枯不求有功枯不求有功枯不求有功枯不求有功枯不求有功枯不求有功枯不求有功枯不求有功枯不求有功枯不求有功]]></description><pubDate>Tue, 24 Apr 2007 13:34:57 GMT</pubDate></item><item><title><![CDATA[收集一些常用的ASP函数]]></title><link>http://blog.chinayes.com:80/UserBlog/Article_Details,91.htm</link> <description><![CDATA[<div class="entry-body">1、一种图像背景的按钮<br />
<div class="UBBPanel">
<div class="UBBTitle"><img style="MARGIN: 0px 2px -3px 0px" alt="程序代码" src="http://www.ziyuehome.com/images/code.gif" /> 程序代码</div>
<div class="UBBContent">&lt;style&nbsp;type=&quot;text/css&quot;&gt;<br />&lt;!--<br />.button&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;font-size:&nbsp;12px;<br />&nbsp;&nbsp;&nbsp;&nbsp;font-weight:&nbsp;bold;<br />&nbsp;&nbsp;&nbsp;&nbsp;color:&nbsp;#FFFFFF;<br />&nbsp;&nbsp;&nbsp;&nbsp;background-color:&nbsp;#CCFF00;<br />&nbsp;&nbsp;&nbsp;&nbsp;background-image:&nbsp;url(uploads/200504/07yc_search.gif);<br />&nbsp;&nbsp;&nbsp;&nbsp;background-repeat:&nbsp;repeat-x;&nbsp;&nbsp;&nbsp;&nbsp;height:&nbsp;18px;<br />&nbsp;&nbsp;&nbsp;&nbsp;border:&nbsp;1px&nbsp;solid&nbsp;#2263A5;<br />}<br />--&gt;<br />&lt;/style&gt;<br />&lt;input&nbsp;name=&quot;Submit&quot;&nbsp;type=&quot;button&quot;&nbsp;class=&quot;button&quot;&nbsp;value=&quot;关&nbsp;闭&quot;&nbsp;onclick=&quot;self.close()&quot;&gt;</div>
</div>
<br /><br />2、一种按钮样式，好像现在采用Web新标准后比较流行这种左边有道竖线的样式。<br />
<div class="UBBPanel">
<div class="UBBTitle"><img style="MARGIN: 0px 2px -3px 0px" alt="程序代码" src="http://www.ziyuehome.com/images/code.gif" /> 程序代码</div>
<div class="UBBContent">&lt;style&nbsp;type=&quot;text/css&quot;&gt;<br />&lt;!--<br />.button&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;font-size:&nbsp;12px;<br />&nbsp;&nbsp;&nbsp;&nbsp;font-family:&nbsp;MS&nbsp;Sans&nbsp;Serif,&nbsp;Tahoma,&nbsp;Arial;<br />&nbsp;&nbsp;&nbsp;&nbsp;color:&nbsp;#006790;<br />&nbsp;&nbsp;&nbsp;&nbsp;height:&nbsp;20px;<br />&nbsp;&nbsp;&nbsp;&nbsp;border:&nbsp;1px&nbsp;solid&nbsp;#006790;<br />&nbsp;&nbsp;&nbsp;&nbsp;border-left:&nbsp;4px&nbsp;solid&nbsp;#10639A;<br />&nbsp;&nbsp;&nbsp;&nbsp;background-color:&nbsp;#ECF4F6;<br />}<br />--&gt;<br />&lt;/style&gt;<br />&lt;input&nbsp;name=&quot;Submit&quot;&nbsp;type=&quot;button&quot;&nbsp;class=&quot;button&quot;&nbsp;value=&quot;Reset&nbsp;Form&quot;&gt;</div>
</div>
<br /><br />3、几个漂亮的Button的CSS，转自：<a target="_blank" href="http://www.smallrain.net/"><font color="#b07e94">小雨在线</font></a><br />
<div class="UBBPanel">
<div class="UBBTitle"><font color="#b07e94"><img style="MARGIN: 0px 2px -3px 0px" alt="程序代码" src="http://www.ziyuehome.com/images/code.gif" /></font> 程序代码</div>
<div class="UBBContent">&lt;style&gt;<br />.btn&nbsp;{<br />&nbsp;BORDER-RIGHT:&nbsp;#7b9ebd&nbsp;1px&nbsp;solid;&nbsp;PADDING-RIGHT:&nbsp;2px;&nbsp;BORDER-TOP:&nbsp;#7b9ebd&nbsp;1px&nbsp;solid;&nbsp;PADDING-LEFT:&nbsp;2px;&nbsp;FONT-SIZE:&nbsp;12px;&nbsp;