<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
<channel>
<title><![CDATA[我是程序员   -Shosh's Blog]]></title>
<link>http://www.wscxy.com/shosh/</link>
<description><![CDATA[]]></description>
<language>zh-cn</language>
<copyright><![CDATA[Copyright 2005 PBlog3 v2.8]]></copyright>
<webMaster><![CDATA[shosh.zhu@qisda.com(shosh)]]></webMaster>
<generator>PBlog2 v2.4</generator> 
<image>
	<title>我是程序员   -Shosh&#39;s Blog</title>
	<url>http://www.wscxy.com/shosh/images/logos.gif</url>
	<link>http://www.wscxy.com/shosh/</link>
	<description>我是程序员   -Shosh&#39;s Blog</description>
</image>

			<item>
			<link>http://www.wscxy.com/shosh/article.asp?id=130</link>
			<title><![CDATA[代码排版中的缩进和行长]]></title>
			<author>shosh.zhu@qisda.com(shosh)</author>
			<category><![CDATA[程序开发]]></category>
			<pubDate>Sun,25 Apr 2010 23:32:56 +0800</pubDate>
			<guid>http://www.wscxy.com/shosh/default.asp?id=130</guid>
		<description><![CDATA[大家都知道，代码的排版虽然不影响代码的编译和程序的运行，但是对于开发人员来说，它同样很重要。当我们看到排版整齐质量又高的代码的时候，我们会像欣赏艺术品一样去欣赏它，而如果代码排版混乱，哪怕思想再好的代码也会让你看了心烦。本文主要和大家探讨一下代码排版中的缩进和行长问题。<br/><br/>代码的缩进主要使用两个字符：tab键的缩进（\t）和空格。而对于到底使用tab还是空格，目前基本上没有形成统一的说法。使用tab的好处是需要缩进的时候，程序员只要敲一下tab键即可，而且多数程序员（包括我）都比较习惯使用tab。缺点是：tab的宽度是可变的。正常情况下，一个tab的长度是8个普通字符的宽度，而习惯上，我们认为用4个普通字符的宽度作为tab的长度是比较理想的，大多数代码编辑器都可以设定tab的长度。而空格除了缩进比较麻烦（得敲多个空格键），在对齐上比较容易。<br/><br/>另外还有一个问题，如果使用tab，在不同的编辑下显示的效果不同。比如在VC下排版得很好，可是用source insight或者Clear Case里的Merge工具打开，发现排列不整齐了。这个事情真的很头疼，所以有人（公司）就直接规定不许使用tab，只使用空格缩进。不过这样做对开发者来说确实是烦人的事情。<br/><br/>本文提供一个想法，即要有tab缩进的便利性，又要不影响对齐。方法如下：<br/>1、行首的缩进统一使用tab，不能使用空格代替（这样不过设置tab的宽度是多少，都能对齐）<br/>2、有效代码开始后如果还想缩进对齐（如变量的类型和变量名直接），不要使用tab，而使用空格。例如：<br/>typedef struct<br/>{<br/>\tint\s\s\s\s\s\s\s\smember1;<br/>\tfloat\s\s\s\s\s\s\smember2;<br/>} typeName;<br/><br/>int function()<br/>{<br/>\tint\s\s\s\s\s\s\s\s\s\sa;<br/>\tmydefinedtype\s\s\sbbb;<br/>}<br/>上面的\t表示tab缩进，\s表示空格。如果使用等宽的字体，不管\t用几个字符的宽度，上面的代码都能对齐。<br/><br/>对你常用的代码编辑器做如下设置：<br/>1、将代码编辑器的字体设置为等宽字体，如Courier New或比较经典的Fixedsys<br/>2、将代码编辑器的缩进宽度设为4个字节（可选）<br/><br/>这样你的代码就能够时刻对齐了。<br/><br/>再来说说行长的问题：<br/>很多文章或编程书籍都推荐代码一行的长度不要超过80（有的也说75）个字符，如果超过就需要换行，然后说了一堆换行的规则。他们说的换行规则我都赞同，不过我觉得一行不超过80个字符这一条可以改改了。<br/>为什么他们推荐一行的长度不超过80个字符？我想主要有以下几点原因：<br/>1、如果将代码打印，太长的代码会打印不下。<br/>2、这个说法应该在很早的时候就提出来的了，当时的显示器和现在的没法比，当时的显示器分辨率可能只有800*600，甚至只有640*480，如果代码写得太长就会出现水平滚动条，这样很麻烦。<br/>不过对于现在的我们来说：<br/>1、我们的代码基本上不会用来打印，最多放到网页上。<br/>2、我们现在的显示器分辨率比较高，甚至有很多宽屏的，最小的水平分辨率也能达到1024个像素。<br/>我们编写的代码首先应该考虑让自己写得顺手，自己看到舒服，其次再是如果在别人的机器上，别人看你的代码的时候，他们也能看得很舒服，最后再考虑如果放到网页上会显示成什么样。<br/><br/>所以我想说的是：我们不用太去在意80个字符长度的约定，我们可以适当加长。不然老是看到一句代码分成好几行，也不会感觉太美观。<br/><br/>以上只是我个人的看法，没有所谓的对与错，适合自己的就是最好的，不用去管太多的陈旧的条条框框。]]></description>
		</item>
		
			<item>
			<link>http://www.wscxy.com/shosh/article.asp?id=129</link>
			<title><![CDATA[MainMenuWidget简介]]></title>
			<author>shosh.zhu@qisda.com(shosh)</author>
			<category><![CDATA[brew开发]]></category>
			<pubDate>Fri,23 Apr 2010 22:52:14 +0800</pubDate>
			<guid>http://www.wscxy.com/shosh/default.asp?id=129</guid>
		<description><![CDATA[<p>之前开发了一个MainMenuWidget，主要用于主菜单的12宫格。它具有以下功能：</p>
<p>1、宫格数可以由用户确定，最大宫格数由宏由MW_ITEM_ROW_MAX_NUM和MW_ITEM_COL_MAX_NUM控制。工程中使用的MainMenuWidget支持n * m宫格（n &lt;= MW_ITEM_ROW_MAX_NUM &amp;&amp; m &lt;= MW_ITEM_COL_MAX_NUM）的任意组合。</p>
<p>2、任意一个宫格都可以设置是否支持可选中状态。</p>
<p>3、可以有动画移动效果，也可以关闭动画移动效果。</p>
<p>4、每个选中的宫格都支持animation动画，也可以关闭该功能。各个宫格的动画帧数可以不一致，也可以设置animation动画的播放次数（0次到无限）</p>
<p>5、可以设置移动选中Item到达边界后移向哪里（不再移动/回到同行另一端/移动到上一行/移动到下一行）</p>
<p>6、用户可以通过IWIDGET_SetFocusIndex()和IWIDGET_SelectIndex()设置focus的item或快速进入某个item。</p>
<p>7、Widget通过用户注册的函数通知用户focus发生了移动或某个Item被用户选中了（一般情况下用户只关心选中事件）：</p>
<div id="shoCodeAreaWscxy">
<ol id="shoCodeMain45ID" class="shoCodeMain">
    <li id="scli"><span style="color: black"><font color="#0000ff">typedef</font>&nbsp;<font color="#0000ff">enum</font>&nbsp;<font color="#4b0082"><b>{</b></font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;EVT_Select&nbsp;=&nbsp;0x00,</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;EVT_MOVE_FROM_LEFT&nbsp;=&nbsp;0x01,</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;EVT_MOVE_FROM_RIGHT&nbsp;=&nbsp;0x02,</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;EVT_MOVE_FROM_UP&nbsp;=&nbsp;0x04,</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;EVT_MOVE_FROM_DOWN&nbsp;=&nbsp;0x08,</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;<font color="#008000">//EVT_MOVE&nbsp;will&nbsp;be&nbsp;sent&nbsp;when&nbsp;the&nbsp;event&nbsp;is&nbsp;not&nbsp;generated&nbsp;by&nbsp;key&nbsp;pressing,</font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;<font color="#008000">//eg.&nbsp;Set&nbsp;property&nbsp;of&nbsp;PROP_FOCUSINDEX&nbsp;or&nbsp;PROP_SelectINDEX,&nbsp;or&nbsp;by&nbsp;touching&nbsp;screen&nbsp;if&nbsp;supported</font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;EVT_MOVE&nbsp;=&nbsp;0x0F&nbsp;<font color="#008000">//You&nbsp;can&nbsp;use&nbsp;it&nbsp;to&nbsp;check&nbsp;whether&nbsp;it&nbsp;is&nbsp;a&nbsp;move&nbsp;event&nbsp;via&nbsp;(evt&nbsp;&amp;&nbsp;EVT_MOVE)</font></span></li>
    <li id="scli"><span style="color: black"><font color="#4b0082"><b>}</b></font>&nbsp;mmwEvent;</span></li>
    <li id="scli"><span style="color: black"><font color="#0000ff">typedef</font>&nbsp;<font color="#0000ff">void</font>&nbsp;<font color="#4b0082"><b>(</b></font>*PFNMMWSelectHANDLER<font color="#4b0082"><b>)(</b></font><font color="#0000ff">void</font>*&nbsp;pCtx,&nbsp;mmwEvent&nbsp;evt,&nbsp;mmwItemPos*&nbsp;pos<font color="#4b0082"><b>)</b></font>;&nbsp;</span></li>
</ol>
</div>
<p>8、在设计之初MainMenuWidget是不支持触摸屏的，不过后来加了二三十行代码让它支持了。这里使用的方法是将触摸屏事件转化为对PROP_SelectINDEX和PROP_FOCUSINDEX进行设置的EVT_WDG_SETPROPERTY事件。当初在设计的时候考虑了多种方案，最后想到了该方案，个人非常喜欢这样的设计，代码如下：</p>
<div id="shoCodeAreaWscxy">
<ol id="shoCodeMain144ID" class="shoCodeMain">
    <li id="scli"><span style="color: black"><font color="#0000ff">#ifdef</font>&nbsp;FEATURE_TOUCH_PANEL</span></li>
    <li id="scli"><span style="color: black"><font color="#008000">//if&nbsp;it&nbsp;is&nbsp;an&nbsp;touch&nbsp;event,&nbsp;we&nbsp;translate&nbsp;it&nbsp;to&nbsp;non-touch&nbsp;event in order&nbsp;to&nbsp;let&nbsp;it&nbsp;support&nbsp;touch&nbsp;events</font></span></li>
    <li id="scli"><span style="color: black"><font color="#008000">//we&nbsp;will&nbsp;calculate&nbsp;the&nbsp;point&nbsp;position&nbsp;and&nbsp;translate it&nbsp;to&nbsp;mmwItemPos&nbsp;which&nbsp;will&nbsp;be&nbsp;saved&nbsp;to&nbsp;*pIp,</font></span></li>
    <li id="scli"><span style="color: black"><font color="#008000">//and&nbsp;let&nbsp;dwParam&nbsp;point&nbsp;to&nbsp;pIp</font></span></li>
    <li id="scli"><span style="color: black"><font color="#0000ff">static</font>&nbsp;<font color="#0000ff">void</font>&nbsp;MainMenuWidget_TranslateTouchEvt<font color="#4b0082"><b>(</b></font>MainMenuWidget*&nbsp;me,&nbsp;AEEEvent*&nbsp;evt,</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint16*&nbsp;wParam,&nbsp;uint32*&nbsp;dwParam,&nbsp;mmwItemPos*&nbsp;pIp<font color="#4b0082"><b>)</b></font></span></li>
    <li id="scli"><span style="color: black"><font color="#4b0082"><b>{</b></font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">if</font>&nbsp;<font color="#4b0082"><b>(</b></font>TRUE&nbsp;==&nbsp;me-&gt;bNapping<font color="#4b0082"><b>)</b></font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">return</font>;</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">switch</font>&nbsp;<font color="#4b0082"><b>(</b></font>*evt<font color="#4b0082"><b>)</b></font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;<font color="#4b0082"><b>{</b></font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">case</font>&nbsp;EVT_POINTER_MOVE:&nbsp;<font color="#008000">//set&nbsp;focus&nbsp;index</font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">case</font>&nbsp;EVT_POINTER_DOWN:&nbsp;<font color="#008000">//set&nbsp;focus&nbsp;index</font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">case</font>&nbsp;EVT_POINTER_UP:&nbsp;<font color="#008000">//set&nbsp;selected&nbsp;index</font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#008000">//set&nbsp;mmwItemPos&nbsp;values</font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pIp-&gt;indexCol&nbsp;=&nbsp;<font color="#4b0082"><b>(</b></font>*dwParam&nbsp;&gt;&gt;&nbsp;16<font color="#4b0082"><b>)</b></font>&nbsp;/&nbsp;me-&gt;mdt-&gt;itemWidth;</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pIp-&gt;indexRow&nbsp;=&nbsp;<font color="#4b0082"><b>(</b></font>*dwParam&nbsp;&amp;&nbsp;0xFFFF<font color="#4b0082"><b>)</b></font>&nbsp;/&nbsp;me-&gt;mdt-&gt;itemHeight;</span></li>
    <li id="scli"><span style="color: black">&nbsp;</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#008000">//point&nbsp;to&nbsp;mmwItemPos</font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*dwParam&nbsp;=&nbsp;<font color="#4b0082"><b>(</b></font>uint32<font color="#4b0082"><b>)</b></font>pIp;</span></li>
    <li id="scli"><span style="color: black">&nbsp;</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#008000">//change&nbsp;wParam&nbsp;value,&nbsp;MUST&nbsp;be&nbsp;BEFORE&nbsp;changing&nbsp;event&nbsp;code</font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">if</font>&nbsp;<font color="#4b0082"><b>(</b></font>EVT_POINTER_UP&nbsp;==&nbsp;*evt<font color="#4b0082"><b>)</b></font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*wParam&nbsp;=&nbsp;<font color="#4b0082"><b>(</b></font>uint16<font color="#4b0082"><b>)</b></font>PROP_SelectINDEX;</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">else</font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*wParam&nbsp;=&nbsp;<font color="#4b0082"><b>(</b></font>uint16<font color="#4b0082"><b>)</b></font>PROP_FOCUSINDEX;</span></li>
    <li id="scli"><span style="color: black">&nbsp;</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#008000">//change&nbsp;event&nbsp;code</font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*evt&nbsp;=&nbsp;EVT_WDG_SETPROPERTY;</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">break</font>;</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">default</font>:</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">break</font>;</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;<font color="#4b0082"><b>}</b></font></span></li>
    <li id="scli"><span style="color: black"><font color="#4b0082"><b>}</b></font></span></li>
    <li id="scli"><span style="color: black"><font color="#0000ff">#endif</font></span></li>
    <li id="scli"><span style="color: black">&nbsp;</span></li>
    <li id="scli"><span style="color: black"><font color="#0000ff">static</font>&nbsp;boolean&nbsp;MainMenuWidget_HandleEvent<font color="#4b0082"><b>(</b></font>IWidget&nbsp;*po,&nbsp;AEEEvent&nbsp;evt,</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint16&nbsp;wParam,&nbsp;uint32&nbsp;dwParam<font color="#4b0082"><b>)</b></font></span></li>
    <li id="scli"><span style="color: black"><font color="#4b0082"><b>{</b></font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;MainMenuWidget*&nbsp;me&nbsp;=&nbsp;IWIDGET_TO_MW_WIDGET<font color="#4b0082"><b>(</b></font>po<font color="#4b0082"><b>)</b></font>;</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&hellip;&hellip;</span></li>
    <li id="scli"><span style="color: black"><font color="#0000ff">#ifdef</font>&nbsp;FEATURE_TOUCH_PANEL</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;mmwItemPos&nbsp;ip&nbsp;=&nbsp;<font color="#4b0082"><b>{</b></font>0<font color="#4b0082"><b>}</b></font>;</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;MainMenuWidget_TranslateTouchEvt<font color="#4b0082"><b>(</b></font>me,&nbsp;&amp;evt,&nbsp;&amp;wParam,&nbsp;&amp;dwParam,&nbsp;&amp;ip<font color="#4b0082"><b>)</b></font>;</span></li>
    <li id="scli"><span style="color: black"><font color="#0000ff">#endif</font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&hellip;&hellip;</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">else</font>&nbsp;<font color="#0000ff">if</font>&nbsp;<font color="#4b0082"><b>(</b></font>EVT_WDG_SETPROPERTY&nbsp;==&nbsp;evt<font color="#4b0082"><b>)</b></font></span></li>
    <li id="scli"><span style="color: black"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;</span><font color="#4b0082"><b>{</b></font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">switch</font>&nbsp;<font color="#4b0082"><b>(</b></font>wParam<font color="#4b0082"><b>)</b></font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#4b0082"><b>{</b></font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">case</font>&nbsp;PROP_FOCUSINDEX:&nbsp;<font color="#008000">//use&nbsp;the&nbsp;same&nbsp;code&nbsp;with&nbsp;PROP_SelectINDEX</font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">case</font>&nbsp;PROP_SelectINDEX:&nbsp;<font color="#008000">//user&nbsp;wanna&nbsp;select&nbsp;the&nbsp;item</font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#4b0082"><b>{</b></font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mmwItemPos&nbsp;*ps&nbsp;=&nbsp;<font color="#4b0082"><b>(</b></font>mmwItemPos*<font color="#4b0082"><b>)</b></font>dwParam;</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;me-&gt;eMovingStep&nbsp;=&nbsp;MOVING_STEP_NONE;</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;me-&gt;eMovingDirect&nbsp;=&nbsp;MOVING_NONE;</span></li>
    <li id="scli"><span style="color: black">&nbsp;</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#008000">//if&nbsp;it&nbsp;is&nbsp;napping,&nbsp;we&nbsp;do&nbsp;not&nbsp;take&nbsp;any&nbsp;action</font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">if</font>&nbsp;<font color="#4b0082"><b>(</b></font>TRUE&nbsp;==&nbsp;me-&gt;bNapping<font color="#4b0082"><b>)</b></font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">break</font>;</span></li>
    <li id="scli"><span style="color: black">&nbsp;</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#008000">//check&nbsp;whether&nbsp;is&nbsp;right&nbsp;pos</font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">if</font>&nbsp;<font color="#4b0082"><b>(</b></font>ps-&gt;indexCol&nbsp;&gt;=&nbsp;me-&gt;mdt-&gt;itemColNum<font color="#4b0082"><b>)</b></font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ps-&gt;indexCol&nbsp;=&nbsp;me-&gt;mdt-&gt;itemColNum&nbsp;- 1;</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">if</font>&nbsp;<font color="#4b0082"><b>(</b></font>ps-&gt;indexRow&nbsp;&gt;=&nbsp;me-&gt;mdt-&gt;itemRowNum<font color="#4b0082"><b>)</b></font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ps-&gt;indexRow&nbsp;=&nbsp;me-&gt;mdt-&gt;itemRowNum&nbsp;- 1;</span></li>
    <li id="scli"><span style="color: black">&nbsp;</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">if</font>&nbsp;<font color="#4b0082"><b>(</b></font>FALSE&nbsp;==&nbsp;MW_CAN_ITEM_TAKE_FOCUS<font color="#4b0082"><b>(</b></font>*ps<font color="#4b0082"><b>))</b></font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#4b0082"><b>{</b></font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">#if</font>&nbsp;0</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">int</font>&nbsp;i,&nbsp;j;</span></li>
    <li id="scli"><span style="color: black">&nbsp;</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">for</font>&nbsp;<font color="#4b0082"><b>(</b></font>i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;me-&gt;mdt-&gt;itemRowNum&nbsp;;&nbsp;i++<font color="#4b0082"><b>)</b></font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#4b0082"><b>{</b></font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">for</font><font color="#4b0082"><b>(</b></font>j&nbsp;=&nbsp;0;&nbsp;j&nbsp;&lt;&nbsp;me-&gt;mdt-&gt;itemColNum&nbsp;;&nbsp;j++<font color="#4b0082"><b>)</b></font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#4b0082"><b>{</b></font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">if</font>&nbsp;<font color="#4b0082"><b>(</b></font>TRUE&nbsp;==&nbsp;me-&gt;mdt-&gt;arrActiveItemData<font color="#4b0082"><b>[</b></font>i<font color="#4b0082"><b>][</b></font>j<font color="#4b0082"><b>]</b></font>.bCanTakeFocus<font color="#4b0082"><b>)</b></font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#4b0082"><b>{</b></font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ps-&gt;indexCol&nbsp;=&nbsp;j;</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ps-&gt;indexRow&nbsp;=&nbsp;i;</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">break</font>;</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#4b0082"><b>}</b></font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#4b0082"><b>}</b></font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#4b0082"><b>}</b></font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">#else</font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#008000">//couldn't set focus to the item, just&nbsp;ignore&nbsp;it,&nbsp;so&nbsp;we&nbsp;break&nbsp;it.</font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">break</font>;&nbsp;<font color="#008000">//break&nbsp;switch&nbsp;(wParam)</font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">#endif</font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#4b0082"><b>}</b></font></span></li>
    <li id="scli"><span style="color: black">&nbsp;</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">if</font>&nbsp;<font color="#4b0082"><b>(</b></font>me-&gt;newFocusItemPos.indexCol&nbsp;!=&nbsp;ps-&gt;indexCol</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;||&nbsp;me-&gt;newFocusItemPos.indexRow&nbsp;!=&nbsp;ps-&gt;indexRow<font color="#4b0082"><b>)</b></font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MW_SEND_EVENT<font color="#4b0082"><b>(</b></font>EVT_MOVE,&nbsp;&amp;me-&gt;newFocusItemPos<font color="#4b0082"><b>)</b></font>;</span></li>
    <li id="scli"><span style="color: black">&nbsp;</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;me-&gt;newFocusItemPos&nbsp;=&nbsp;*ps;</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;me-&gt;oldFocusItemPos&nbsp;=&nbsp;me-&gt;newFocusItemPos;</span></li>
    <li id="scli"><span style="color: black">&nbsp;</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SET_RECT_BY_POS<font color="#4b0082"><b>(</b></font>me-&gt;newFocusItemRect,&nbsp;me-&gt;newFocusItemPos<font color="#4b0082"><b>)</b></font>;</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;me-&gt;oldFocusItemRect&nbsp;=&nbsp;me-&gt;newFocusItemRect;</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MW_SET_ANIMATION_POS<font color="#4b0082"><b>(</b></font>me-&gt;newFocusItemPos<font color="#4b0082"><b>)</b></font>;</span></li>
    <li id="scli"><span style="color: black">&nbsp;</span></li>
    <li id="scli"><span style="color: black"><font color="#0000ff">#if</font>&nbsp;<font color="#0000ff">defined</font>&nbsp;MW_PRELOAD_IMAGES&nbsp;&amp;&amp;&nbsp;<font color="#0000ff">defined</font>&nbsp;MW_PRELOAD_ANIMATION</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MW_MOVE_ANI_LIST<font color="#4b0082"><b>(</b></font>me-&gt;oldAnimateList,&nbsp;me-&gt;newAnimateList<font color="#4b0082"><b>)</b></font>;</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MW_LOAD_ANI_LIST_DEFAULT<font color="#4b0082"><b>(</b></font>me-&gt;animatingItemPos<font color="#4b0082"><b>)</b></font>;</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;me-&gt;bDrawImageFromNewList&nbsp;=&nbsp;TRUE;</span></li>
    <li id="scli"><span style="color: black"><font color="#0000ff">#endif</font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#008000">//draw&nbsp;new&nbsp;active&nbsp;item&nbsp;immediately</font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#008000">//WidgetBase_Invalidate(CAST(IWidget*,&nbsp;me),&nbsp;ICIF_REDRAW);</font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#008000">//start&nbsp;its&nbsp;animation</font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ISHELL_Resume<font color="#4b0082"><b>(</b></font>me-&gt;piShell,&nbsp;&amp;me-&gt;cbkItemAnimation<font color="#4b0082"><b>)</b></font>;</span></li>
    <li id="scli"><span style="color: black">&nbsp;</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#008000">//defer&nbsp;to&nbsp;call&nbsp;user's&nbsp;callback&nbsp;function</font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">if</font>&nbsp;<font color="#4b0082"><b>(</b></font>PROP_SelectINDEX&nbsp;==&nbsp;wParam<font color="#4b0082"><b>)</b></font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#4b0082"><b>{</b></font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;me-&gt;userSelectedPos&nbsp;=&nbsp;me-&gt;newFocusItemPos;</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;me-&gt;bNapping&nbsp;=&nbsp;TRUE;</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ISHELL_SetTimer<font color="#4b0082"><b>(</b></font>me-&gt;piShell,&nbsp;100,&nbsp;MainMenuWidget_SelectItem,&nbsp;<font color="#4b0082"><b>(</b></font><font color="#0000ff">void</font>*<font color="#4b0082"><b>)</b></font>me<font color="#4b0082"><b>)</b></font>;</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#4b0082"><b>}</b></font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#4b0082"><b>}</b></font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">break</font>;</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&hellip;&hellip;</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#4b0082"><b>}</b></font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;<font color="#4b0082"><b>}</b></font></span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&hellip;&hellip;</span></li>
    <li id="scli"><span style="color: black"><font color="#4b0082"><b>}</b></font>&nbsp;&nbsp;&nbsp;&nbsp;</span></li>
</ol>
</div>
<p>&nbsp;以上为触摸屏添加的代码都用宏FEATURE_TOUCH_PANEL控制起来了。</p>
<p>正因为MainMenuWidget的灵活性，所以各个工程中各个使用到它的地方，可以很方便的（用宏）控制或切换效果。</p>
<p>注：网站后台程序会自动将Select转化为Select，代码中的PFNMMWSelectHANDLER、EVT_Select和PROP_SelectINDEX应为全部大写。</p>]]></description>
		</item>
		
			<item>
			<link>http://www.wscxy.com/shosh/article.asp?id=128</link>
			<title><![CDATA[RFID代码编写问题汇总]]></title>
			<author>shosh.zhu@qisda.com(shosh)</author>
			<category><![CDATA[brew开发]]></category>
			<pubDate>Fri,02 Apr 2010 01:02:30 +0800</pubDate>
			<guid>http://www.wscxy.com/shosh/default.asp?id=128</guid>
		<description><![CDATA[最近在做RFID的开发，驱动由另外一个同事负责，而OEM/AEE和上层的Applet全部由我开发。<br/><br/>OEM层的作用主要是实现IRFID接口，该接口主要通过调用驱动提供的函数读取芯片里的数据。驱动在收到请求后做出处理，最后通过回调的方式将请求结果发还给OEMRfid，OEMRfid再通知上层Applet将数据显示到界面上。<br/><br/>OEM向Applet发送请求结果的方式，当时主要考虑了回调的方式、ISHELL_SendEvent和ISHELL_PostEvent。因为可选的方式较多，所以当初在设计的时候定义了一个宏来向Applet发送结果，这样一来可以简化代码，看上去更简洁，二是如果想选择另外的方式，不需要到处修改代码，而只需要将这个宏的定义调整一下就好。<br/><br/>最开始的时候其实允许Applet来选择是否使用回调，如果注册了回调函数，则通过回调函数返回请求结果，否则就使用ISHELL_SendEvent的方式。之所以没有选择ISHELL_PostEvent，是因为ISHELL_SendEvent是同步调用，可以不用考虑异步的问题，相对会比较简单一点。<br/><br/>问题一：不能使用同步的方法：<br/>不过很快当我测试的时候，发现一个很奇怪的现象，就是Applet在回调函数中将数据显示到界面上的时候，却发现不是我想要的显示效果，而是乱乱的。不过我怎么也找不出问题出现在哪里，最后找来我们部门的高人——我的老大来帮我分析。他通过JTAG看Call Stack发现因为UI的绘制没有发生在UI Task里，也就是说，OEM层的回调函数是在另一个Task里执行的（UIM Task），然后调用Applet的回调用BUIW显示界面，所以发生了问题。所以OEMRfid不能通过Applet注册的回调函数也不能通过ISHELL_SendEvent向Applet发送结果。所以最后将IRFID提供的注册回调的接口删除掉了，并改用了ISHELL_PostEvent的方式。<br/><br/>问题二：两个前后紧挨在一起的语句需要设定顺序:<br/>IRFID的其中一个功能是允许使用这查询交易记录，交易记录是按照顺序一条一条查询的。OEMRfid为了防止使用者连续查询多条交易记录（上一条交易记录还没有查询好就有开始了下一天交易记录的查询），同时为了保存当前正在查询的交易记录ID号，在Applet调用IRFID的接口查询某条交易记录的时候，OEMRfid会将该记录ID号记录下来，在OEMRfid提供给驱动的回调函数中如果收到查询交易记录的响应的时候，再将刚才保存的交易记录ID号设置为无效值，表示允许用户查询另一条交易记录了。所以在IRFID的查询交易记录的接口实现中会判断该变量，如果发现当前还在查询上一条记录，用户的这次调用会返回失败。概括起来说，Applet主动发起查询第一条交易记录请求，OEMRfid发现当前没有正在查询的交易记录，就向驱动发送请求，驱动在处理完请求之后调用回调函数将数据交给OEMRfid，OEMRfid对数据进行一定地处理变拷贝到自己的临时变量空间里，然后通过ISHELL_PostEvent通知Applet，让后再将正在查询的交易记录好设置回无效的ID号，Applet会收到Post过来的Event，将数据按照一定的规则显示到Form里，再去发送下一条请求。最开始OEMRfid回调函数中的POST_EVENT语句位于设置正在查询的记录ID号为无效值的语句之前。<br/><br/>后来被发现有的时候显示的交易记录数目少于实际保存在芯片中的交易记录数，而且时多时少，不是确定的。通过分析Trace终于被我发现那两条语句需要调整一下顺序，因为在正常情况下（没有在刚好发完ISHELL_PostEvent就将活动Task切换到UI Task），两条语句会连续执行的，不会有问题。但是在刚好在刚发完ISHELL_PostEvent的时候活动Task从UIM切换到UI，这样Applet调用IRFID_QueryRecordById的时候就会因为OEMRfid保存的正在查询的ID号还是上一条查询的ID号，就会返回失败而不会向驱动发送查询请求。<br/><br/>最后调整了两句语句的顺序后，果然如果所预期的，一切正常了。<br/><br/>问题三：ISHELL_PostEvent发送保存在局部变量中的数据<br/>最开始使用的是同步的回调或ISHELL_SendEvent，所以数据的保存很简单，只要在OEM提供给驱动的回调函数里申请个局部变量（一个结构体）就好了，数据在处理完后该回调函数才会结束，这个局部变量才会失效。不过后来改成了异步的ISHELL_PostEvent，却忘记了数据是否还是有效的问题。这个问题一直都没有被我注意到，因为一直以来，不过是查询余额，还是查询交易记录，抑或是天线测试，都没有发生任何问题，Applet都能从这个局部变量中获取正确的数据并显示到屏幕上。今天又完成了COS Version的查询功能，结果意外地发现最后两条数据显示有问题（在OEMRfid里使用数据Format出来的保存在那个局部变量中的时间字符串），前面的两个时间显示正常，第三个时间却显示经常显示乱码，并且显示的乱码也不是总是相同的，而有的时候却也能显示正常。本来就感觉那个Format时间字符串的函数没有问题，因为前面的两个时间Format出来都没有问题，而通过Trace更加确定如此了。这是才让我想起PostEvent的异步和局部变量的问题。可是想不明白的是：既然PostEvent异步，局部变量放在栈中，按理说很有可能发生当Applet收到事件的时候，那个局部变量应该已经归还，而且空间是在栈中的，所以数据是不可能不被改写的（只要后面还有入栈的操作，内存中的数据就会被改写），为什么之前测试了那么多次的余额查询和交易记录查询都没有问题？难道是ISHELL_PostEvent做了特殊的处理？可是ISHELL_PostEvent根本无法知道最后的那个参数所代表的含义（即使知道是指针，也无法知道是什么类型的指针），所以ISHELL_PostEvent是不可能作任何保护的。后来才想明白，之所以在查询记录、查询余额、天线测试的时候都没有发现问题，是因为他们的操作比较少，速度比较快，而那个局部变量是在UIM的栈中申请的空间，所以即使那个变量的生命周期到了，那栈里的数据还是可以保存一定时间的，COS Version之所以最后的数据有问题，正是因为在读取完UIM栈里的数据之前，UIM发生了出入栈的事情，所以前面的数据是正常的，后面的数据是错误的。后来我在Applet收到COS Version的事件的时候，先将数据拷贝到自己的临时变量里，让后再处理将数据显示当屏幕到，结果果然没有了问题——这证实了我的猜测。<br/><br/>虽然这样解决了问题，而且看上去不会有问题发生，不过为了确保不发生意外，所以不再使用OEMRfid回调函数里的那个局部变量，而将其放到了OEMRfid的结构体里，这样就可以保证不会发生问题了。<br/><br/>以上这些问题主要是同步异步、任务切换和栈空间的使用问题，平时写代码可能不怎么会碰到（尤其是上层开发时任务切换的问题），这样的问题都让我碰到了，感觉很有意思。<br/>]]></description>
		</item>
		
			<item>
			<link>http://www.wscxy.com/shosh/article.asp?id=127</link>
			<title><![CDATA[copydir.bat: 拷贝目录及各级子目录下的文件到一个目录的工具]]></title>
			<author>shosh.zhu@qisda.com(shosh)</author>
			<category><![CDATA[程序开发]]></category>
			<pubDate>Sun,14 Mar 2010 20:55:18 +0800</pubDate>
			<guid>http://www.wscxy.com/shosh/default.asp?id=127</guid>
		<description><![CDATA[<p>背景：工作中，UI工程师提供图片资源是分目录放置的，可是提交给CM的时候却需要在一个目录下的，如果手动拷贝非常麻烦，而如果直接用COPY 或 XCOPY命令把文件从A目录拷贝到B目录，B目录还是会维持A目录的目录结构。昨天晚上手动写了一根批处理工具，正是用来解决该问题的。具体用法代码中也有，这里不赘述。</p>
<p>copydir.bat代码如下：</p>
<div id="shoCodeAreaWscxy">
<ol id="shoCodeMain43ID" class="shoCodeMain">
    <li id="scli"><span style="color: black">::&nbsp;Auther:&nbsp;Shosh</span></li>
    <li id="scli"><span style="color: black">::&nbsp;Site:&nbsp;&nbsp;http://www.wscxy.com</span></li>
    <li id="scli"><span style="color: black">::&nbsp;Date:&nbsp;&nbsp;2010.03.13</span></li>
    <li id="scli"><span style="color: black">::&nbsp;This&nbsp;bat&nbsp;copies&nbsp;all&nbsp;the&nbsp;files&nbsp;under&nbsp;a&nbsp;directory&nbsp;and&nbsp;all&nbsp;levels&nbsp;of&nbsp;subdirectories&nbsp;to&nbsp;another&nbsp;folder(no&nbsp;subfolder)</span></li>
    <li id="scli"><span style="color: black">@ECHO&nbsp;OFF</span></li>
    <li id="scli"><span style="color: black">&nbsp;</span></li>
    <li id="scli"><span style="color: black">SET&nbsp;DefSrcRootDir=.</span></li>
    <li id="scli"><span style="color: black">SET&nbsp;DefDestDir=.</span></li>
    <li id="scli"><span style="color: black">&nbsp;</span></li>
    <li id="scli"><span style="color: black">:FunBegin</span></li>
    <li id="scli"><span style="color: black">SET&nbsp;bConfirm=NO</span></li>
    <li id="scli"><span style="color: black">IF&nbsp;&quot;%1&quot;&nbsp;==&nbsp;&quot;/?&quot;&nbsp;GOTO&nbsp;FunUsage</span></li>
    <li id="scli"><span style="color: black">&nbsp;</span></li>
    <li id="scli"><span style="color: black">SET&nbsp;bHaveOption=FALSE</span></li>
    <li id="scli"><span style="color: black">IF&nbsp;&quot;%1&quot;&nbsp;==&nbsp;&quot;/c&quot;&nbsp;SET&nbsp;bHaveOption=TRUE</span></li>
    <li id="scli"><span style="color: black">IF&nbsp;&quot;%1&quot;&nbsp;==&nbsp;&quot;/C&quot;&nbsp;SET&nbsp;bHaveOption=TRUE</span></li>
    <li id="scli"><span style="color: black">IF&nbsp;&quot;%1&quot;&nbsp;==&nbsp;&quot;-c&quot;&nbsp;SET&nbsp;bHaveOption=TRUE</span></li>
    <li id="scli"><span style="color: black">IF&nbsp;&quot;%1&quot;&nbsp;==&nbsp;&quot;-C&quot;&nbsp;SET&nbsp;bHaveOption=TRUE</span></li>
    <li id="scli"><span style="color: black">&nbsp;</span></li>
    <li id="scli"><span style="color: black">IF&nbsp;bHaveOption&nbsp;==&nbsp;TRUE&nbsp;(</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SET&nbsp;bConfirm=YES</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IF&nbsp;&quot;%2&quot;&nbsp;==&nbsp;&quot;&quot;&nbsp;(</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SET&nbsp;srcRootDir=%DefSrcRootDir%</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SET&nbsp;destDir=%DefDestDir%</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)&nbsp;ELSE&nbsp;(</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IF&nbsp;NOT&nbsp;&quot;%4&quot;&nbsp;==&nbsp;&quot;&quot;&nbsp;GOTO&nbsp;FunErrorUsing</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SET&nbsp;srcRootDir=%2</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SET&nbsp;destDir=%3</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)</span></li>
    <li id="scli"><span style="color: black">)&nbsp;ELSE&nbsp;(</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SET&nbsp;bConfirm=NO</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IF&nbsp;&quot;%1&quot;&nbsp;==&nbsp;&quot;&quot;&nbsp;(</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SET&nbsp;srcRootDir=%DefSrcRootDir%</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SET&nbsp;destDir=%DefDestDir%</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)&nbsp;ELSE&nbsp;(</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IF&nbsp;NOT&nbsp;&quot;%3&quot;&nbsp;==&nbsp;&quot;&quot;&nbsp;GOTO&nbsp;FunErrorUsing</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SET&nbsp;srcRootDir=%1</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SET&nbsp;destDir=%2</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)</span></li>
    <li id="scli"><span style="color: black">)</span></li>
    <li id="scli"><span style="color: black">IF&nbsp;&quot;%destDir%&quot;&nbsp;==&nbsp;&quot;&quot;&nbsp;GOTO&nbsp;FunErrorUsing</span></li>
    <li id="scli"><span style="color: black">&nbsp;</span></li>
    <li id="scli"><span style="color: black">::confirm&nbsp;settings</span></li>
    <li id="scli"><span style="color: black">ECHO&nbsp;================================================================</span></li>
    <li id="scli"><span style="color: black">ECHO&nbsp;&nbsp;&nbsp;Source&nbsp;Root&nbsp;Dir:&nbsp;%srcRootDir%</span></li>
    <li id="scli"><span style="color: black">ECHO&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Dest&nbsp;Dir:&nbsp;%destDir%</span></li>
    <li id="scli"><span style="color: black">ECHO&nbsp;Overwrite&nbsp;Confirm:&nbsp;%bConfirm%</span></li>
    <li id="scli"><span style="color: black">ECHO&nbsp;================================================================</span></li>
    <li id="scli"><span style="color: black">SET&nbsp;/P&nbsp;choice=Start&nbsp;executing?&nbsp;[Y/N]&nbsp;</span></li>
    <li id="scli"><span style="color: black">if&nbsp;NOT&nbsp;%choice%&nbsp;==&nbsp;Y&nbsp;(</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;NOT&nbsp;%choice%&nbsp;==&nbsp;y&nbsp;GOTO&nbsp;FunCancel</span></li>
    <li id="scli"><span style="color: black">)</span></li>
    <li id="scli"><span style="color: black">::check&nbsp;input&nbsp;directories&nbsp;settings</span></li>
    <li id="scli"><span style="color: black">IF&nbsp;NOT&nbsp;EXIST&nbsp;%srcRootDir%&nbsp;ECHO&nbsp;[%srcRootDir%]&nbsp;not&nbsp;found!!!</span></li>
    <li id="scli"><span style="color: black">IF&nbsp;NOT&nbsp;EXIST&nbsp;%destDir%&nbsp;ECHO&nbsp;[%destDir%]&nbsp;not&nbsp;found,&nbsp;we&nbsp;will&nbsp;create&nbsp;it.</span></li>
    <li id="scli"><span style="color: black">&nbsp;</span></li>
    <li id="scli"><span style="color: black">::check&nbsp;source&nbsp;root&nbsp;dir&nbsp;before&nbsp;starting&nbsp;coping</span></li>
    <li id="scli"><span style="color: black">IF&nbsp;NOT&nbsp;EXIST&nbsp;%srcRootDir%&nbsp;GOTO&nbsp;FunPause</span></li>
    <li id="scli"><span style="color: black">IF&nbsp;%bConfirm%&nbsp;==&nbsp;YES&nbsp;(</span></li>
    <li id="scli"><span style="color: black">::&nbsp;confirm&nbsp;overwriting</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FOR&nbsp;/R&nbsp;%srcRootDir%&nbsp;%%i&nbsp;IN&nbsp;(.)&nbsp;DO&nbsp;XCOPY&nbsp;&quot;%%i&quot;&nbsp;&quot;%destDir%&quot;&nbsp;/-Y&nbsp;/V&nbsp;/F&nbsp;/I&nbsp;/K</span></li>
    <li id="scli"><span style="color: black">)&nbsp;ELSE&nbsp;(</span></li>
    <li id="scli"><span style="color: black">::&nbsp;no&nbsp;confirm</span></li>
    <li id="scli"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FOR&nbsp;/R&nbsp;%srcRootDir%&nbsp;%%i&nbsp;IN&nbsp;(.)&nbsp;DO&nbsp;XCOPY&nbsp;&quot;%%i&quot;&nbsp;&quot;%destDir%&quot;&nbsp;/Y&nbsp;/V&nbsp;/F&nbsp;/I&nbsp;/K</span></li>
    <li id="scli"><span style="color: black">)</span></li>
    <li id="scli"><span style="color: black">&nbsp;</span></li>
    <li id="scli"><span style="color: black">ECHO&nbsp;================================================================</span></li>
    <li id="scli"><span style="color: black">ECHO&nbsp;Finish!!!&nbsp;</span></li>
    <li id="scli"><span style="color: black">ECHO&nbsp;Thank&nbsp;you&nbsp;for&nbsp;using&nbsp;copydir.bat&nbsp;written&nbsp;by&nbsp;Shosh!!!</span></li>
    <li id="scli"><span style="color: black">ECHO&nbsp;Welcome&nbsp;to&nbsp;visit&nbsp;my&nbsp;website&nbsp;http://www.wscxy.com</span></li>
    <li id="scli"><span style="color: black">GOTO&nbsp;FunPause</span></li>
    <li id="scli"><span style="color: black">&nbsp;</span></li>
    <li id="scli"><span style="color: black">:FunErrorUsing</span></li>
    <li id="scli"><span style="color: black">ECHO&nbsp;!!!&nbsp;Error&nbsp;using&nbsp;copydir.bat&nbsp;!!!</span></li>
    <li id="scli"><span style="color: black">GOTO&nbsp;FunUsage</span></li>
    <li id="scli"><span style="color: black">&nbsp;</span></li>
    <li id="scli"><span style="color: black">:FunUsage</span></li>
    <li id="scli"><span style="color: black">ECHO&nbsp;USAGE:&nbsp;&nbsp;&nbsp;&nbsp;copydir&nbsp;[/C]&nbsp;[source&nbsp;root&nbsp;dir]&nbsp;[dest&nbsp;dir]</span></li>
    <li id="scli"><span style="color: black">ECHO&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[/C]&nbsp;Confirm&nbsp;if&nbsp;a&nbsp;file&nbsp;needs&nbsp;overwriting.&nbsp;if&nbsp;not&nbsp;set,&nbsp;it&nbsp;will&nbsp;overwrite&nbsp;without&nbsp;confirm.</span></li>
    <li id="scli"><span style="color: black">ECHO&nbsp;If&nbsp;set&nbsp;both&nbsp;src&nbsp;root&nbsp;dir&nbsp;and&nbsp;dest&nbsp;dir&nbsp;to&nbsp;.,&nbsp;that&nbsp;means&nbsp;all&nbsp;the&nbsp;files&nbsp;in&nbsp;all&nbsp;levels&nbsp;of&nbsp;subfolders&nbsp;will&nbsp;be&nbsp;copied&nbsp;to&nbsp;the&nbsp;current&nbsp;folder.</span></li>
    <li id="scli"><span style="color: black">goto&nbsp;FunPause</span></li>
    <li id="scli"><span style="color: black">&nbsp;</span></li>
    <li id="scli"><span style="color: black">:FunCancel</span></li>
    <li id="scli"><span style="color: black">ECHO&nbsp;You've&nbsp;canceled&nbsp;executing.</span></li>
    <li id="scli"><span style="color: black">GOTO&nbsp;FunPause</span></li>
    <li id="scli"><span style="color: black">&nbsp;</span></li>
    <li id="scli"><span style="color: black">:FunPause</span></li>
    <li id="scli"><span style="color: black">ECHO&nbsp;================================================================</span></li>
    <li id="scli"><span style="color: black">SET&nbsp;/P&nbsp;a=Press&nbsp;ENTER&nbsp;key&nbsp;to&nbsp;continue...&nbsp;</span></li>
</ol>
</div>]]></description>
		</item>
		
			<item>
			<link>http://www.wscxy.com/shosh/article.asp?id=126</link>
			<title><![CDATA[头文件的部分规则：重定义相关]]></title>
			<author>shosh.zhu@qisda.com(shosh)</author>
			<category><![CDATA[C/C++]]></category>
			<pubDate>Thu,28 Jan 2010 00:32:30 +0800</pubDate>
			<guid>http://www.wscxy.com/shosh/default.asp?id=126</guid>
		<description><![CDATA[Author: Shosh<br/>Site: <a href="http://www.wscxy.com" target="_blank" rel="external">http://www.wscxy.com</a><br/><br/>RULE1: 每个头文件都用以下宏包起来，防止被其他文件多次包含。<br/>&nbsp;&nbsp;&nbsp;&nbsp;#ifndef __FILENAME_H__<br/>&nbsp;&nbsp;&nbsp;&nbsp;#define __FILENAME_H__<br/>&nbsp;&nbsp;&nbsp;&nbsp;（……文件内容……）<br/>&nbsp;&nbsp;&nbsp;&nbsp;#endif //__FILENAME_H__<br/><br/>RULE2: 在定义一个宏的时候，考虑是否需要检测是否已经被定义过。<br/>&nbsp;&nbsp;&nbsp;&nbsp;#ifndef MACRO_NAME<br/>&nbsp;&nbsp;&nbsp;&nbsp;#define MACRO_NAME&nbsp;&nbsp;&nbsp;&nbsp; MACRO_VALUE<br/>&nbsp;&nbsp;&nbsp;&nbsp;#endif<br/><br/>RULE3：头文件中不要去定义全局变量，也就是说头文件中的所有语句不能涉及实际内存的分配。<br/><br/>对于RULE1，基本上大家都会这么做，当然也可以用pragma once来代替，只是pragma once的通用性不好，所以大家大多选择比较麻烦一点的RULE1中的做法。RULE1不是我想说的重点。<br/><br/>RULE2主要是为了防止宏重定义。在同一个工程中，尤其是一较大的工程中，同一个名字的宏在多个文件被定义是很正常的，比如BREW中RELEASEIF往往在多处被定义。在VC的编译器中，即使重定义也不会报错，甚至连Warning都没有，但是TCC会作为Error来处理。<br/>举例：a.h中定义了宏A，b.h中也定义了宏A，他们都没有用ifndef包起来。然后某个源文件同时包含了这两个文件。对于严格的编译器来说，会出现重定义的错误，而对于检查较松的编译器，后者的定义会覆盖前者的定义（有的时候不同地方对同一个宏的定义不同）。有的时候，某些头文件我们需要包含进来，但是我们不关心那些头文件有没有已经定义了自己想要定义的宏或者自己想要定义的宏名被那些头文件定义成了什么样子，我们可以先undef掉那个宏，然后再定义自己的宏，这样可以保证自己用的宏是自己想要的定义。用RULE2的做法确实存在这样一个问题，我们不能确定自己用的宏是什么样子的（和包含的头文件以及它们的顺序有关系，这意味着本来都正常的代码，忽然有一天你又把另外一个头文件包含进来，结果这个宏的定义可能就不再是原来的那个了）。如果需要确认，可以让编译器生成预处理后的文件查看，不过一般情况下不需要这么做。<br/><br/>今天有个同事碰到了这样一个问题，让我过去帮他看看：我看到的错误是说某个头文件的某个宏重定义了。据他描述是因为他在某个C源文件里包含了多个头文件导致的。可是这些被他包含进来的头文件中却没有那个提示出错的头文件，另外这个重定义的宏对他来说一点用也没有。当时我怎么也没想不明白，既然没有包含进那个出错的头文件，怎么会是因为加了这一堆头文件导致的，就算是有重定义的错误也该发生在这些被包含进来的头文件才对呀。原来这些被包含的头文件往往又会包含其它头文件，这样扩展开来是类似树状的结构，一种情况是那个出错的文件被这些头文件直接或间接地包含进来了一次，但是还有其他被比较或间接包含进来的进来的头文件也同时定义了这个宏，只是那个出错的文件被包含的顺序比较靠后一点，所以出错并提示该头文件的那个宏重定义；另一种情况是这个这个出错的头文件被间接地包含了多次，并且这个头文件没有用RULE1去做，当然这种可能性很小。解决该问题的方法是找到去找到被他包含进来的（包括间接包含进来的）的头文件哪里定义了这个宏，却没有用RULE2去定义的。但是这样找很多文件，即使使用Source Insight搜索到所有的包含该宏定义的头文件，也要去确认那些头文件是否属于被他包含的头文件之列，比较麻烦。如果使用#error通过二分法查找，需要不停地编译数次可以找到。另一种方法是在他的某处合适的头文件包含语句之间添加#undef那个宏的语句，可以解决掉这个问题（别人忽然看到可能会觉得奇怪，如果找到精确位置还是要一定功夫的，如果每个包含头文件语句之间都添加这样的语句，会显得很冗赘）。还有专门的工具可以生成文件包含关系，如果手头有这样的工具的话，找起来还是很方便的。<br/><br/>RULE3比较容易理解：如果没有遵循RULE3的头文件被多个源文件包含的时候，链接的时候编译器就会发现不知道该使用哪个符号了。<br/><br/>总结：RULE1 是作为预防头文件被重复的做法，虽然能够保证头文件不被重复包含，但是却不能预防宏的重定义。在多文件工程的头文件中，应该按此法去做。RULE2可以有效防止宏的重定义，但是某些检查较松的编译器如VC的CL是允许宏重定义的。RULE2可能会让你使用的宏的实际定义变得模糊，有的时候你可能只想使用自己定义的宏，但是你包含的其他头文件可能会已经包含了这个宏名，可以先undef掉。另外，我们应该尽量避免在不同头文件定义同名的宏，而比较公用的、可能会被多个其他文件包含的头文件应该使用RULE2去定义宏，以防止重定义。RULE3是必须遵循的。]]></description>
		</item>
		
			<item>
			<link>http://www.wscxy.com/shosh/article.asp?id=125</link>
			<title><![CDATA[杂谈：Brew上的应用开发]]></title>
			<author>shosh.zhu@qisda.com(shosh)</author>
			<category><![CDATA[brew开发]]></category>
			<pubDate>Sun,24 Jan 2010 01:27:38 +0800</pubDate>
			<guid>http://www.wscxy.com/shosh/default.asp?id=125</guid>
		<description><![CDATA[<p>Author: Shosh<br />
Site: <a href="http://www.wscxy.com/">http://www.wscxy.com</a></p>
<p>对于MMI工程师在BREW上的开发需求，往往是以Applet为单位的。Brew上的Applet就是一个应用程序，和Application的概念类似。</p>
<p>大多数Applet都需要UI界面（Daemon程序的需求往往很少），他们往往需要完成一定的功能，所以有逻辑的部分，如计算器程序，就是要处理用户输入的数据并给出计算结果；另外，我们需要提供显示界面和用户进行交互，越是动感越是绚丽的界面效果越能赢得用户的喜爱。话说回来，MMI层次上开发的应用，逻辑上大多比较简单，不需要复杂的算法。开发者不必了解太多的底层知识和硬件知识，只要有扎实的程序语言开发功底（BREW上多数用C，也有用C++的），基本上都能写出一般的应用来。另外，逻辑部分的代码变动性不强，而界面效果在不同的工程间则可以相差很大，还是拿计算器程序来举例，我们在不同的手机上看到的计算器程序，有的界面效果看上去很一般，而有的则很漂亮，但是他们完成的功能是差不多的。而对于一个公司来讲，他们往往希望同一套代码能够适应不同工程项目上的需求，这样可以在很大程度上减少工作量。其实这是客制化的一部分，最理想的客制化是不需要修改代码，只要替换图片资源、字符串资源和其他一些资源如音频资源即可达到目的。但是如果差异较大，光靠资源的替换是很难满足需求的，还是需要修改到代码的。我们会希望尽量少地改动到逻辑代码，最好是只需要修改到一些数据，而不用去修改实质性的代码，而功能逻辑上的一致性给了我们一定的可能。说了这么多，其实是说：我们在设计的时候尽量考虑通用性，以提高代码的复用率以及风格变换的简易性。</p>
<p>目前，在Brew上开发界面，主要使用BUIW。在BUIW中，主要有Form, RootForm, Container, Widget, Decorator, Model等概念。下面简单介绍一下这些基本概念：</p>
<p>Model：其实Model是一个用来存放数据的结构。它提供专门的接口让用户设置Model的值或得到Model的值。另外Model还负责维护Listener List，并提供接口允许对象监听它（将Listener加入到Listener List中）。当用户通过Model提供的设置数据的接口改变Model的值的时候，Model就会逐个给监听它的Listener对象发送消息（实际上是直接调用Listener注册的回调函数），监听的对象再做出相应的动作，如使用新设置进来的数据更新画面等。其实这里应用了设计模式中的观察者模式（Abserver Pattern）。Model分很多种，比较常用的有Value Model, Interface Model, Vector&nbsp;Model等，不同种类的Model存放的数据类型不同。一般情况下，一个Widget会关联上一种Model，并监听Model数据的改动。</p>
<p>Widget：Widget是BUIW中一个最小的UI元素，可以理解成控件，比如按钮(Button Widget)、图片（Image&nbsp;Widget）、静态文本框（Static&nbsp;Widget）、可编辑文本框（Text Widget）、滚动条（Scroolbar Widget）等。它们会根据需要关联Model，如Static Widget，它需要记录显示的字符串内容，所以会关联一个Value&nbsp;Model，而对于Image&nbsp;Widget，则关联Interface Model。一般Model存放的是一些允许用户设置或修改的数据，比如一个Static Widget，有的时候显示&ldquo;你好&rdquo;，有的时候显示&ldquo;这是一段文本&rdquo;，这些不确定的可随时修改的数据就存放在它关联的Model中。这样当这些数据更改的时候，Model会通知Widget你需要更新你的长相，和你的数据保持同步了。当然监听者对于数据的改动也可以做出不同的反应。</p>
<p>Container：一个个Widget创建好之后，它们该怎么摆放是一个问题。因为Widget只知道自己长什么样子，却不知道自己该站在什么地方。Container就是Widget的家，它是用来组织管理Widget的，一个个Widget会依次插入到Container合适的位置去（什么是合适的位置？就是在这个Container中，除了相对于Container的相对位置以外，还有Z轴方向上的叠放次序，也就是说在垂直于屏幕的方向上，Widget之间还是有先后顺序的，位于上层的Widget有可能挡住位于其下的Widget，这就是Z-Order的概念）。Widget本身是有大小的，Container本身也是有大小的，所谓大小就是矩形区域的意思。所以位于Container中的Widget与它的Parent Container有一定的位置关系，分别是完全位于Container中、与Container一部分相交和完全位于Container外部。位于Container外部的那部分是肯定不会被显示出来的，而位于Container内部的那部分如果在其上没有被其它Widget遮挡住，就可以显示出来。Container同样根据定位方式可以分成以下几种：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XYContainer，这是一种最简单的Container，通过Widget的左上角位置和Container的左上角位置的偏移量确定Widget的相对位置。这里水平方向为X方向，向右为正，竖直方向为Y方向，向下为正（一般程序中坐标系都是这么定的）。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PropContainer：这里的Prop是Proportion的缩写，也就是比例的意思。所以PropContainer实际上就是通过给它包含的Widget在空间上按照比例分配大小来实现定位的。PropContainer需要指定是在X方向上的按比例分配还是Y方向上的按比例分配，不能同时在X方向和Y方向按比例分配。PropContainer的好处是在不同分辨率的情况下，它都能够布局得很好。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ConstrainContainer：这是通过约束来实现定位的Container，Widget可以通过相对于Parent Container的上下左右边界的距离或者相对于Sibling Widgets边界的距离进行定位，使用起来比XYContainer和PropContainer都来得复杂，在特殊场合会比较有用，平时一般用得比较少。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CardContainer：CardContainer很特殊，也很简单，因为它只考虑Z方向的叠放次序，而忽略X方向和Y方向的位置距离。它就像一叠堆放整齐的纸牌，我们只能看到最上面的一张，而位于下面的是无法看到的。前面提到的3种Container，其实我们都是在X方向和Y方向对它们进行定位，CardContainer根本不需要，所以它最简单。CardContainer的典型应用是和TabWidget的搭配。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 所有的Container在Z方向的叠放次序都是在插入的时候指定的。另外，我们可以把一个Container看成是一个比较复杂的Widget，因为我们可以通过ISHELL_QueryInterface(, AEEIID_WIDGET,)获取到与它相应的IWidget*，然后当做是一个简单的Widget调用WIDGET提供的方法。正因为如此，我们可以把Container作为Child Widget插入到另一个Container中，来实现比较复杂的界面组织。也正因为如此，我们可以把Container作为WID_FORM插入到Form中，作为Form的Widget。若不是如此，界面结构将是多么单调，所以对于Container来说，它本身可以作为Widget来使用是极具意义的。</p>
<p>Decorator：Decorator和Container类似，也可以往里面装入Widget，只是Decorator只能往里面装入一个Widget。它也不是用来给Widget布局的，而只是为Widget提供修饰服务的。Decorator同样可以被看成是一个Widget，通过ISHELL_QueryInterface(, AEEIID_WIDGET,)获取到与它相应的IWidget*。MMI在开发Applet设计Form的时候，一般不会用到Decorator。它主要在设计某些Widget的时候被用到，如Border&nbsp;Widget, TabWidget, ScrollbarWidget等。所以这里也不讨论其具体用法。</p>
<p>FORM：比较传统的理解可以这样认为：每个界面差不多都是一个FORM，正常情况下它包括顶上标题Title、底部的软键SoftKeys和中间的那个ID为WID_FORM的Widget（前面提到过了），这个WID_FORM的Widget是Form中最重要的一部分，设计和创建Form的时候，主要在设计和创建这个Widget（前面说过多数情况下它是Container，里面可以包含多个Widget和子Container，这种包含关系是树形结构）。但是其实也可以这么理解，其实Form只是保存着一部分用来显示的信息，包括Title, WID_FORM的Widget和Softkeys等相关的数据；另外一部分重要的功能就是处理事件（IFORM&nbsp;是直接从 IHANDLER继承下来的，本身没有增加任何方法），像IFORM_GetWidget(), IFORM_GetRootForm之类的接口实际上都不是IFORM虚函数表中的实现，都只是普通的inline函数。Form的很多功能包括显示都是依赖RootForm的。</p>
<p>ROOTFORM：比较传统的理解可以这样认为：RootForm继承自Form，基本上每个Applet（只后台运行的Daemon程序除外）都会创建一个属于自己的RootForm，负责维护应用中所有创建出来的Form。事实上，我们看到的Applet画面就是RootForm绘制的，也可以理解成我们看到的是RootForm，因为RootForm才真正创建了........（待续）.......</p>]]></description>
		</item>
		
			<item>
			<link>http://www.wscxy.com/shosh/article.asp?id=124</link>
			<title><![CDATA[最新Android SDK 地址]]></title>
			<author>shosh.zhu@qisda.com(shosh)</author>
			<category><![CDATA[Android开发]]></category>
			<pubDate>Fri,11 Dec 2009 19:09:30 +0800</pubDate>
			<guid>http://www.wscxy.com/shosh/default.asp?id=124</guid>
		<description><![CDATA[最新Android开发地址： <a href="http://developer.android.com/sdk/index.html" target="_blank" rel="external">http://developer.android.com/sdk/index.html</a><br/>以前在国内这个地址好像是打不开的，不过现在可以了。<br/><br/>Android快速起步（搭建Android环境）<br/>Quick Start：<br/>The steps below provide an overview of how to get started with the Android SDK. For detailed instructions, start with the Installing guide. <br/><br/>0. Prepare your development computer<br/><br/>Read the System Requirements document and make sure that your development computer meets the hardware and software requirements for the Android SDK. Install any additional software needed before downloading the Android SDK. In particular, if you plan to develop Android applications in the Eclipse IDE using the ADT Plugin (see below), make sure that you have the correct version of Eclipse installed. <br/><br/>1. Download and install the SDK starter package<br/><br/>Sel&#101;ct a starter package from the table at the top of this page and download it to your development computer. To install the SDK, simply unpack the starter package to a safe location and then add the location to your PATH. <br/><br/>2. Install the ADT Plugin for Eclipse<br/><br/>If you are developing in Eclipse, set up a remote up&#100;ate site and install the Android Development Tools (ADT) plugin. For detailed instructions, see Installing and Updating ADT.<br/><br/>3. Add Android platforms to your SDK<br/><br/>Use the Android SDK and AVD Manager, included in the SDK starter package, to add one o&#114; more Android platforms (for example, Android 1.6 o&#114; Android 2.0) to your SDK. In most cases, you will want to download multiple platforms, so that you can build your application on the lowest version you want to support, but test against higher versions that you intend the application to run on. Information about each platform is available at left, under &#34;Downloadable SDK Components.&#34;<br/><br/>To launch the Android SDK and AVD Manager on Windows, execute SDK Setup.exe, at the root of the SDK directory. On Mac OS X o&#114; Linux, execute the android tool in the &lt;sdk&gt;/tools/ folder. For more information about how to add platforms and other components, see Adding SDK Components. <br/><br/>4. Get the latest documentation<br/><br/>If you develop while offline, use the Android SDK and AVD Manager to download the latest documentation package. The documentation covers all versions of the API and lets you filter out those versions that your application won&#39;t support. Once installed, the documentation is also available to you directly from the Eclipse IDE. <br/><br/>5. Download other SDK components<br/><br/>You can use the Android SDK and AVD Manager to download other SDK components, such as the SDK add-ons. An SDK add-on provides a development environment for an Android external library o&#114; a customized Android system image. For example, the Google APIs Add-On lets you develop an application that takes advantage of the Google Maps external library. <br/><br/>6. Get started with an application project<br/><br/>Once you&#39;ve set up your SDK, the next step is to start a new application project o&#114; move existing applications into the new SDK.<br/><br/>If you are new to Android, you can use the Hello World tutorial to get started quickly. Next Steps offers other suggestions of how to begin. Welcome!<br/>]]></description>
		</item>
		
			<item>
			<link>http://www.wscxy.com/shosh/article.asp?id=123</link>
			<title><![CDATA[第三章： 进程同步机制]]></title>
			<author>shosh.zhu@qisda.com(shosh)</author>
			<category><![CDATA[操作系统]]></category>
			<pubDate>Sun,15 Nov 2009 02:52:52 +0800</pubDate>
			<guid>http://www.wscxy.com/shosh/default.asp?id=123</guid>
		<description><![CDATA[<p>第三章： 进程同步机制</p>
<p>3.1 信号量和P、V操作</p>
<p>信号量：表示资源使用情况的一种数据结构</p>
<pre>
struct{
	int n; //正数表示当前可用的资源个数，负数表示等待该种资源的进程个数
	PCB* pcbList; //等待该种资源的进程(PCB)列表
}
</pre>
<p>信号量的值仅由P、V操作来改变 </p>
<p>原语：机器指令的延生，往往是为完成某些特定功能而编制的一段系统程序，其操作具有不可分割性（一次性完成）</p>
<p>P操作P(S)：也叫wait操作，S为相应的信号量</p>
<pre>
S = S - 1;
if (S < 0)
{
    //资源不足，得不到分配的情况
    将本进程链入 S 的队尾；
    阻塞本进程；
}
else
{
    本进程继续执行；
}
</pre>
<p>V操作V(S): 也叫signal操作
<pre>
S = S + 1;
if (S > 0)
{
    //说明目前没有进场在等待该资源
    本进程继续执行；
}
else
{
    //说明有进程在等待该资源
    释放S队列上的第一个PCB；
    本进程继续执行；
}
</pre>
<p>3.2 同步机制的应用</p>
<p>使用PV操作实现进程互斥</p>
<ul>
  <li>在每个进程中，P(mutex)和V（mutex）必须成对出现，并且先P后V</li>
  <li>互斥信号量mutex的初值一般为1</li>
</ul>
<p>使用PV操作实现简单同步</p>
<p>例如 ： 供者和用者共同使用缓冲区的问题 </p>
<p>分析和解答：供者和用者两个需要合作来完成，它们之间的桥梁是缓冲区，它们之间的动作需要按照一定的先后顺序才能顺利进行，它们之间的关系是同步。临界资源是缓冲区，因为供者在向缓冲区写入数据的时候，用者不能从缓冲区读数据，同样，在缓冲区数据写满后，用者开始读缓冲区数据，这时供者不能往缓冲区里写数据，直到用者从缓冲区中取完数据。缓冲区有两个临界状态，一是空了，一是满了。使用两个信号量来表示，E表示空了的状态，F表示满了的状态，初始状态下缓冲区是空着的，所以E = 1, F = 0。对于供者，先用P操作获得空着的缓冲区，在写满数据之后，再用V操作释放一个满了的缓冲区的信号量；而用者则使用P操作获得写满的缓冲区，在取完数据之后，再用V操作释放清空的缓冲区的信号量。
所以供者的程序如下：
<br />P(E);
<br />写数据到缓冲区;
<br />V(F);
<br />
用者的程序如下：
<br />P(F);
<br />将缓冲区中的数据全部取走;
<br />V(E);</p>
<p>
不难理解为什么P操作又叫wait操作，而V操作又叫signal操作。因为P操作会确保获得满足信号量要求的临界资源，如果暂时没有，会等待直到其他进程释放出该临界资源并得到后再继续执行；V操作会释放出一种临界资源，发出一个信号，如果有其他进程在等待该资源，会将该资源交给队列最前面的那个进程。</p>
<p>这里有个比较容易混淆的问题：既然临界资源只有缓冲区一种，为什么使用两个信号量E和F？回顾一下什么是信号量,信号量并不代表临界资源，而是临界资源的状态，既然临界资源有两种状态空着和满了，就可以用两个信号量来表示。另外初始值E = 1表示有一个空着的缓冲区，而不是表示缓冲区是空着的，F = 0 表示没有满了的缓冲区，而不是表示缓冲区没有满（或者是空着的）。</p>

<p>使用PV操作的说明：</p>
<ul>
  <li>确定彼此关系和信号量种类</li>
  <li>设定信号量初值</li>
  <li>同一信号量的PV操作要成对出现，只是互斥的PV操作在同一进程中成对出现，而同步的PV操作在不同进程中成对出现。</li>
</ul>
<p>同步互斥的经典例子：生产者和消费者</p>
<p>生产者和消费者的问题和上面提到的供着和用者的例子类似，只是供着和用者只有一个缓冲区，而生产者和消费者有N个缓冲区，构成缓冲池。当N=1时候，本问题就成为了供者和用者的问题，可见，供者和用者的问题只是本问题的一个特例而已。</p>
<p>1、消费者只有在生产者生产出产品之后才能消费（缓冲池中有满的缓冲区时才可以让消费者从缓冲区取走产品消费）<br />
2、生产者在缓冲池满了以后要暂停生产，直到有空的缓冲区出现<br />
3、为避免混乱，生产者和消费者互斥使用缓冲池</p>
<p>上面的1、2点讲的就是供者和用者中提到的同步问题，第3点讲的是互斥问题。</p>
<p>同步问题同样设E和F两个信号量，E表示缓冲池中空缓冲区的数目，初始状态下E = 0; F表示缓冲池中满了的缓冲区的个数，初始状态下F = N。另外增加缓冲池的互斥信号量M， 初始状态下M = 1(表示只用一个缓冲池可供使用）</p>
<p>对于生产者，他要做的事情是：1、等待获得空缓冲区；2、等待获得缓冲池的使用权；3、往空缓冲区中放入产品；4、释放缓冲池使用权（通知缓冲池可以使用了）；5、通知新增一个满的缓冲区（一个新产品）</p>
<p>对于消费者，他要做的事情是：1、等待获得满的缓冲区；2、等待获得缓冲池的使用权；3、从满的缓冲区中取走产品；4、释放缓冲池使用权（通知缓冲池可以使用了）；5、通知新增一个空的缓冲区</p>

<p>生产者和消费者都要做5步动作，其中他们的第4步和第5步都是可以互换的，但是其他步骤是不能改变顺序的，尤其是第一步和第二步。如果第一步和第二步颠倒，很可能发生锁住的问题（死锁），导致生产者和消费者都不能往下进行。举个例子：假如消费者先获得了缓冲池的使用权，然后等待获得满的缓冲区，不过当时没有满的缓冲区，它就在一直占用缓冲池的情况下处于等待状态；而生产者因为得不到缓冲池的使用权，也无法让缓冲区变慢，这样消费者也就永远无法获得满的缓冲区（产品），于是生产者和消费者谁也干不了活了。不过有个原则是：互斥信号量的PV操作要成对出现在临界区的前后，所以第4步和第5步最好不要颠倒，既便于记忆，又避免出错。</p>
<p>上面的步骤中凡是使用了”等待获得“来描述的，都是P操作，要获得的东西是P操作的信号量；凡是用到了”释放“或”通知“的步骤都是V操作，释放或通知的东西就是V操作的信号量。</p>

<p>注意：</p>
<ul>
  <li>P(mutex)和V(mutex)分别出现在临界区的前后</li>
  <li>各信号量的P、V操作都要成对出现</li>
  <li>两个P操作的顺序不能颠倒</li>
</ul>]]></description>
		</item>
		
			<item>
			<link>http://www.wscxy.com/shosh/article.asp?id=122</link>
			<title><![CDATA[第二章： 进程概念]]></title>
			<author>shosh.zhu@qisda.com(shosh)</author>
			<category><![CDATA[操作系统]]></category>
			<pubDate>Sat,14 Nov 2009 17:54:22 +0800</pubDate>
			<guid>http://www.wscxy.com/shosh/default.asp?id=122</guid>
		<description><![CDATA[<p>第二章： 进程概念</p>
<p>2.1 进程的概念</p>
<p>资源的分配单位、并发执行的基本单位、能独立运行的单位</p>
<p>进程：程序在并发环境中的执行过程。</p>
<p>程序本身是具有顺序性的（顺序执行），它的并发执行是通过进程来实现的。</p>
<p>一个程序可由多个进程共用，一个进程可顺序执行多个程序。</p>
<p>特征：</p>
<ul>
    <li>动态性</li>
    <li>并发性</li>
    <li>调度性：资源的分配单位</li>
    <li>异步性：（走走停停）</li>
    <li>结构性： PCB</li>
</ul>
<p>进程的组成：</p>
<ul>
    <li>进程控制块PCB</li>
    <li>程序</li>
    <li>数据集合</li>
</ul>
<p>进程和PCB的关系：</p>
<ul>
    <li>每个进程有唯一的PCB</li>
    <li>OS依赖PCB管理进程</li>
    <li>利用PCB实现进程的动态和并发</li>
    <li>PCB是进程存在的唯一标志</li>
</ul>
<p>2.2 进程的状态及其转换</p>
<ul>
    <li>状态存在于PCB</li>
    <li>基本状态
    <ul>
        <li>运行态：分到CPU，真正在运行</li>
        <li>就绪态：万事具备，只差CPU</li>
        <li>阻塞态：等待设备资源</li>
    </ul>
    </li>
</ul>
<p>2.3 进程的同步与互斥</p>
<p>进程活动中会相互制约</p>
<ul>
    <li>所有进程均相互独立</li>
    <li>以异步方式并发执行</li>
</ul>
<p>同步：进程间共同完成一项任务时直接发生相互作用的关系</p>
<p>举例：供者和用者的关系（供者把数据放入缓冲区，用者从缓冲区提取数据）</p>
<p>说明：</p>
<ul>
    <li>同步进程间具有合作关系</li>
    <li>在执行顺序上须按照一定的顺序协调进行</li>
</ul>
<p>互斥：并发执行的多个进程由于竞争同一资源而产生的相互排斥的关系</p>
<p>说明：</p>
<ul>
    <li>互斥进程在逻辑上是完全无关的</li>
    <li>他们的运行不具有时间次序的特征（对同一资源的使用并无谁先谁后的规定）</li>
</ul>
<p>2.4 临界资源和临界区</p>
<p>临界资源（Critical Resource）：一次仅允许一个进程使用的共享资源（包含硬件资源和软件资源）</p>
<p>临界区（Critical Section）:在每个进程中访问临界资源的那段程序（简称CS区）</p>
<p>进入临界区的准则：</p>
<ul>
    <li>单一进入：进入临界区的进程在任何时候最多只能有一个</li>
    <li>独自占用：进入临界区的进程单独占用临界资源</li>
    <li>尽快退出：使用完临界资源后尽快释放临界资源并退出临界区</li>
    <li>等则让权：在等待临界资源的时候，需让出CPU使用权</li>
</ul>]]></description>
		</item>
		
			<item>
			<link>http://www.wscxy.com/shosh/article.asp?id=121</link>
			<title><![CDATA[第一章： 操作系统引论]]></title>
			<author>shosh.zhu@qisda.com(shosh)</author>
			<category><![CDATA[操作系统]]></category>
			<pubDate>Fri,13 Nov 2009 23:31:50 +0800</pubDate>
			<guid>http://www.wscxy.com/shosh/default.asp?id=121</guid>
		<description><![CDATA[<p>都是概念性的东西，稍微了解下即可。</p>
<p>操作系统的功能：</p>
<ul>
    <li>存储器管理
    <ul>
        <li>内存分配</li>
        <li>地址映射：把逻辑地址映射为内存的物理地址</li>
        <li>内存保护：各程序之间的内存如何做到不冲突</li>
        <li>内存扩充：提供虚拟内存</li>
    </ul>
    </li>
    <li>处理机管理
    <ul>
        <li>作业调度</li>
        <li>进程调度</li>
        <li>进程控制</li>
        <li>进程通信</li>
    </ul>
    </li>
    <li>设备管理
    <ul>
        <li>缓冲区管理</li>
        <li>设备分配</li>
        <li>设备驱动</li>
        <li>设备无关性：方便编程使用</li>
    </ul>
    </li>
    <li>文件管理
    <ul>
        <li>文件存储空间管理</li>
        <li>文件操作</li>
        <li>目录管理</li>
        <li>读写管理和存取控制</li>
    </ul>
    </li>
    <li>用户接口
    <ul>
        <li>命令界面</li>
        <li>程序界面</li>
        <li>图形界面</li>
    </ul>
    </li>
</ul>
<p>操作系统的特点：</p>
<ul>
    <li>并发（宏观上的，与并行相区分）</li>
    <li>共享</li>
    <li>异步</li>
</ul>
<p>操作系统的类型：</p>
<ul>
    <li>批处理系统：单道+多道（作业）批处理系统
    <ul>
        <li>多道批处理系统虽然多个作业成批进行，但是缺乏与用户的交互性</li>
    </ul>
    </li>
    <li>分时系统
    <ul>
        <li>分时：若干并发程序对CPU时间的共享</li>
        <li>多个用户终端共用主机</li>
        <li>特点：
        <ul>
            <li>同时性：多个用户同时使用</li>
            <li>交互：用户可控制程序的运行</li>
            <li>独立：用户感觉不到其它用户的存在，感觉自己在独立使用计算机</li>
            <li>及时：计算机对命令及时响应</li>
        </ul>
        </li>
    </ul>
    </li>
    <li>实时系统
    <ul>
        <li>响应时间更短，比分时系统的&ldquo;及时&rdquo;更为&ldquo;及时&rdquo;</li>
        <li>特点：
        <ul>
            <li>专用</li>
            <li>实时</li>
            <li>高可靠</li>
        </ul>
        </li>
    </ul>
    </li>
    <li>个人机系统
    <ul>
        <li>分类
        <ul>
            <li>单用户操作系统</li>
            <li>多用户操作系统</li>
        </ul>
        </li>
    </ul>
    </li>
    <li>网络操作系统
    <ul>
        <li>多个主机通过网络互联</li>
    </ul>
    <ul>
        <li>特征
        <ul>
            <li>分布式</li>
            <li>自治性：各台主机可自行运行</li>
            <li>互连性</li>
            <li>可见性：知道对方计算机地址</li>
        </ul>
        </li>
    </ul>
    </li>
    <li>分布式操作系统
    <ul>
        <li>特征
        <ul>
            <li>分布式处理</li>
            <li>模块化结构</li>
            <li>利用信息通信</li>
            <li>实施整体控制</li>
        </ul>
        </li>
        <li>特点
        <ul>
            <li>透明：不知道资源位于何处</li>
            <li>灵活：得益于模块化结构，系统的修改很方便</li>
            <li>可靠：一部分发生故障并不影响整体的使用</li>
            <li>高性能</li>
            <li>可扩充</li>
        </ul>
        </li>
    </ul>
    </li>
</ul>]]></description>
		</item>
		
</channel>
</rss>
