<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
<channel>
<title><![CDATA[我是程序员   -Shosh's Blog - brew开发]]></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=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=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=101</link>
			<title><![CDATA[TabWidget使用简介]]></title>
			<author>shosh.zhu@qisda.com(shosh)</author>
			<category><![CDATA[brew开发]]></category>
			<pubDate>Wed,25 Mar 2009 22:11:21 +0800</pubDate>
			<guid>http://www.wscxy.com/shosh/default.asp?id=101</guid>
		<description><![CDATA[<p>上一次为了给同仁们讲 BUIW 相关的 Training，用一张图总结了 TabWidget 的结构及其简单使用方法，这张图刚好被设计成了一个房屋的形状。 BUIW中的 form, widget 都是可扩展的，所以，为了满足各自的需求，基本上每个OEM厂家都会自己在高通的 BUIW 基础上进行扩展，所以各个OEM厂商之间应该是不同的。不过因为自己扩展的和高通提供的 TabWidget 在使用方法上很相似，所以在准备 TabWidget 的时候，没有做专门的区分。</p>
<p><img alt="" src="http://www.wscxy.com/shosh/attachments/month_0903/k2009325211825.jpg" /></p>
<p>从上图可以看出，使用 TabWidget 的时候，我们一般需要通过ISHELL_CreateInstance 的 TabWidget, VecterModel, CardContainer 的实例，然后通过 IWIDGET_SetModel 来建立 TabWidget 和 VectorModel之间的联系；使用I DECORATOR_SetWidget 来建立 TabWidget 和 CardContainer 之间的联系，不过，之前我们需要通过 IWIDGET_QueryInterface (第二个参数AEEIID_DECORATOR)来查询到 TabWidget 的 IDecorator 接口指针，通过ICARDCONTAINER_QueryInterface (第二个参数AEEIID_WIDGET)来查询到 IWidget 接口指针。接下来的事情就是准备数据了，使用IVECTORMODEL_Add 或 IVECTORMODEL_InsertAt&nbsp; 等&ldquo;函数&rdquo;往 VectorModel 中插入IMageStaticInfo结构类型的数据，使用ICARDCONTAINER_Insert 往CardContainer中插入创建好的Widget（要显示的内容，content widget，多数情况下是用 container 组装起来的，在这里形象地说成一张张 Card），这一张张的Card 是和 VectorModel 中的 ModelItem 是一一对应的。</p>]]></description>
		</item>
		
			<item>
			<link>http://www.wscxy.com/shosh/article.asp?id=90</link>
			<title><![CDATA[inline的一种特殊用法]]></title>
			<author>shosh.zhu@qisda.com(shosh)</author>
			<category><![CDATA[brew开发]]></category>
			<pubDate>Tue,24 Feb 2009 10:44:52 +0800</pubDate>
			<guid>http://www.wscxy.com/shosh/default.asp?id=90</guid>
		<description><![CDATA[<p>曾经我在一个c文件里用几个函数实现了一个比较Common的Functions，并提供一个对应的h文件让使用者<font color="#0000ff">#include</font>。接口如下：<br />
<br />
<font color="#008000">//please&nbsp;do&nbsp;not&nbsp;call&nbsp;these&nbsp;functions&nbsp;directly</font><br />
<font color="#0000ff">int</font>&nbsp;WriteTrace<font color="#800080"><b>(</b></font><font color="#0000ff">int</font>&nbsp;nLevel<font color="#4b0082">,</font>&nbsp;<font color="#0000ff">char</font><font color="#4b0082">*</font>&nbsp;pFile<font color="#4b0082">,</font>&nbsp;<font color="#0000ff">int</font>&nbsp;nLine<font color="#4b0082">,</font>&nbsp;<font color="#0000ff">char</font><font color="#4b0082">*</font>&nbsp;format<font color="#4b0082">,</font>&nbsp;<font color="#4b0082">...</font><font color="#800080"><b>)</b></font><font color="#4b0082">;</font><br />
<font color="#0000ff">void</font>&nbsp;EndWriteTrace<font color="#800080"><b>(</b></font><font color="#0000ff">void</font><font color="#800080"><b>)</b></font><font color="#4b0082">;</font><br />
<br />
这个Common的功能会在很多地方被人调用，但是它只在target端（真实运行环境）运行，而在simulator端（模拟运行环境，为方便调试加快编程速度而引入的模拟的运行环境）不需要<font color="#4b0082">/</font>无法运行该功能。所以我定义了下面一些宏，让用户通过宏来调用这些提供出来的接口：</p>
<p><font color="#008000">//please&nbsp;use&nbsp;these&nbsp;macros&nbsp;instead</font><br />
<font color="#0000ff">#ifdef</font>&nbsp;AEE_SIMULATOR&nbsp;<font color="#008000">//don't&nbsp;let&nbsp;it&nbsp;run&nbsp;in&nbsp;simulator</font><br />
&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">#define</font>&nbsp;TRACE_FILE<br />
&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">#define</font>&nbsp;END_TRACE<br />
<font color="#0000ff">#else</font><br />
&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">#define</font>&nbsp;TRACE_FILE&nbsp;WriteTrace<br />
&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">#define</font>&nbsp;END_TRACE&nbsp;&nbsp;EndWriteTrace<br />
<font color="#0000ff">#endif</font><br />
<br />
为了方便描述问题，模拟地写了一段代码：</p>
<p>&nbsp;</p>
<div id="shoCodeAreaWscxy">
<ol id="shoCodeMain107ID" style="border-right: gray 1px solid; padding-right: 2px; border-top: gray 1px solid; padding-left: 2px; padding-bottom: 2px; margin: 0px; border-left: gray 1px solid; color: #2f4f4f; word-break: break-all; padding-top: 2px; border-bottom: gray 1px solid; font-family: Courier New; list-style-type: decimal; background-color: #dcf5dc">
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black"><font color="#0000ff">int</font>&nbsp;WriteTrace<font color="#800080"><b>(</b></font><font color="#0000ff">int</font>&nbsp;nLevel<font color="#4b0082">,</font>&nbsp;<font color="#0000ff">int</font>&nbsp;add<font color="#800080"><b>)</b></font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black"><font color="#800080"><b>{</b></font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">return</font>&nbsp;nLevel&nbsp;<font color="#4b0082">+</font>&nbsp;add<font color="#4b0082">;</font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black"><font color="#800080"><b>}</b></font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black"><font color="#0000ff">void</font>&nbsp;EndWriteTrace<font color="#800080"><b>(</b></font><font color="#0000ff">void</font><font color="#800080"><b>)</b></font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black"><font color="#800080"><b>{</b></font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">return</font><font color="#4b0082">;</font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black"><font color="#800080"><b>}</b></font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black"><font color="#008000">//#define&nbsp;AEE_SIMULATOR</font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black"><font color="#0000ff">#ifdef</font>&nbsp;AEE_SIMULATOR&nbsp;<font color="#008000">//don't&nbsp;let&nbsp;it&nbsp;run&nbsp;in&nbsp;simulator</font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">#define</font>&nbsp;TRACE_FILE</span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">#define</font>&nbsp;END_TRACE</span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black"><font color="#0000ff">#else</font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">#define</font>&nbsp;TRACE_FILE&nbsp;WriteTrace</span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">#define</font>&nbsp;END_TRACE&nbsp;&nbsp;EndWriteTrace</span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black"><font color="#0000ff">#endif</font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa">&nbsp;</li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black"><font color="#0000ff">int</font>&nbsp;main<font color="#800080"><b>(</b></font><font color="#0000ff">void</font><font color="#800080"><b>)</b></font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black"><font color="#800080"><b>{</b></font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;TRACE_FILE<font color="#800080"><b>(</b></font><font color="#ff0000">1</font><font color="#4b0082">,</font>&nbsp;<font color="#ff0000">3</font><font color="#800080"><b>)</b></font><font color="#4b0082">;</font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;END_TRACE<font color="#800080"><b>()</b></font><font color="#4b0082">;</font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">return</font>&nbsp;<font color="#ff0000">0</font><font color="#4b0082">;</font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black"><font color="#800080"><b>}</b></font>&nbsp;</span></li>
</ol>
</div>
<p><br />
当AEE_SIMULATOR未被定义时，那么TRACE_FILE就是WriteTrace，END_TRACE就是EndWriteTrace，也就是前文提到的在target端运行，这样不存在任何问题，可以无错误无警告通过编译。但是如果定义了AEE_SIMULATOR，也就是想编译出在simulator上运行的代码，会发现会有一个错误。错误原因很容易发现，因为main函数体内第二行语句END_TRACE<font color="#800080"><b>()</b></font><font color="#4b0082">;</font>宏展开后的代码是<font color="#800080"><b>()</b></font><font color="#4b0082">;</font>，这句代码自然不可以编译通过了。那第一行TRACE_FILE<font color="#800080"><b>(</b></font><font color="#ff0000">1</font><font color="#4b0082">,</font>&nbsp;<font color="#ff0000">3</font><font color="#800080"><b>)</b></font><font color="#4b0082">;</font>宏展开后是<font color="#800080"><b>(</b></font><font color="#ff0000">1</font><font color="#4b0082">,</font>&nbsp;<font color="#ff0000">3</font><font color="#800080"><b>)</b></font><font color="#4b0082">;</font>为什么没有错误也没有警告呢？因为<font color="#800080"><b>(</b></font><font color="#ff0000">1</font><font color="#4b0082">,</font>&nbsp;<font color="#ff0000">3</font><font color="#800080"><b>)</b></font><font color="#4b0082">;</font>是C语言中的表达式（逗号运算，表达式的值是<font color="#ff0000">3</font>），就算是<font color="#800080"><b>(</b></font><font color="#ff0000">1</font><font color="#800080"><b>)</b></font><font color="#4b0082">;</font>&nbsp;也是C语言中的表达式（表达式的值是<font color="#ff0000">1</font>），没有错误。因为<font color="#800080"><b>(</b></font><font color="#0000ff">void</font><font color="#800080"><b>)</b></font><font color="#4b0082">;</font>不是表达式（<font color="#0000ff">void</font>不是值），所以就算将END_TRACE<font color="#800080"><b>()</b></font>改成END_TRACE<font color="#800080"><b>(</b></font><font color="#0000ff">void</font><font color="#800080"><b>)</b></font>也是不能通过编译的。<br />
<br />
要解决这样的问题，我最先想到了两种解决方案：<br />
<br />
<font color="#ff0000">1</font>、给END_TRACE添加一个无效的参数。对于target端，多了一个无效参数，有一定的资源浪费，不过影响小到可以忽略。<br />
<br />
<font color="#ff0000">2</font>、在simulator上实现一个空函数<font color="#0000ff">void</font>&nbsp;funNum<font color="#800080"><b>(</b></font><font color="#0000ff">void</font><font color="#800080"><b>)</b></font>，将END_TRACE定义为该函数的函数名funNum，这样做对target端无任何影响，但是simulator端多了一个空函数，加大了编译出来的文件，不过影响同样很小。关键是要添加空函数<font color="#0000ff">void</font>&nbsp;funNum<font color="#800080"><b>(</b></font><font color="#0000ff">void</font><font color="#800080"><b>)</b></font>的实现，当然最适合放在我提供的那个c文件里。不过这样需要增加工作量，在simulator的编译工程中也需要将该c文件编译进来，需要修改到dsp文件，而实际上我们不希望这样（在simulator上只需要包含h文件即可编译通过了，那c文件不需要编译，也不需要加到工程中）。<br />
<br />
后来想到了一个完美的方法，既解决了问题，又没有上面的问题。那就是在h文件中实现空函数<font color="#0000ff">void</font>&nbsp;funNum<font color="#800080"><b>(</b></font><font color="#0000ff">void</font><font color="#800080"><b>)</b></font>，不过得加关键字<font color="#0000ff">__inline</font>。 <br />
<br />
&nbsp;</p>
<ol id="shoCodeMain353ID" style="border-right: gray 1px solid; padding-right: 2px; border-top: gray 1px solid; padding-left: 2px; padding-bottom: 2px; margin: 0px; border-left: gray 1px solid; color: #2f4f4f; word-break: break-all; padding-top: 2px; border-bottom: gray 1px solid; font-family: Courier New; list-style-type: decimal; background-color: #dcf5dc">
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black"><font color="#008000">//-------------in&nbsp;.c&nbsp;file------------------------//</font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black"><font color="#0000ff">int</font>&nbsp;WriteTrace<font color="#800080"><b>(</b></font><font color="#0000ff">int</font>&nbsp;nLevel<font color="#4b0082">,</font>&nbsp;<font color="#0000ff">int</font>&nbsp;add<font color="#800080"><b>)</b></font>&nbsp;</span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black"><font color="#800080"><b>{</b></font>&nbsp;</span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">return</font>&nbsp;nLevel&nbsp;<font color="#4b0082">+</font>&nbsp;add<font color="#4b0082">;</font>&nbsp;</span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black"><font color="#800080"><b>}</b></font>&nbsp;</span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black"><font color="#0000ff">void</font>&nbsp;EndWriteTrace<font color="#800080"><b>(</b></font><font color="#0000ff">void</font><font color="#800080"><b>)</b></font>&nbsp;</span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black"><font color="#800080"><b>{</b></font>&nbsp;</span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">return</font><font color="#4b0082">;</font>&nbsp;</span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black"><font color="#800080"><b>}</b></font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black">&nbsp;</span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black"><font color="#008000">//---------in&nbsp;.h&nbsp;file&nbsp;that&nbsp;for&nbsp;users&nbsp;to&nbsp;include------//</font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black"><font color="#0000ff">__inline</font>&nbsp;<font color="#0000ff">void</font>&nbsp;FuncName<font color="#800080"><b>(</b></font><font color="#0000ff">void</font><font color="#800080"><b>)</b></font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black"><font color="#800080"><b>{</b></font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;<font color="#008000">//this&nbsp;function's&nbsp;just&nbsp;empty&nbsp;for&nbsp;special&nbsp;usage</font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black"><font color="#800080"><b>}</b></font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black"><font color="#008000">//#define&nbsp;AEE_SIMULATOR&nbsp;</font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black"><font color="#0000ff">#ifdef</font>&nbsp;AEE_SIMULATOR&nbsp;<font color="#008000">//don't&nbsp;let&nbsp;it&nbsp;run&nbsp;in&nbsp;simulator&nbsp;</font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">#define</font>&nbsp;TRACE_FILE&nbsp;</span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">#define</font>&nbsp;END_TRACE&nbsp;FuncName</span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black"><font color="#0000ff">#else</font>&nbsp;</span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">#define</font>&nbsp;TRACE_FILE&nbsp;WriteTrace&nbsp;</span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">#define</font>&nbsp;END_TRACE&nbsp;&nbsp;EndWriteTrace&nbsp;</span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black"><font color="#0000ff">#endif</font>&nbsp;</span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black">&nbsp;</span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black"><font color="#008000">//------------in&nbsp;test.c&nbsp;file------------//</font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black"><font color="#0000ff">int</font>&nbsp;main<font color="#800080"><b>(</b></font><font color="#0000ff">void</font><font color="#800080"><b>)</b></font>&nbsp;</span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black"><font color="#800080"><b>{</b></font>&nbsp;</span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;TRACE_FILE<font color="#800080"><b>(</b></font><font color="#ff0000">1</font><font color="#4b0082">,</font>&nbsp;<font color="#ff0000">3</font><font color="#800080"><b>)</b></font><font color="#4b0082">;</font>&nbsp;</span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;END_TRACE<font color="#800080"><b>()</b></font><font color="#4b0082">;</font>&nbsp;</span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">return</font>&nbsp;<font color="#ff0000">0</font><font color="#4b0082">;</font>&nbsp;</span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black"><font color="#800080"><b>}</b></font>&nbsp;&nbsp;</span></li>
</ol>
<p>&nbsp;</p>]]></description>
		</item>
		
			<item>
			<link>http://www.wscxy.com/shosh/article.asp?id=87</link>
			<title><![CDATA[Shosh谈手机的发展]]></title>
			<author>shosh.zhu@qisda.com(shosh)</author>
			<category><![CDATA[brew开发]]></category>
			<pubDate>Thu,19 Feb 2009 13:47:50 +0800</pubDate>
			<guid>http://www.wscxy.com/shosh/default.asp?id=87</guid>
		<description><![CDATA[<p>昨晚有朋友问我：&ldquo;手机行业已入夕阳，我们这些做手机开发的将何去何从？&rdquo;<br />
之前尚未细想，现在来谈谈敝人的一点看法。如需转载，请保留作者信息：Shosh，http://www.wscxy.com，2009年2月19日。</p>
<p>在手机之前，是固定电话。固定电话需要放在固定的位置，如家里或办公室。而人是需要经常移动的，这样就会存在找不到人或错过一些电话的缺点。手机正是通过其移动性来解决该问题的产物。最开始的时候，手机很大，携带相当不便，且功能很少（当时设计的需求估计focus在能够接听拨打电话上），价格却相当昂贵。不过那个时候能够拥有这样一部手机的人是相当酷的，所以名字也很酷，叫&ldquo;大哥大&rdquo;，颇有黑社会老大的味道在里面。<br />
新事物一旦诞生，如果它具有生命力，它的发展就会相当迅速。人们开始不满足于黑白屏幕，开始不满足于光打电话光发短信。随着液晶屏幕技术上的发展，彩屏慢慢进入了人们的视野。而在手机功能上，电子书、音乐、广播、视频、相机、摄像以及蓝牙红外等短距离通信等功能和其他一些辅助功能（如日历、闹钟等）也日趋丰富，曾经就有很多款手机主打音乐旗帜拉动消费；而最近手机又融入了GPS导航、信息同步、计步感应器、手机上网等功能。我们老大曾经说过一句话，一点也不错：电脑的今天就是手机的明天。手机的发展确实紧随电脑的发展，而智能手机则让手机更加接近电脑。电脑上有鼠标，而手机没有鼠标，于是随着触摸技术的发展，很多手机配上了触摸屏，而Apple的手机（iPhone）更是使用了多点触控技术，凭借其独到的设计和绚丽的屏幕以及Apple自身所具有的品牌影响力，赢得了不少顾客和广大的追随者、赞赏者（触控技术是一项让手机赢过桌面电脑率先使用的技术，其实它在多功能查询机、ATM存/取款机等设备上早有应用）。可以说，目前手机上该有的功能都已经具备，只剩下各家运营商想破脑袋想出来的各种用来诱惑消费者来使用他们的网络成为他们的客户的功能还可以推陈出新了。</p>
<p>总体来说，以本人的理解和概括，随着高速网络的普及和高性能手机硬件的支持，手机最近及未来几年内的发展主要有以下几个方面：<br />
1、动画效果应用将更加广泛，手机的UI将变得更加绚丽。<br />
最近在评估一些新的案子，要求里的动画效果相当绚丽，绝对超过Apple手机（iPhone）的。不过如果不用flash，不用3D引擎，即使对BUIW再熟悉，纯粹用BUIW，纯粹用C Code，除了代码冗长、维护困难，恐怕效果也会不理想。不过这肯定是一个方向，最近接到的案子，动画效果都很炫。工程开发的时候，应该将这部分架构好，而不应该碰到一个效果，从头开始设计一个。<br />
2、随着3G网络的普及，视频通话、流媒体在线收看、手机电视、在线游戏等将得到应用。<br />
其实几年前，就算在电脑上想在线收看一部电影，也是相当困难的，尤其是免费的。两三年前，将Flash视频嵌入到网页中才使越来越多的视频资源在网络上免费呈现，随后各种在线点播系统、各种现在播放软件纷纷出现，就连一向在媒体播放领域大名顶顶的暴风影音也开始将在其播放器中加入在线播放的功能。其实目前，很多手机已经具备视频通话的功能，只是需要网络的支持。高速的3G网络普及后，如果这些功能的价位低廉，它们将得到广泛应用。所以程序员往这个方向发展，应该是一条不错的路子。<br />
3、3D游戏也将会在手机中出现。<br />
3D游戏在电脑上倒很早就已出现，而手机上的游戏到目前为止基本上都是简单的2D游戏。但本人觉得，等到时机成熟，3D游戏战火必将延伸到手机，而且很可能以网络游戏的形式出现。不过受其屏幕大小和操作不便的限制，手机游戏还是会很简单，不可能像电脑上的某些需要高操作性的游戏那么复杂。<br />
4、声控技术有可能在几年后得到应用。<br />
声控技术，就是使用声音来控制一定的设备的一种技术，如使用声音来控制个人电脑或机器人等。这个似乎还很遥远，因为桌面电脑上都还不成熟（有在尝试）。不过微软正在努力将他的操作系统开发成可以脱离鼠标键盘但仍能方便操作的系统，比如采用触摸屏，而另一种方法就是使用声控（两种方法并不冲突，应该会同步发展）。用户可以通过嘴巴说出口令来操作计算机，而打字，也将会变得只是动动嘴巴而已。不过这涉及到声音识别的准确性问题，桌面系统上都还不成熟，要在手机上应用，还需要较长的一段时间。</p>
<p>总之一句话：手机的今天就是电脑的昨天，手机的明天就是电脑的今天。发展还在继续，就看会发展成什么样子了。以上看法尚不成熟，如若有不对的地方，望勿见笑。</p>]]></description>
		</item>
		
			<item>
			<link>http://www.wscxy.com/shosh/article.asp?id=86</link>
			<title><![CDATA[BUIW中的HTMLWidget]]></title>
			<author>shosh.zhu@qisda.com(shosh)</author>
			<category><![CDATA[brew开发]]></category>
			<pubDate>Wed,18 Feb 2009 11:08:13 +0800</pubDate>
			<guid>http://www.wscxy.com/shosh/default.asp?id=86</guid>
		<description><![CDATA[<p>在BREW UI的开发中，很少会用到HTMLWidget。它本该在浏览器等程序中使用到，不过现在需要让一个提示FORM能够显示图文混排的效果，从而想到了使用HTMLWidget。第一次使用，当然想测试测试它对HTML的支持情况了。</p>
<p><img alt="" src="http://www.wscxy.com/shosh/attachments/month_0902/y2009218104826.jpg" /></p>
<p>对应的HTML代码在宏HTMLSTR中定义：</p>
<p>#define HTMLSTR &quot;&lt;font color=green&gt;hello&lt;/font&gt;,&lt;img src=fs:/bad.gif&gt; \<br />
&nbsp;&nbsp;&lt;b&gt;Sh&lt;font color=red&gt;o&lt;/font&gt;sh&lt;/b&gt;,&lt;br&gt; &lt;img src=fs:/test.bmp&gt; \<br />
&nbsp;&nbsp;&lt;font color=blue size=6&gt;wel&lt;/font&gt;&lt;font color=red&gt;com&lt;sup&gt;e&lt;/sup&gt;&lt;/font&gt;&lt;i&gt;!&lt;/i&gt;&lt;br&gt; \<br />
&nbsp;&nbsp;&lt;input type=text value=enter&gt;&lt;input type=button value=yes size=4&gt;&quot;</p>
<p>从效果来看，还是有很多是不能够支持的，比如斜体，比如sup等（另外css一点也不支持）。并且因为sup的开始导致font的提前结束。</p>
<p>而图片，虽然有显示，但是不是我所指定的图片。看来HTMLWidget是支持图片的显示的，只是不认fs这样的URL（在brew中，都是用&ldquo;fs：/&rdquo;去访问efs中的文件的）。</p>
<p>在IE浏览器的显示效果为（将图片路径设置正确后）：</p>
<p><img alt="" src="http://www.wscxy.com/shosh/attachments/month_0902/d2009218105734.jpg" /></p>
<p>测试代码为：</p>
<ol id="shoCodeMain87ID" style="border-right: gray 1px solid; padding-right: 2px; border-top: gray 1px solid; padding-left: 2px; padding-bottom: 2px; margin: 0px; border-left: gray 1px solid; color: #2f4f4f; word-break: break-all; padding-top: 2px; border-bottom: gray 1px solid; font-family: Courier New; list-style-type: decimal; background-color: #dcf5dc">
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">do</font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#800080"><b>{</b></font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IModel&nbsp;<font color="#4b0082">*</font>pDocModel&nbsp;<font color="#4b0082">=</font>&nbsp;NULL<font color="#4b0082">;</font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">int</font>&nbsp;nNumWritten&nbsp;<font color="#4b0082">=</font>&nbsp;<font color="#ff0000">0</font><font color="#4b0082">;</font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pMe&nbsp;<font color="#4b0082">=</font>&nbsp;<font color="#800080"><b>(</b></font>CalcMainForm<font color="#4b0082">*</font><font color="#800080"><b>)</b></font>&nbsp;MALLOC<font color="#800080"><b>(</b></font><font color="#0000ff">sizeof</font><font color="#800080"><b>(</b></font>CalcMainForm<font color="#800080"><b>))</b></font><font color="#4b0082">;</font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BREAKIFNULL_FATAL<font color="#800080"><b>(</b></font>pMe<font color="#4b0082">,</font><font color="#800000">&quot;Fail:&nbsp;%d&quot;</font><font color="#800080"><b>)</b></font><font color="#4b0082">;</font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ISHELL_AddRef<font color="#800080"><b>(</b></font>pIShell<font color="#800080"><b>)</b></font><font color="#4b0082">;</font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pMe<font color="#4b0082">-&gt;</font>pIShell&nbsp;<font color="#4b0082">=</font>&nbsp;pIShell<font color="#4b0082">;</font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ISHELL_CreateInstance<font color="#800080"><b>(</b></font>pMe<font color="#4b0082">-&gt;</font>pIShell<font color="#4b0082">,</font>&nbsp;AEECLSID_HTMLWIDGET<font color="#4b0082">,</font>&nbsp;<font color="#800080"><b>(</b></font><font color="#0000ff">void</font><font color="#4b0082">**</font><font color="#800080"><b>)</b></font><font color="#4b0082">&amp;</font>pMe<font color="#4b0082">-&gt;</font>pHTMLWidget<font color="#800080"><b>)</b></font><font color="#4b0082">;</font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black">&nbsp;</span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black"><font color="#0000ff">#define</font>&nbsp;HTMLSTR&nbsp;<font color="#800000">&quot;&lt;font&nbsp;color=green&gt;hello&lt;/font&gt;,&lt;img&nbsp;src=fs:/bad.gif&gt;&nbsp;\</font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black"><font color="#800000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;b&gt;Sh&lt;font&nbsp;color=red&gt;o&lt;/font&gt;sh&lt;/b&gt;,&lt;br&gt;&nbsp;&lt;img&nbsp;src=fs:/test.bmp&gt;&nbsp;\</font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black"><font color="#800000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;font&nbsp;color=blue&nbsp;size=6&gt;wel&lt;/font&gt;&lt;font&nbsp;color=red&gt;com&lt;sup&gt;e&lt;/sup&gt;&lt;/font&gt;&lt;i&gt;!&lt;/i&gt;&lt;br&gt;&nbsp;\</font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black"><font color="#800000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;input&nbsp;type=text&nbsp;value=enter&nbsp;color=#358879&gt;&lt;input&nbsp;type=button&nbsp;value=yes&nbsp;size=4&gt;&quot;</font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black">&nbsp;</span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IWIDGET_GetModel<font color="#800080"><b>(</b></font>pMe<font color="#4b0082">-&gt;</font>pHTMLWidget<font color="#4b0082">,</font>&nbsp;AEEIID_DOCMODEL<font color="#4b0082">,</font>&nbsp;<font color="#800080"><b>(</b></font>IModel&nbsp;<font color="#4b0082">**</font><font color="#800080"><b>)(</b></font><font color="#0000ff">void</font>&nbsp;<font color="#4b0082">**</font><font color="#800080"><b>)</b></font><font color="#4b0082">&amp;</font>pDocModel<font color="#800080"><b>)</b></font><font color="#4b0082">;</font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><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="#800080"><b>(</b></font>NULL&nbsp;<font color="#4b0082">!=</font>&nbsp;pDocModel<font color="#800080"><b>)</b></font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#800080"><b>{</b></font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><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;IDOCMODEL_Write<font color="#800080"><b>(</b></font>pDocModel<font color="#4b0082">,</font>&nbsp;HTMLSTR<font color="#4b0082">,</font>&nbsp;STRLEN<font color="#800080"><b>(</b></font>HTMLSTR<font color="#800080"><b>)</b></font><font color="#4b0082">,</font>&nbsp;<font color="#4b0082">&amp;</font>nNumWritten<font color="#800080"><b>)</b></font><font color="#4b0082">;</font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><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;DBGPRINTF<font color="#800080"><b>(</b></font><font color="#800000">&quot;nNumWritten&nbsp;=&nbsp;%d&quot;</font><font color="#4b0082">,</font>&nbsp;nNumWritten<font color="#800080"><b>)</b></font><font color="#4b0082">;</font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><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;IDOCMODEL_WriteTerminate<font color="#800080"><b>(</b></font>pDocModel<font color="#800080"><b>)</b></font><font color="#4b0082">;</font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#800080"><b>}</b></font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ISHELL_CreateInstance<font color="#800080"><b>(</b></font>pMe<font color="#4b0082">-&gt;</font>pIShell<font color="#4b0082">,</font>AEECLSID_Q_FORM<font color="#4b0082">,</font><font color="#800080"><b>(</b></font><font color="#0000ff">void</font><font color="#4b0082">**</font><font color="#800080"><b>)</b></font><font color="#4b0082">&amp;</font>pMe<font color="#4b0082">-&gt;</font>pIForm<font color="#800080"><b>)</b></font><font color="#4b0082">;</font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IFORM_SetWidget<font color="#800080"><b>(</b></font>pMe<font color="#4b0082">-&gt;</font>pIForm<font color="#4b0082">,</font>&nbsp;WID_FORM<font color="#4b0082">,</font>&nbsp;pMe<font color="#4b0082">-&gt;</font>pHTMLWidget<font color="#800080"><b>)</b></font><font color="#4b0082">;</font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black"><font color="#008000">/*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black"><font color="#008000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HANDLERDESC_Init(&amp;pMe-&gt;CalcMainFormHandler,&nbsp;</font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black"><font color="#008000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CalcMainForm_HandleEvent,</font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black"><font color="#008000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pMe,</font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black"><font color="#008000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CalcMainForm_Free);</font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black"><font color="#008000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black"><font color="#008000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//Setting&nbsp;the&nbsp;handler&nbsp;for&nbsp;the&nbsp;Form//</font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black"><font color="#008000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IFORM_SetHandler(pMe-&gt;pIForm,&amp;pMe-&gt;CalcMainFormHandler);</font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black"><font color="#008000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bHandlerSet&nbsp;=&nbsp;TRUE;</font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black"><font color="#008000">*/</font></span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#4b0082">*</font>ppObj<font color="#4b0082">=</font>pMe<font color="#4b0082">-&gt;</font>pIForm<font color="#4b0082">;</font>&nbsp;&nbsp;&nbsp;&nbsp;</span></li>
    <li style="padding-left: 6px; margin: 0px 0px 0px 50px; border-left: silver 2px ridge; line-height: 18px; background-color: #f5fffa"><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#800080"><b>}</b></font>&nbsp;<font color="#0000ff">while</font>&nbsp;<font color="#800080"><b>(</b></font>FALSE<font color="#800080"><b>)</b></font><font color="#4b0082">;</font>&nbsp;</span></li>
</ol>]]></description>
		</item>
		
			<item>
			<link>http://www.wscxy.com/shosh/article.asp?id=84</link>
			<title><![CDATA[手机开发平台指南、教程和资料介绍(转载)]]></title>
			<author>shosh.zhu@qisda.com(shosh)</author>
			<category><![CDATA[brew开发]]></category>
			<pubDate>Tue,10 Feb 2009 11:19:01 +0800</pubDate>
			<guid>http://www.wscxy.com/shosh/default.asp?id=84</guid>
		<description><![CDATA[<p>欢迎转载，转载请注明出处。作者：手机即信息 博客：http://canco.javaeye.com</p>
<p>近来无事，把手机开发平台的学习指南、教程和资料总结一下，方便大家参考。<br />
手机客户端软件开发最大的困难就是平台不统一，手机开发平台太多。<br />
手机可分为智能手机开发和feather phone手机。开发平台可分为开放式平台和封闭式平台，开放式平台包括symbian、windows mobile、linux、iPhone、Android、BlackBerry、j2me、brew等，支持手机应用程序通过OTA下载和安装；封闭式平台包括MTK、展讯、TI、飞利浦等。下面分别介绍。<br />
1． Symbian：<br />
Symbian平台为目前智能手机市场的老大，智能手机全球市场占70%以上，在欧洲和亚洲占绝对优势，只是在美国市场份额少得可怜，希望今年nokia在美国发力，赶上其它智能手机。根据UI风格的不同，Symbian分为s60和UIQ两个平台，其中nokia使用s60平台，索爱和moto采用UIQ平台。Symbian平台由于发展时间较长，又是市场老大，目前中文资料也较多，不像几年前刚接触时只有英文资料。以下书籍值得推荐：<br />
《SYMBIAN OS软件开发开发&ndash;应用C++开发智能手机应用程序入门》（其中UI部分为UIQ平台），<br />
《Series 60 应用程序开发》（以s60平台为主，重点推荐）<br />
《Symbian OS C++手机应用开发 （第2卷）》<br />
另外今年将出来一本有关uiq3.0的新书，值得期待。<br />
关于symbian的开发网站和论坛：<br />
诺基亚论坛：最好的symbian论坛，<br />
http://discussion.forum.nokia.com/forum/forumdisplay.php?f=6，其中还有中文论坛。<br />
UIQ官方论坛：http://developer.uiq.com/<br />
Symbian公司中文论坛：http://developer.symbian.com/forum/forum.jspa?forumID=37<br />
NewLC网站：http://www.newlc.com/<br />
索爱uiq官方论坛：http://developer.sonyericsson.com/category.jspa?categoryID=3<br />
索爱uiq中文论坛http://developer.sonyericsson.com/forum.jspa?forumID=133</p>
<p>2．windows mobile：<br />
智能手机全球市场中windows mobile占12%左右市场份额。开发与windows平台类似，所以熟悉windows开发的能很快上手。目前没有较好的针对windows mobile的书，经典书籍《Windows 程序设计（第5版）》对于开发win32程序依然是最好的，经典的书就是牛啊！虽然pocket pc支持MFC，但smartphone不支持，所以为了更好的移植，用win32开发较好。由本书做基础，再参考windows mobile的sdk以及示例代码，应该能很快上手。<br />
关于windows mobile的开发网站和论坛：<br />
Windows mobile中文社区：http://www.winbile.net/BBS/<br />
Pocket pc forum：http://www.windowsmobiledn.com/forum/<br />
微软官方网站：http://www.microsoft.com/windowsmobile/developers/default.mspx</p>
<p>3． linux：<br />
智能手机全球市场中linux手机仅占可怜的4.4%市场份额。原来moto还出过不少linux手机，如A768、A1200、E680、E2、E6、 V8等，07年8月份还信誓旦旦预测60%手机采用Linux OS，但moto后来回购了UIQ的股份，又与微软合作，还加入了google的开放手机联盟，看来要抛弃自己的linux平台了。另外，moto的策略是linux+j2me的模式，虽然采用linux os，但并不对外开放linux的sdk，只有和moto合作的厂家才能获得native linux sdk，所以导致目前linux手机开发的资料和论坛较少。虽然有民间linux高手破解了moto的linux的sdk，可以开发native linux的程序，但native linux的程序不能直接安装在moto的linux手机上，还必须安装一个插件，这对普通用户又是难以跨越的一个门槛。所以个人觉得native linux手机的开发将走向末路。大部分linux手机的ui开发都是基于QT，关于QT开发，可参考《C++ GUI Qt3编程》、《精通Qt4编程》，如果有moto官方的sdk，参考API文档以及一些示例代码，将可以较快上手，如果没有官方的sdk，那就要话很长时间hack了。目前没有很好的关于linux手机开发的论坛，个人推荐陈罡的博客http://www.cublog.cn/u/26691/，内有moto a1200开发随笔，对于熟悉和了解手机native linux开发有很大帮助。</p>
<p>4． MTK：<br />
MTK最近几年异军突起，近70%的国产手机采用MTK的芯片和平台，黑手机更几乎是MTK的代名词。国内厂家只有夏新没有采用MTK的方案。MTK的模式名为&ldquo;Turn-key&rdquo;的全面解决方案，厂商采用了这个方案，只需要加一个手机外壳即可成品&mdash;&mdash;这能大大降低了出货时间，一般厂家只修改界面、铃声以及增加一些应用软件。有关MTK平台的介绍，见环球企业家杂志的文章&ldquo;国产手机操纵者联发科的秘密&rdquo;http://www.cnbeta.com/articles/45580.htm。<br />
MTK是私有平台，目前没有书籍介绍MTK平台，所以只能从网上查找MTK的资料。以下资料大家可以从网上获得，对于了解MTK很有帮助：《mtk 训练课程.pdf》、《MMI Platform Source Code Training.pdf》主要是MMI界面开发介绍、《MMI Resource &amp; Customization Tool.pdf》MMI资源工具介绍。<br />
最近，MTK平台ＭＭＩ设计牛人ＦＵＧＵＩ自己编写了一本有关mtk平台MMI开发的实例教程，书名为《MMI实例培训教程》（本书大家通过Google 下载到），此书深入浅出，全面的介绍了MTK平台MMI开发的各个方面，通过本书，开发人员将能很快进入MTK平台开发领域，实为MTK平台MMI开发的圣经！MTK平台的操作系统为nucleus，有关nucleus的介绍网上有一篇文章《Nucleus实时操作系统分析报告》。MTK平台主要用C语言开发，所以要熟悉MTK开发，首先必须熟悉掌握C语言，MTK的sdk与vc6集成，MMI的各控件和窗口之间通过回调函数实现通讯。<br />
关于MTK的开发网站和论坛：<br />
我爱研发网：http://www.52rd.com/ 上面几篇文章和书籍都能从本网站找到。<br />
手机研发论坛：http://www.1mp.cc/bbs/index.asp</p>
<p>5． 展讯：<br />
展讯平台07年也发展很快，利用MTK下半年PA放大器缺货的机会，趁势而入，抢走mtk很多市场份额。展讯的开发模式和MTK的很类似，基本也是给厂家提供整体解决方案，与MTK的差别见此链接http://www.chinabyte.com/telecom/267/2507267.shtml。国内主要是夏新、联想、文泰等采用展讯平台。展讯平台采用的嵌入式操作系统是threadx，关于threadx的有一本中文书《嵌入式实时操作系统的多线程计算：基于ThreadX和ARM》。同MTK平台一样，为封闭平台，开发语言为C，开发环境为vc6, MMI的各控件和窗口之间与windows类似通过消息进制实现通讯。另外也没有书籍介绍展讯平台，以下资料值得推荐：<br />
《Spreadtrum_SAP.ppt》<br />
《MMK_Kernel软件API接口说明书.doc》<br />
《MMK_Window_Table开发说明书.doc》<br />
《展讯平台MMI窗口开发说明书.pdf》<br />
《展讯手机平台软件简介.pdf》<br />
关于展讯的开发网站和论坛：<br />
我爱研发网：http://www.52rd.com/ 上面几篇文章都能从本网站找到。<br />
手机研发论坛：http://www.1mp.cc/bbs/index.asp</p>
<p>6． J2ME：<br />
J2ME平台为手机上运用最广泛的开放式平台，绝大部分手机均已经支持J2ME了。关于J2ME的书籍数不胜数，个人推荐以下书籍：<br />
《j2me技术手册》<br />
《J2ME开发大全》<br />
《J2ME移动应用程序开发》<br />
关于J2ME的开发网站和论坛：<br />
J2ME开发网：http://www.j2medev.com/Index.html<br />
中国Java手机网：http://www.cnjm.net/<br />
以及各手机厂商的官方java论坛</p>
<p>7． Brew<br />
Brew 的全称是无线二进制运行时环境。Brew平台是高通公司开发的，从无线应用程序开发、设备配置、应用程序分发以及计费和支付的完整端到端解决方案中的无线应用程序开发部分。目前绝大部分CDMA手机都支持Brew平台。学习Brew平台，首先需要熟悉c语言。学习步骤和方法可参考&rdquo; BREW高手之路－解析BREW学习过程&rdquo;。<br />
学习书籍：<br />
《深入BREW手机游戏开发》<br />
《BREW 技术开发与应用》<br />
这些书虽然不够深入，但对于入门还是可以参考的。<br />
关于Brew的开发网站和论坛：<br />
Brew官方论坛：http://brewforums.qualcomm.com/index.php</p>
<p>8. iPhone<br />
Windows平台iPhone开发环境搭建方法见笔者的文章《Windows平台上iPhone基于cygwin开发环境的搭建方法》<br />
http://canco.javaeye.com/admin/blogs/199106</p>
<p>开发入门介绍见笔者的文章《iPhone手机开发平台入门介绍和教程》<br />
http://canco.javaeye.com/admin/blogs/199144</p>
<p>9． Blackberry，Android<br />
黑莓公司BlackBerry手机和Google的Android手机均只支持java开发。BlackBerry的开发网站和论坛：<br />
BlackBerry开发者指南：http://www.cnblogs.com/confach/category/36451.htmlBlackBerry官方网站：http://na.blackberry.com/eng/developers/community.jsphttp://bbs.maxpda.com/forum-184-1.html<br />
Android的开发网站和论坛：<br />
http://www.androiddev.net.cn/bbs/<br />
http://www.androidin.com/http://www.androidcn.net/<br />
http://bbs.maxpda.com/forum-190-1.html</p>
<p>10． 其它Feather phone平台<br />
其它feather phone平台，如TI、飞利浦、英飞凌（Infineon）、飞思卡尔（Freescale）、Broadcom、Skyworks等平台，由于平台私有，并且不提供第三方sdk，所以也没有相关资料和文档，希望有了解的朋友介绍一下。</p>]]></description>
		</item>
		
			<item>
			<link>http://www.wscxy.com/shosh/article.asp?id=80</link>
			<title><![CDATA[EVB &amp; EVT Porting Experience Sharing]]></title>
			<author>shosh.zhu@qisda.com(shosh)</author>
			<category><![CDATA[brew开发]]></category>
			<pubDate>Tue,06 Jan 2009 11:55:43 +0800</pubDate>
			<guid>http://www.wscxy.com/shosh/default.asp?id=80</guid>
		<description><![CDATA[<p>前一阵子在做EVB/EVT的Porting，碰到了不少问题，多亏各路高手（platform的，PS的，MMI的都有）各施绝技，才帮助我最终完成任务。在此感谢他们！</p>
<p>EVB：其实我也不知道这三个字母是哪些单词的缩写，不过这个不重要，其实就是手机里面的硬件设备放到一块板子上，再写入正确的software load之后能够运行代码。该板子比最后我们要生产出来的手机要大不少，因为这样可以简化硬件布局设计和生产时间，使用起来也比较方便。它包含了一个手机需要包含的大多数硬件设备，但是某些功能模块可能没有完成，在该板子上，我们主要测试正常开机和一些比较简单的APP。有特殊要求的一些APP，比如call,bt,往往会因为硬件环境没准备好而无法执行。</p>
<p><br />
EVT：EVT其实和EVB一样，只是这块板在大小上和布局上，更像手机了。我曾戏称&ldquo;EVT就是更像手机的EVB&rdquo;来解释EVT。因为EVT更小，但是同样没有手机外壳的支撑保护，所以使用的时候要特别小心，不然它的哪根&ldquo;神经&rdquo;（线路）断了都不一定知道。</p>
<p><br />
EVB/EVT Porting：刚才介绍的EVB/EVT是从硬件层面上的，有些计算机里的&ldquo;裸机&rdquo;的概念。其实我要完成的EVB/EVT Porting任务，就是将特定的project source编译出来的image（主要是那些mbn文件）load到EVB/EVT中，然后开机，让它正确地跑到Idle（可以理解成计算机里的桌面），进而进入各个App。所以这里有两个关键的任务：1.能够正确build出来；2.开机流程正确，可以正确跑进Idle。</p>
<p><br />
第一步：build通过</p>
<p>其实只是让它编译链接通过，没有什么特别的，只是很费时间而已。build主要的两个阶段编译和链接，编译阶段的错误多数只是语法上的，将发现的错误一个个改正再编译就没有问题了，只是需要时间而已；链接阶段的错误多数是要么找不到某个符号，要么有多个符号，导致不知道用哪个来链接（这里的符号指一些函数和全局的变量）。这里倒有几个经验技巧和大家分享。</p>
<p>1. 如果在编译阶段中途手动停掉编译，需要注意将正在编译的源文件生成的对应对象文件（.o文件）删除，否则下一次编译成功后很可能会链接不过。这是编译原理决定的：在编译阶段，每个源文件(c/cpp)会对应生成一个.o文件，在链接阶段，会将这些.o文件链接在一起。而默认情况下，为了缩短编译时间，并不会直接去将每个源文件都编译生成.o文件，而是先去找同名的.o文件，如果没有找到或者.o文件的最后修改时间比源文件的最后修改时间早，则会去编译该源文件，生成.o文件，否则就认为原来的.o文件是可用的，不需要编译，则跳过。所以在手动停止编译的时候，正在编译的源文件的.o文件可能已经生成，但是并没有编译完成，也就是说该.o文件是不完整的；如果以后并没有修改该源文件，因为对应的.o文件已经生成且比该源文件新，就不会去重新编译，生成正确的.o文件。所以最后链接的时候就会出错了。出错的时候还很诡异，当你发现对应的链接错误，你会定位到该文件，结果你会发现这个文件中的代码并没有问题，然后你就丈二和尚摸不着头脑了。</p>
<p>2. 文件内的全局变量或函数使用static关键字，使其只在文件内其作用：因为工程中文件个数上万，而开发者也有几百，很难保证你使用的全局变量别人在其他文件不会声明使用，尤其是名字比较common的，大家都容易想到的，这样一来就会有重定义的错误。所以：要尽量缩小变量或函数的作用域，文件内的全局函数或变量使用static使其限定在文件内。</p>
<p>3. 如果在链接是发现有找不到的符号，去搜索源文件有没有对应的函数会变量，如果有，则需要去检查所在文件对应的.o文件有没有生成。因为代码中加了，不一定就是编译了的。如果.o也生成了，可以看看是不是被宏包起来了；如果.o文件没有生成，看看该源文件有没有放入正确的.min文件，并确定该min文件是不是起作用。归纳起来就是两件事：一是源文件有没有被正确编译，二是代码有没有被宏包起来导致没有编译到。</p>
<p><br />
第二步：调试开机</p>
<p>调试开机之前，你根本不会想到会有哪些问题，甚至会认为会比较顺利，一开机，就不小心进了Idle。事实往往比想象得复杂，基本上花在调试开机上的时间会占总时间的60%以上。</p>
<p>调试的工具是大家都比较熟悉的trace32，不过刚开始的时候，我只会使用trace32 download，并不会使用它来调试，连设置最简单的断点都不会。所以如果不大熟悉，需要先学会简单的使用。（哈哈，还好，platform那边的兄弟个个是高手，教我不少，感谢他们！）</p>
<p>大体上，我们是按照&ldquo;公交线路式&rdquo;的方法进行调试的。刚开机是起始点（公交始发站），进入Idle是终止点（公交终点站），在之间设置了多个中点（中间站点）。调试的过程就是让一辆公交车（程序指令）从始发站出发，经过各个中间站点，最后到达终点站的过程。因为司机是第一次在该路线上驾车，所以在中间的时候总会迷路，我们需要帮助他一个站点一个站点的往下走。</p>
<p>下面来分享一些经验技巧，不过也是比较初级的，高手们请不要见笑：</p>
<p>1. 使用trace32打断点：因为这个是使用trace32调试时最经常使用到的，所以在这里简单说一下。使用trace32打断点有很多途径，可以通过菜单项先找到函数，也可以先找到文件再找函数。不过为了节约时间，可以使用命令来快速完成：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>break.set <span style="color: #0000ff">functionName</span> /onchip</strong><br />
如果functionName指示错误，会有提示的，functionName不管是在debug版本还是非debug版本都可以使用的（只是在非debug版本里看不到原始的code而已）。onchip类型的断点只能同时enable两个，而且onchip的断点比较可靠，所以基本上我们只使用onchip类型的断点，所以同时只能使用两个断点。另外点击高级按钮，可以打开高级的断点设置，包括设置一定的条件，设置计数器等。</p>
<p>2. 在EVB Porting的时候，我们碰到了一个比较麻烦的问题，第一次开机能够显示画面，但是之后开机就只能看到白屏（屏幕发白光），尽管已经确认Form已经创建成功，并顺利push到了rootform，而且display也确实有调用update的函数。我们知道在BREW中，刷屏实际上是使用IDisplay_Update来完成的，尽管我们使用的是BUIW，其实也不例外。所以我们希望能够找到display update的函数处打个断点，确定有没有跑到--这就是我要说的在这些地方打断点，需要对Brew中接口的实现要有一定的了解，不然很可能找不到函数名而不知道在哪里打断点。类似的还有IShell_CreateInstance, IShell_StartApplet等。这些是需要我们去猜测的，尽管我们可以看到这些函数名在对象结构体中的成员名，但是并不是函数名，我们可以使用部分搜索的方法来找到。BREW提供给我们使用的&ldquo;函数&rdquo;叫接口，用I左右前缀，而在内部实现它叫类，用&ldquo;C&rdquo;做为前缀。比如IShell_StartApplet函数，真正的实现函数名为CShell_StartApplet。也有的代码并没有用&ldquo;C&rdquo;来做前缀，只是把&quot;I&quot;前缀去掉而已。回到屏幕不能显示画面的问题，最后幸亏platform的人发现LCD的电压为0（尽管开着背光灯，两者两码事）。</p>
<p>3. 在BREW3上，我们知道applet的handle event函数收到的第一个事件是EVT_APP_START，不过这次在调试时，发现在BREW4上，handle event函数收到的第一个事件是EVT_APP_START_WINDOW(后来得知这个事件是专门给运行在background的applet用的)。 <br />
&nbsp;</p>]]></description>
		</item>
		
			<item>
			<link>http://www.wscxy.com/shosh/article.asp?id=79</link>
			<title><![CDATA[3 Key Coding Tips for BREW Developers]]></title>
			<author>shosh.zhu@qisda.com(shosh)</author>
			<category><![CDATA[brew开发]]></category>
			<pubDate>Fri,26 Dec 2008 17:57:20 +0800</pubDate>
			<guid>http://www.wscxy.com/shosh/default.asp?id=79</guid>
		<description><![CDATA[<div>
<p><b>Tip #1: Code for the phone, not the emulator. </b><br />
Handsets are small form factor, constrained devices &mdash; so relative to what you're used to on the desktop, phones have limited speed, limited resources, small screens, and a limited ARM processor. You have to remember that the emulator has amazing speed (your 2GHz desktop machine at full speed, for example), emulated resources, incorrect use of screen size for many of the skins, and an x86 processor. The emulator is just that; it's not a phone.</p>
<p>Here's a closer look at each of the four main development issues when using an emulator to code for a BREW phone:</p>
<p>&nbsp;</p>
<ul>
    <li><i>Speed.</i> Phones have fairly slow processors. Don't expect to be able to do complex math calculations in real-time for a simulation.
    <p>&nbsp;</p>
    </li>
    <li><i>Limited resources.</i> Phones have a small amount of storage, and policy of specific phones (such as the Z-800) can make that even more limiting than it seems at first. Also, an application's code is loaded into RAM from storage (just like a traditional PC, but unlike many PDAs). This means even less RAM is available than you may have originally expected. A good case in point is the Kyocera 3035; it has 60 kilobytes of RAM available. If your application is 35 kilobytes, then only 25 kilobytes remain for processing.
    <p>&nbsp;&nbsp;</p>
    </li>
    <li><i>Screen size.</i> These are small screens, even by PDA standards. Design the UI the way you see them on other phones: That is &mdash; keep it simple. Don't try to do too much on one screen. Instead, break a screen up and have a menu to access the various portions of it so everything is clean and uncluttered.
    <p>&nbsp;&nbsp;</p>
    </li>
    <li><i>Don't forget that the target for the application is an ARM processor. </i>The application must compile for the ARM processor. Start with this example: make files. Although they aren't the best design, they have the settings that are required for this particular ARM processor. Don't try to change them to compile your application; that won't work. Instead, fix the code. Common mistakes include doing division, using global or static variables, and, when compiling in Visual Studio, ignoring Level 4 warnings, which often become errors using the ARM compiler.</li>
</ul>
<p>&nbsp;</p>
<p>Make sure to build often with the ARM compiler and test often on the phone. QUALCOMM has recently made this much easier by providing the BREW Logger for download. This allows you to see the DBGPRINTF messages on your PC while you're debugging on the phone. This beats grabbing debug files on the phone!</p>
<b>Tip #2: Remember that BREW is Asynchronous. </b><br />
Writing software for BREW means writing fully asynchronous, event-driven software. This is even more pronounced than early Mac OS programming or Palm OS programming. In those systems, there was usually a way for the application to create its own event loop wherever it wanted by grabbing the next event off the system queue and seeing if that event was for it or not. If it was, it could handle it and go on; otherwise, it would dispatch it back to the system. This is not possible in BREW.
<p>Most IO calls in BREW are non-blocking. What this means is that the action doesn't actually take place right when the call is made. That would have made it synchronous. For instance, if you make a call to ISOCKET_Connect(), you have to provide a callback routine. What happens here, at least as far as we are concerned, is the action to do the ISOCKET_Connect() is placed on a system stack, and the call returns immediately, returning control to the application. If we want the action to actually occur, we must return to the system before it can happen.</p>
<p>All of this means that the best BREW applications will need to be designed from the ground up to work well within an asynchronous system. Sure, there are ways of somewhat mechanically converting a synchronous application to work in an asynchronous system, but for anything but the simplest of applications, this can get very complex very quickly.</p>
<p>Another effect of this is that when an application is busy, nothing else is occurring on the phone. Since this is a phone, that's a bad thing. A phone is still primarily for voice calls. If your application is busy doing something, a voice call can't occur (at least the part of notifying the user that a voice call is incoming) until your application returns to the system. Because of this, there is a watchdog timer. If an application spends too much time without returning to the system, the phone will reset. This means that if an application is going to do some processing, some of the flow of control should be passed via sending events to itself. This is easily accomplished by using EVT_USER events with ISHELL_PostEvent(). (I don't recommend ISHELL_SendEvent() as that causes the event to happen synchronously, which is not what we want.)</p>
<p>There are a number of BREW system calls that require the application to be waiting for a callback before flow will continue. What if this never occurs? Well, the obvious effect is that control will never return to your application, and the user will think it has hung. This is actually quite a common occurrence (for example, a phone indoors may not have very good network coverage). This is easily solved by using ISHELL_SetTimer() with your own callback. Don't worry: If the event occurs before the timer, you can easily cancel the timer by using ISHELL_CancelTimer().</p>
<p><b>Tip #3: Know How to Handle Your Events. </b><br />
As mentioned in the previous tip, BREW is very event-driven. As such, an application will get many events that it may not be expecting. Controls talk to themselves using events. The system sends events to the application to tell it a variety of things about the state of the phone. All of these need some action taken by the application. Because of this, a well-designed event handler is required for a stable application.</p>
<p>It is the application's responsibility to make sure all controls being used get the messages they require to function properly. It is not defined what all of the events are, so the best way to handle this is to take special action on those events you know about and may want to intercept occasionally (such as the arrow keys or CLR key) and have a default handler that passes everything else to any active controls to see if they can handle the event.</p>
<p>Handling the CLR key (event code of EVT_KEY with a wParam of AVK_CLR) is a special case in BREW. A well-designed application will have the CLR key behaving as a backspace when in text entry controls, as a back key to go back a screen, and exiting the application when on the main screen. This means an application needs to watch for it and perhaps do something special. If FALSE is ever returned from handling the CLR key, the application will exit. Except at the main screen, this is likely not the action you want the application to take.</p>
<p>One of the most important events to handle properly in any application is the suspend event (EVT_APP_SUSPEND). If an application receives this, it means that the phone wants to do something, such as notifying the user of a voice call or maybe an SMS message. QUALCOMM defines a bunch of things that an application must do before returning from a suspend event. These things including closing down all used sockets, stopping all timers, and deactivating all controls, among many other things. An application will not pass testing if these aren't done.</p>
<p><i>Originally published in the BREW Wireless Resource Center</i></p>
</div>
<p>&nbsp;</p>]]></description>
		</item>
		
</channel>
</rss>
