<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="wordpress/2.1.3" -->
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	>

<channel>
	<title>Hu's Blog</title>
	<link>http://www.zhanghu.org</link>
	<description>Just a blog</description>
	<pubDate>Wed, 23 Apr 2008 03:59:09 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.1.3</generator>
	<language>en</language>
			<item>
		<title>第03章 输入：键盘、鼠标和触摸屏 3.2 鼠标和触摸屏</title>
		<link>http://www.zhanghu.org/2008/04/23/programming-win-ce-32/</link>
		<comments>http://www.zhanghu.org/2008/04/23/programming-win-ce-32/#comments</comments>
		<pubDate>Wed, 23 Apr 2008 03:59:09 +0000</pubDate>
		<dc:creator>Hu</dc:creator>
		
		<category><![CDATA[《Windows CE 程序设计》]]></category>
<category>WinCE</category>
		<guid isPermaLink="false">http://www.zhanghu.org/2008/04/23/programming-win-ce-32/</guid>
		<description><![CDATA[//————————————————————————-
// 标题：Windows CE 程序设计(3rd)-第03章 输入：键盘、鼠标和触摸屏 3.2 鼠标和触摸屏
// 作者：Douglas Boling
// 译者：Zhanghu.org
// 更新时间：2008/04/23
//————————————————————————-
鼠标和触摸屏
和桌面PC不同，Windows CE设备并不总是有鼠标的。作为替代，许多Windows CE设备都有触摸屏和手写笔。但对有鼠标的Windows CE系统来说，编程接口和桌面系统是一样的。
鼠标消息


每当鼠标光标在显示区域移动，光标下的最顶层窗口都会收到一个WM_MOUSEMOVE消息。如果用户点击鼠标左键或者右键，窗口会收到 WM_LBUTTONDOWN或WM_RBUTTONDOWN消息；而当用户释放按键时，窗口则会收到WM_LBUTTONUP或 WM_RBUTTONUP消息。如果用户按下并释放鼠标滚轮，窗口会收到WM_MBUTTONDOWN及WM_MBUTTONUP消息。
对所有这些消息，wParam和lParam参数加载的将是同一样的值。wParam参数包含一个位标志的集合，用来指出当前键盘上Ctrl或Shift键是否被按下。同 Windows 的其它版本一样，在这些消息里没有提供Alt键的状态。要想在消息发送时获得Alt键的状态，可以使用GetKeyState函数。
lParam参数包含两个16位的值，用来指出点击点在屏幕上的位置。低16位是相对窗口客户区左上角的x（水平）坐标位置，高16位是y（垂直）坐标位置。
如果用户双击，也就是在预定义的时间内在屏幕同一位置点两次，Windows会向被双击的窗口发送WM_LBUTTONDBLCLK消息，不过只有当窗口类注册了CS_DBLCLKS风格时才会这么做。可以在用RegisterClass注册窗口类时设置类风格。
您可以通过对比发送给窗口的消息来区分单击和双击。当双击发生时，窗口首先收到来自最初单击的WM_LBUTTONDOWN和WM_LBUTTONUP消息。接下来一个WM_LBUTTONDBLCLK消息会在WM_LBUTTONUP后发出。The trick is to refrain from acting on a WM_LBUTTONDOWN message in any way that precludes action on a subsequent WM_LBUTTONDBLCLK. 有一个窍门是采用任何方法来限制WM_LBUTTONDOWN消息起作用， 这将阻止后续的WM_LBUTTONDBLCLK消息起作用。通常来说这没什么问题，因为单击通常是选择一个对象，而双击则只是启动用于该对象的默认操作。
如果用户滚动鼠标轮，窗口会收到WM_MOUSEWHEEL消息。对于该消息，lParam的内容和其它鼠标消息的内容一样，都是鼠标光标的水平和垂直位置。wParam的低字位也是同样的位标志，指出当前被按下的键。但wParam的高字位则包含的是滚轮的距离，用常量WHEEL_DELTA的倍数来表示滚动的距离。如果该值为正，表示滚轮是朝远离用户方向滚动；如果该值为负，表示滚轮是朝用户方向滚动。
使用触摸屏
触摸屏和手写笔这一组合对Windows平台来说相对是比较新的，但幸运的是，要把它们集成到Windows CE应用程序里相对还是比较容易的。处理手写笔的最好方法就是把它看成是一个单键鼠标。手写笔产生的鼠标消息，同其它版本的Windows以及有鼠标的 Windows CE里鼠标提供的消息相同。鼠标和手写笔的不同在于这两种输入设备的物理实体的不同。
和鼠标不同，手写笔没有光标来指示其当前位置。因此，手写笔不能像鼠标光标那样在屏幕的一个点上盘旋。当用户将光标移过一个窗口而不按鼠标键的话，光标就会盘旋。这个概念不适用于手写笔编程，因为当手写笔不和屏幕接触的时候，触摸屏是检测不到手写笔的位置的。
手写笔和鼠标之间的差异带来的另一个后果是：没有鼠标光标，应用程序不能通过改变盘旋光标的外貌来给用户提供反馈。基于触摸屏的Windows CE系统为这种典型的Windows反馈方式提供了光标设置功能。提示用户必须等待系统完成处理的沙漏光标，在Windows CE下得到支持，应用程序可以通过SetCursor函数来显示繁忙的沙漏，这和其它版本的Windows里的应用程序使用的方式一样。
&#160;
手写笔消息
当用户用手写笔在屏幕上压触时，压触点下的顶层窗口如果此前没有输入焦点的话就会收到焦点，随后收到WM_LBUTTONDOWN消息。当用户抬起手写笔时，窗口会收到WM_LBUTTONUP消息。在手写笔按下的同时在同一个窗口内移动它，窗口就会收到WM_MOUSEMOVE消息。
电子墨水
对手持设备来说最典型的应用是捕捉屏幕上用户在的笔迹并存储下来。这个过程不是手写识别，只是简单的墨迹存储。在开始阶段，完成这个功能的最好方法应该是存储由WM_MOUSEMOVE消息传入的手写笔的各个点。但有个问题，就是有时候这些小型CE设备不能快速的发送消息，导致不能获得满意的分辨率。因此在 Windows CE下，增加了一个函数来帮助程序员追踪手写笔。
 

1
BOOL GetMouseMovePoints &#40;PPOINT pptBuf, UINT nBufPoints,UINT *pnPointsRetrieved&#41;;

 
GetMouseMovePoints [...]]]></description>
			<content:encoded><![CDATA[<p>//————————————————————————-<br />
// 标题：Windows CE 程序设计(3rd)-第03章 输入：键盘、鼠标和触摸屏 3.2 鼠标和触摸屏<br />
// 作者：Douglas Boling<br />
// 译者：Zhanghu.org<br />
// 更新时间：2008/04/23<br />
//————————————————————————-</p>
<h1><span style="font-size: 18pt; line-height: 240%; font-family: 宋体">鼠标和触摸屏</span><span style="font-size: 18pt; line-height: 240%" lang="EN-US"><o:p></o:p></span></h1>
<p class="MsoNormal" style="text-indent: 24pt; line-height: 150%"><span style="font-size: 12pt; line-height: 150%; font-family: 宋体">和桌面<span lang="EN-US">PC</span>不同</span><span style="font-family: 宋体">，</span><span style="font-size: 12pt; line-height: 150%; font-family: 宋体" lang="EN-US">Windows CE</span><span style="font-size: 12pt; line-height: 150%; font-family: 宋体">设备并不总是有鼠标的。作为替代，许多<span lang="EN-US">Windows CE</span>设备都有触摸屏和手写笔。但对有鼠标的<span lang="EN-US">Windows CE</span>系统来说，编程接口和桌面系统是一样的。</span></p>
<p><a title="_Toc157323252" name="_Toc157323252"></a><a title="_Toc156659417" name="_Toc156659417"></a><span><span class="3Char"><span style="font-size: 16pt">鼠标消息</span></span></span><span class="3Char"><span style="font-size: 16pt" lang="EN-US"><o:p></o:p></span></span></p>
<p><span class="3Char"><span style="font-size: 16pt" lang="EN-US"><o:p></o:p></span></span></p>
<p><strong><span><span class="3Char"><span style="font-size: 16pt"></span></span></span></strong><a title="_Toc156659417" name="_Toc156659417"></a><span><span class="3Char"><span style="font-size: 16pt"></span></span></span><span class="3Char"><span style="font-size: 16pt" lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal" style="text-indent: 24pt; line-height: 150%"><span style="font-size: 12pt; line-height: 150%; font-family: 宋体">每当鼠标光标在显示区域移动，光标下的最顶层窗口都会收到一个<span lang="EN-US">WM_MOUSEMOVE</span>消息。如果用户点击鼠标左键或者右键，窗口会收到<span lang="EN-US"> WM_LBUTTONDOWN</span>或<span lang="EN-US">WM_RBUTTONDOWN</span>消息；而当用户释放按键时，窗口则会收到<span lang="EN-US">WM_LBUTTONUP</span>或<span lang="EN-US"> WM_RBUTTONUP</span>消息。如果用户按下并释放鼠标滚轮，窗口会收到<span lang="EN-US">WM_MBUTTONDOWN</span>及<span lang="EN-US">WM_MBUTTONUP</span>消息。<span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal" style="text-indent: 24pt; line-height: 150%"><span style="font-size: 12pt; line-height: 150%; font-family: 宋体">对所有这些消息，<span lang="EN-US">wParam</span>和<span lang="EN-US">lParam</span>参数加载的将是同一样的值。<span lang="EN-US">wParam</span>参数包含一个位标志的集合，用来指出当前键盘上<span lang="EN-US">Ctrl</span>或<span lang="EN-US">Shift</span>键是否被按下。同<span lang="EN-US"> Windows </span>的其它版本一样，在这些消息里没有提供<span lang="EN-US">Alt</span>键的状态。要想在消息发送时获得<span lang="EN-US">Alt</span>键的状态，可以使用<span lang="EN-US">GetKeyState</span>函数。<span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal" style="text-indent: 24pt; line-height: 150%"><span style="font-size: 12pt; line-height: 150%; font-family: 宋体" lang="EN-US">lParam</span><span style="font-size: 12pt; line-height: 150%; font-family: 宋体">参数包含两个<span lang="EN-US">16</span>位的值，用来指出点击点在屏幕上的位置。低<span lang="EN-US">16</span>位是相对窗口客户区左上角的<span lang="EN-US">x</span>（水平）坐标位置，高<span lang="EN-US">16</span>位是<span lang="EN-US">y</span>（垂直）坐标位置。<span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal" style="text-indent: 24pt; line-height: 150%"><span style="font-size: 12pt; line-height: 150%; font-family: 宋体">如果用户双击，也就是在预定义的时间内在屏幕同一位置点两次，<span lang="EN-US">Windows</span>会向被双击的窗口发送<span lang="EN-US">WM_LBUTTONDBLCLK</span>消息，不过只有当窗口类注册了<span lang="EN-US">CS_DBLCLKS</span>风格时才会这么做。可以在用<span lang="EN-US">RegisterClass</span>注册窗口类时设置类风格。<span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal" style="text-indent: 24pt; line-height: 150%"><span style="font-size: 12pt; line-height: 150%; font-family: 宋体">您可以通过对比发送给窗口的消息来区分单击和双击。当双击发生时，窗口首先收到来自最初单击的<span lang="EN-US">WM_LBUTTONDOWN</span>和<span lang="EN-US">WM_LBUTTONUP</span>消息。接下来一个<span lang="EN-US">WM_LBUTTONDBLCLK</span>消息会在<span lang="EN-US">WM_LBUTTONUP</span>后发出。</span><span lang="EN-US">The trick is to refrain from acting on a <em>WM_LBUTTONDOWN</em> message in any way that precludes action on a subsequent <em>WM_LBUTTONDBLCLK</em>. </span><span style="font-size: 12pt; line-height: 150%; font-family: 宋体">有一个窍门是采用任何方法来限制<span lang="EN-US">WM_LBUTTONDOWN</span>消息起作用， 这将阻止后续的<span lang="EN-US">WM_LBUTTONDBLCLK</span>消息起作用。通常来说这没什么问题，因为单击通常是选择一个对象，而双击则只是启动用于该对象的默认操作。<span lang="EN-US"><o:p></o:p></span></span></p>
<p><span style="font-size: 12pt; line-height: 150%; font-family: 宋体">如果用户滚动鼠标轮，窗口会收到<span lang="EN-US">WM_MOUSEWHEEL</span>消息。对于该消息，<span lang="EN-US">lParam</span>的内容和其它鼠标消息的内容一样，都是鼠标光标的水平和垂直位置。<span lang="EN-US">wParam</span>的低字位也是同样的位标志，指出当前被按下的键。但<span lang="EN-US">wParam</span>的高字位则包含的是滚轮的距离，用常量<span lang="EN-US">WHEEL_DELTA</span>的倍数来表示滚动的距离。如果该值为正，表示滚轮是朝远离用户方向滚动；如果该值为负，表示滚轮是朝用户方向滚动。</span><br />
<a title="_Toc157323252" name="_Toc157323252"></a><a title="_Toc156659417" name="_Toc156659417"></a><span><span class="3Char"><span style="font-size: 16pt"></span></span></span><a title="_Toc156659418" name="_Toc156659418"></a><span><span class="3Char"><span style="font-size: 16pt">使用触摸屏</span></span></span><span class="3Char"><span style="font-size: 16pt" lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal" style="text-indent: 24pt; line-height: 150%"><span style="font-size: 12pt; line-height: 150%; font-family: 宋体">触摸屏和手写笔这一组合对<span lang="EN-US">Windows</span>平台来说相对是比较新的，但幸运的是，要把它们集成到<span lang="EN-US">Windows CE</span>应用程序里相对还是比较容易的。处理手写笔的最好方法就是把它看成是一个单键鼠标。手写笔产生的鼠标消息，同其它版本的<span lang="EN-US">Windows</span>以及有鼠标的<span lang="EN-US"> Windows CE</span>里鼠标提供的消息相同。鼠标和手写笔的不同在于这两种输入设备的物理实体的不同。<span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal" style="text-indent: 24pt; line-height: 150%"><span style="font-size: 12pt; line-height: 150%; font-family: 宋体">和鼠标不同，手写笔没有光标来指示其当前位置。因此，手写笔不能像鼠标光标那样在屏幕的一个点上盘旋。当用户将光标移过一个窗口而不按鼠标键的话，光标就会盘旋。这个概念不适用于手写笔编程，因为当手写笔不和屏幕接触的时候，触摸屏是检测不到手写笔的位置的。<span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal" style="text-indent: 24pt; line-height: 150%"><span style="font-size: 12pt; line-height: 150%; font-family: 宋体">手写笔和鼠标之间的差异带来的另一个后果是：没有鼠标光标，应用程序不能通过改变盘旋光标的外貌来给用户提供反馈。基于触摸屏的<span lang="EN-US">Windows CE</span>系统为这种典型的<span lang="EN-US">Windows</span>反馈方式提供了光标设置功能。提示用户必须等待系统完成处理的沙漏光标，在<span lang="EN-US">Windows CE</span>下得到支持，应用程序可以通过<span lang="EN-US">SetCursor</span>函数来显示繁忙的沙漏，这和其它版本的<span lang="EN-US">Windows</span>里的应用程序使用的方式一样。</span></p>
<p class="MsoNormal" style="text-indent: 24pt; line-height: 150%">&nbsp;</p>
<p><a title="_Toc157323254" name="_Toc157323254"></a><a title="_Toc156659419" name="_Toc156659419"></a><span><strong><span style="font-family: 宋体">手写笔消息</span></strong></span><strong><span style="font-family: 宋体" lang="EN-US"><o:p></o:p></span></strong></p>
<p class="MsoNormal" style="text-indent: 24pt; line-height: 150%"><span style="font-size: 12pt; line-height: 150%; font-family: 宋体">当用户用手写笔在屏幕上压触时，压触点下的顶层窗口如果此前没有输入焦点的话就会收到焦点，随后收到<span lang="EN-US">WM_LBUTTONDOWN</span>消息。当用户抬起手写笔时，窗口会收到<span lang="EN-US">WM_LBUTTONUP</span>消息。在手写笔按下的同时在同一个窗口内移动它，窗口就会收到<span lang="EN-US">WM_MOUSEMOVE</span>消息。<span lang="EN-US"><o:p></o:p></span></span></p>
<p><a title="_Toc157323255" name="_Toc157323255"></a><a title="_Toc156659420" name="_Toc156659420"></a><span><strong><span style="font-family: 宋体">电子墨水</span></strong></span><strong><span style="font-family: 宋体" lang="EN-US"><o:p></o:p></span></strong></p>
<p class="MsoNormal" style="text-indent: 24pt; line-height: 150%"><span style="font-size: 12pt; line-height: 150%; font-family: 宋体">对手持设备来说最典型的应用是捕捉屏幕上用户在的笔迹并存储下来。这个过程不是手写识别，只是简单的墨迹存储。在开始阶段，完成这个功能的最好方法应该是存储由<span lang="EN-US">WM_MOUSEMOVE</span>消息传入的手写笔的各个点。但有个问题，就是有时候这些小型<span lang="EN-US">CE</span>设备不能快速的发送消息，导致不能获得满意的分辨率。因此在<span lang="EN-US"> Windows CE</span>下，增加了一个函数来帮助程序员追踪手写笔。<span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal" style="text-align: left" align="left"><span style="font-size: 9pt; font-family: 宋体" lang="EN-US"><o:p> </o:p></span></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="cpp"><span style="color: #0000ff;">BOOL</span> GetMouseMovePoints <span style="color: #000000;">&#40;</span>PPOINT pptBuf, UINT nBufPoints,UINT *pnPointsRetrieved<span style="color: #000000;">&#41;</span>;</pre></td></tr></table></div>

<p class="MsoNormal" style="text-indent: 18pt; line-height: 150%"><span style="font-size: 9pt; line-height: 150%; font-family: 宋体" lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal" style="text-indent: 24pt; line-height: 150%"><span style="font-size: 12pt; line-height: 150%; font-family: 宋体" lang="EN-US">GetMouseMovePoints </span><span style="font-size: 12pt; line-height: 150%; font-family: 宋体">返回一批手写笔点，而没有产生<span lang="EN-US">WM_MOUSEMOVE</span>消息。函数参数包括点数组、数组大小和一个指向整数的指针，用来接收返回给应用程序的点数。一旦接收完，这些附加的点可以用来填充上一个<span lang="EN-US">WM_MOUSEMOVE</span>消息和当前<span lang="EN-US">WM_MOUSEMOVE</span>消息之间的空白。<span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal" style="text-indent: 24pt; line-height: 150%"><span style="font-size: 12pt; line-height: 150%; font-family: 宋体" lang="EN-US">GetMouseMovePoints </span><span style="font-size: 12pt; line-height: 150%; font-family: 宋体">产生一条曲线。它是按触摸板的分辨率返回点的，而不是按屏幕的。触摸板的分辨率通常设置为屏幕分辨率的<span lang="EN-US">4</span>倍，所以您需要把<span lang="EN-US"> GetMouseMovePoints</span>返回的坐标除以<span lang="EN-US">4</span>来转换成屏幕坐标。额外的分辨率是用在手写识别之类的程序中的。<span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal" style="text-indent: 24pt; line-height: 150%"><span style="font-size: 12pt; line-height: 150%; font-family: 宋体">在简短的示例程序<span lang="EN-US">PenTrac</span>中，演示了<span lang="EN-US">GetMouseMovePoints</span>带来的不同之处。图<span lang="EN-US">3-4</span>显示了<span lang="EN-US">PenTrac</span>窗口。注意观察窗口上的两条点线。上面的线是仅仅使用来自<span lang="EN-US">WM_MOUSEMOVE</span>的点绘制的。底下的线则是包括了用<span lang="EN-US">GetMouseMovePoints</span>查询到的点，其中黑色点是来自<span lang="EN-US"> WM_MOUSEMOVE</span>，而红色（浅色）点是来自<span lang="EN-US">GetMouseMovePoints</span>。<span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal" style="text-indent: 24pt; line-height: 150%">&nbsp;</p>
<p class="MsoNormal" style="text-indent: 24pt; line-height: 150%">&nbsp;</p>
<p class="MsoNormal" style="text-indent: 21pt; line-height: 150%"><span style="font-family: 宋体">图</span><span lang="EN-US">3-4</span><span style="font-family: 宋体">：显示了两条线的</span><span lang="EN-US">PenTrac</span><span style="font-family: 宋体">窗口 (暂略)<br />
</span></p>
<p class="MsoNormal" style="text-indent: 24pt; line-height: 150%">&nbsp;</p>
<p class="MsoNormal" style="text-indent: 24pt; line-height: 150%">&nbsp;</p>
<p class="MsoNormal" style="text-indent: 24pt; line-height: 150%"><span style="font-size: 12pt; line-height: 150%; font-family: 宋体">清单<span lang="EN-US">3-2</span>给出了<span lang="EN-US">PenTrac</span>的源代码。该程序为每个接收到的<span lang="EN-US">WM_MOUSEMOVE</span>或<span lang="EN-US">WM_LBUTTONDOWN</span>消息在屏幕上绘制一个点。如果在鼠标移动期间<span lang="EN-US">Shift</span>键被按下，<span lang="EN-US">PenTrac</span>会调用<span lang="EN-US">GetMouseMovePoints</span>并把获得的这些点显示成红色，用于和来自鼠标消息的点进行区分。<span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal" style="text-indent: 24pt; line-height: 150%"><span style="font-size: 12pt; line-height: 150%; font-family: 宋体">为了加强<span lang="EN-US">GetMouseMovePoints</span>的效果，<span lang="EN-US">PenTrac</span>做了一些手脚。在处理<span lang="EN-US">WM_MOUSEMOVE</span>和<span lang="EN-US"> WM_LBUTTONDOWN</span>消息的<span lang="EN-US">DoMouseMain</span>例程里，调用了<span lang="EN-US">sleep</span>函数来消耗掉一些毫秒时间。这个延迟模拟了那些没有时间及时处理每个鼠标移动消息的响应缓慢的应用程序。<span lang="EN-US"><o:p></o:p></span></span></p>
<p><a title="_Toc157323256" name="_Toc157323256"></a><a title="_Toc156659421" name="_Toc156659421"></a><span><span class="3Char"><span style="font-size: 16pt">清单<span lang="EN-US">3-2</span>：<span lang="EN-US">PenTrac</span>程序</span></span></span><span class="3Char"><span style="font-size: 16pt" lang="EN-US"><o:p></o:p></span></span></p>
<p>[程序暂略]</p>
<p class="MsoNormal"><strong><span style="font-family: 宋体">输入焦点和鼠标消息</span><span lang="EN-US"><o:p></o:p></span></strong></p>
<p class="MsoNormal"><strong><span lang="EN-US"><o:p> </o:p></span></strong></p>
<p class="MsoNormal" style="text-indent: 24pt; line-height: 150%"><span style="font-size: 12pt; line-height: 150%; font-family: 宋体">对于如何以及何时把手写笔产生的鼠标消息发送到不同的窗口，这个过程中涉及的相关规则是需要关注一下的。正如我前面提到的，当手写笔压触到一个窗口上时，系统的输入焦点将发生变化。但是，把手写笔从一个窗口拖动到另一个窗口并不会使新窗口获得输入焦点。因为是下压时才设置焦点，而拖动手写笔滑过窗口是不会设置的。当手写笔拖动出窗口时，该窗口就停止接收<span lang="EN-US">WM_MOUSEMOVE</span>消息了，但会继续保持输入焦点。因为手写笔的笔尖依然下压，所以没有其它窗口会接收<span lang="EN-US">WM_MOUSEMOVE</span>消息了。这一点与保持鼠标按键按下并拖动出一个窗口很类似。<span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal" style="text-indent: 24pt; line-height: 150%"><span style="font-size: 12pt; line-height: 150%; font-family: 宋体">要想在手写笔即使被移动到窗口外时继续接收手写笔消息，应用程序只要用接收鼠标消息的窗口句柄做参数，调用<span lang="EN-US"><o:p></o:p></span></span></p>

<div class="wp_syntax"><div class="code"><pre class="cpp">  HWND SetCapture <span style="color: #000000;">&#40;</span>HWND hWnd<span style="color: #000000;">&#41;</span></pre></div></div>

<p class="MsoNormal" style="line-height: 150%"><span style="font-size: 12pt; line-height: 150%; font-family: 宋体">函数就可以了。该函数返回前一个捕捉鼠标消息的窗口的句</span><span style="font-size: 12pt; line-height: 150%; font-family: 宋体">柄</span><span style="font-size: 12pt; line-height: 150%; font-family: 宋体">，如果之前没有捕捉过则返回</span><span style="font-size: 12pt; line-height: 150%" lang="EN-US">NULL</span><span style="font-size: 12pt; line-height: 150%; font-family: 宋体">。要停止接收手写笔输入产生的鼠标消息，窗口可以调用</span><span style="font-size: 12pt; line-height: 150%" lang="EN-US"><o:p></o:p></span></p>

<div class="wp_syntax"><div class="code"><pre class="cpp"> <span style="color: #0000ff;">BOOL</span> ReleaseCapture <span style="color: #000000;">&#40;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&#41;</span>;</pre></div></div>

<p class="MsoNormal" style="line-height: 150%"><span style="font-size: 12pt; line-height: 150%; font-family: 宋体">函数。任何时候都只有一个窗口可以捕捉手写笔的输入。要判断手写笔是否被捕捉了，可以调用</span><span style="font-size: 12pt; line-height: 150%" lang="EN-US"><o:p></o:p></span></p>

<div class="wp_syntax"><div class="code"><pre class="cpp"> HWND GetCapture <span style="color: #000000;">&#40;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&#41;</span>;</pre></div></div>

<p class="MsoNormal" style="line-height: 150%"><span style="font-size: 12pt; line-height: 150%; font-family: 宋体">函数，它返回捕捉手写笔的窗口的句柄，如果没有窗口捕捉手写笔的输入，则返回</span><span style="font-size: 12pt; line-height: 150%" lang="EN-US">0</span><span style="font-size: 12pt; line-height: 150%; font-family: 宋体">（不过要注意一个警告：返回</span><span style="font-size: 12pt; line-height: 150%" lang="EN-US">0</span><span style="font-size: 12pt; line-height: 150%; font-family: 宋体">只是表示该线程没有捕捉鼠标，并不表示其它线程或进程没有捕捉鼠标）。捕捉手写笔的窗口必须和调用该函数的的窗口在同样的线程环境里。这个限制意味着，如果手写笔被另一个应用里的窗口捕捉了，</span><span style="font-size: 12pt; line-height: 150%" lang="EN-US">GetCapture</span><span style="font-size: 12pt; line-height: 150%; font-family: 宋体">依然返回</span><span style="font-size: 12pt; line-height: 150%" lang="EN-US">0</span><span style="font-size: 12pt; line-height: 150%; font-family: 宋体">。</span><span style="font-size: 12pt; line-height: 150%" lang="EN-US"><o:p></o:p></span></p>
<p class="MsoNormal" style="text-indent: 24pt; line-height: 150%"><span style="font-size: 12pt; line-height: 150%; font-family: 宋体">如果一个窗口捕捉了手写笔而另一个窗口调用了<span lang="EN-US">GetCapture</span>，那么最初捕捉手写笔的窗口会收到一个<span lang="EN-US">WM_CAPTURECHANGED</span>消息。消息的<span lang="EN-US">lParam</span>参数中包含了获得手写笔捕捉的窗口的句柄。您不应该试图调用<span lang="EN-US"> GetCapture</span>来取回捕捉。通常，因为手写笔是共享资源，应用程序应该小心谨慎的捕捉手写笔一段时间，并且应该能够优雅地处理捕捉丢失的情况。<span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal" style="text-indent: 24pt; line-height: 150%"><span style="font-size: 12pt; line-height: 150%; font-family: 宋体">另外一个有趣的事情是：正因为窗口捕捉了鼠标，所以它不能阻止在另一个窗口上点击来获得输入焦点。您可以使用其它方法来防止输入焦点的更换，但几乎在所有情况下，最好是让用户而不是程序来决定哪个顶层窗口应该拥有输入焦点。<span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal"><a title="_Toc157323258" name="_Toc157323258"></a><a title="_Toc156659423" name="_Toc156659423"></a><span><strong><span style="font-family: 宋体">点击右键</span></strong></span><strong><span lang="EN-US"><o:p></o:p></span></strong></p>
<p class="MsoNormal"><strong><span lang="EN-US"><o:p> </o:p></span></strong></p>
<p class="MsoNormal" style="text-indent: 24pt; line-height: 150%"><span style="font-size: 12pt; line-height: 150%; font-family: 宋体">在<span lang="EN-US">Windows </span>系统里，当您在一个对象上单击鼠标右键，通常地会调出上下文相关的、独立的菜单，显示针对该具体对象能做什么的功能项集合。在有鼠标的系统中，<span lang="EN-US"> Windows</span>发送<span lang="EN-US">WM_RBUTTONDOWN</span>和<span lang="EN-US">WM_RBUTTONUP</span>消息，指出右键点击了。但是当使用手写笔的时候，不会有右键。不过<span lang="EN-US"> Windows CE</span>指导方针中允许您使用手写笔模拟右键点击。指导方针规定，如果用户按下<span lang="EN-US">Alt</span>键的同时用手写笔点击屏幕，程序会当成是右键鼠标被点击，并显示相关的上下文菜单。在<span lang="EN-US">WM_LBUTTONDOWN</span>的<span lang="EN-US">wParam</span>中没有<span lang="EN-US">MK_ALT</span>标志，所以判断<span lang="EN-US">Alt</span>键是否被按的最好方法是用<span lang="EN-US">VK_MENU</span>做参数调用<span lang="EN-US"> GetKeyState</span>，并测试返回值的相关位是否被设置了。在这种情况下，<span lang="EN-US">GetKeyState</span>是最合适的，因为返回的是鼠标消息从消息队列里取出时的键的状态。<span lang="EN-US"><o:p></o:p></span></span></p>
<p>在没有键盘的系统上，采取压下并保持这一姿势来模拟鼠标右键点击。<span lang="EN-US">SHRecognizeGesture</span>函数可以用在<span lang="EN-US">Pocket PC</span>和具有适当<span lang="EN-US">Shell</span>组件的嵌入式<span lang="EN-US">Windows CE</span>系统中，用来检查压下并保持这一姿势。函数原型如下：</p>

<div class="wp_syntax"><div class="code"><pre class="cpp">WINSHELLAPI DWORD SHRecognizeGesture<span style="color: #000000;">&#40;</span>SHRGINFO *shrg<span style="color: #000000;">&#41;</span>;</pre></div></div>

<p>唯一的参数是一<span lang="EN-US">SHRGINFO</span>结构的地址，该结构定义如下：</p>

<div class="wp_syntax"><div class="code"><pre class="cpp"><span style="color: #0000ff;">typedef</span> <span style="color: #0000ff;">struct</span> tagSHRGI<span style="color: #000000;">&#123;</span>
DWORD cbSize;
HWND hwndClient;
POINT ptDown;
DWORD dwFlags;
<span style="color: #000000;">&#125;</span>SHRGINFO,*PSHRGINFO;</pre></div></div>

<p class="MsoNormal" style="text-indent: 24pt; line-height: 150%"><span style="font-size: 12pt; line-height: 150%; font-family: 宋体" lang="EN-US">cbSize </span><span style="font-size: 12pt; line-height: 150%; font-family: 宋体">需要用结构体的大小来填充。<span lang="EN-US">hwndClient</span>则需要设置为调用该函数的窗口的句柄。<span lang="EN-US">ptDown</span>项需要用识别出姿势时的点结构体来填充。<span lang="EN-US">dwFlags</span>则包 含许多标志。<span lang="EN-US">SHRG_RETURNCMD</span>标志表示如果用户做出正确的下压保持姿势，则让函数返回<span lang="EN-US">GN_CONTEXTMENU</span>；否则就返回<span lang="EN-US">0</span>。<span lang="EN-US"> SHRG_NOTIFYPARENT</span>标志表示如果识别出正确姿势的话，就给父窗口发送一个<span lang="EN-US">WM_NOTIFY</span>消息。<span lang="EN-US">SHRG_LONDELAY</span>消息要求在识别出姿势之前，用户需要保持点压一段时间。<span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal"><a title="_Toc157323259" name="_Toc157323259"></a><a title="_Toc156659424" name="_Toc156659424"></a><span><strong><span lang="EN-US">TicTac1</span></strong></span><span><span><strong><span style="font-family: 宋体">示例程序</span></strong></span></span><strong><span lang="EN-US"><o:p></o:p></span></strong></p>
<p class="MsoNormal" style="text-indent: 21pt; line-height: 150%"><span style="font-family: 宋体">为了演示手写笔编程，我写了一个</span><span lang="EN-US">tic-tac-toe</span><span style="font-family: 宋体">小游戏。图</span><span lang="EN-US">3-5</span><span style="font-family: 宋体">显示了</span><span lang="EN-US">TicTac1</span><span style="font-family: 宋体">窗口。清单</span><span lang="EN-US">3-3</span><span style="font-family: 宋体">显示了程序的源代码。这个程序并不提供人机游戏，也不判断游戏结束，只是简单绘制边界并记录</span><span lang="EN-US">X</span><span style="font-family: 宋体">和</span><span lang="EN-US">O</span><span style="font-family: 宋体">的位置。尽管如此，该程序已经演示了手写笔的基本交互功能。</span></p>
<p><span style="font-size: 10.5pt; font-family: 宋体">图</span><span style="font-size: 10.5pt" lang="EN-US">3-5</span><span style="font-size: 10.5pt; font-family: 宋体">：</span><span style="font-size: 10.5pt" lang="EN-US">TicTac1</span><span style="font-size: 10.5pt; font-family: 宋体">窗口[略]</span><span style="font-size: 10.5pt" lang="EN-US"><br />
</span><span class="3Char"><span style="font-size: 16pt">清单</span></span><span class="3Char"><span style="font-size: 16pt" lang="EN-US">3-3</span></span><span class="3Char"><span style="font-size: 16pt">：</span></span><span class="3Char"><span style="font-size: 16pt" lang="EN-US">TicTac1</span></span><span class="3Char"><span style="font-size: 16pt">程序[略]</span></span><span class="3Char"><span style="font-size: 16pt" lang="EN-US"><br />
<!--[if !supportLineBreakNewLine]--><br />
<!--[endif]--></span></span></p>
<p class="MsoNormal" style="text-indent: 24pt; line-height: 150%">&nbsp;</p>
<p class="MsoNormal" style="text-indent: 24pt; line-height: 150%">&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zhanghu.org/2008/04/23/programming-win-ce-32/feed/</wfw:commentRss>
		</item>
		<item>
		<title>第03章 输入：键盘、鼠标和触摸屏 3.0 概述</title>
		<link>http://www.zhanghu.org/2008/04/23/programming-win-ce-30/</link>
		<comments>http://www.zhanghu.org/2008/04/23/programming-win-ce-30/#comments</comments>
		<pubDate>Wed, 23 Apr 2008 02:22:13 +0000</pubDate>
		<dc:creator>Hu</dc:creator>
		
		<category><![CDATA[《Windows CE 程序设计》]]></category>
<category>WinCE</category>
		<guid isPermaLink="false">http://www.zhanghu.org/2008/04/23/programming-win-ce-30/</guid>
		<description><![CDATA[//————————————————————————-
// 标题：Windows CE 程序设计(3rd)-第03章 输入：键盘、鼠标和触摸屏 3.0 概述
// 作者：Douglas Boling
// 译者：Zhanghu.org
// 更新时间：2008/04/23
//————————————————————————-
传统上，微软Windows平台为用户提供两种输入方式：键盘和鼠标。Windows CE继承了这一方式，但在其大部分系统上，用输入笔和触摸屏替代了鼠标。从程序角度看，这种变化很小，因为输入笔的消息已经被映射成Windows其它版本中使用的鼠标消息了。同PC版的Windows比，Windows CE上一个很细微但又很重要的变化是要么是只有一个很小的键盘，要么根本没有键盘。这种配置使笔式输入对Windows CE更加重要了。
]]></description>
			<content:encoded><![CDATA[<p>//————————————————————————-<br />
// 标题：Windows CE 程序设计(3rd)-第03章 输入：键盘、鼠标和触摸屏 3.0 概述<br />
// 作者：Douglas Boling<br />
// 译者：Zhanghu.org<br />
// 更新时间：2008/04/23<br />
//————————————————————————-</p>
<p>传统上，微软Windows平台为用户提供两种输入方式：键盘和鼠标。Windows CE继承了这一方式，但在其大部分系统上，用输入笔和触摸屏替代了鼠标。从程序角度看，这种变化很小，因为输入笔的消息已经被映射成Windows其它版本中使用的鼠标消息了。同PC版的Windows比，Windows CE上一个很细微但又很重要的变化是要么是只有一个很小的键盘，要么根本没有键盘。这种配置使笔式输入对Windows CE更加重要了。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zhanghu.org/2008/04/23/programming-win-ce-30/feed/</wfw:commentRss>
		</item>
		<item>
		<title>CString 赋值给 LPTSTR</title>
		<link>http://www.zhanghu.org/2008/04/02/cstring-lptstr/</link>
		<comments>http://www.zhanghu.org/2008/04/02/cstring-lptstr/#comments</comments>
		<pubDate>Wed, 02 Apr 2008 01:34:08 +0000</pubDate>
		<dc:creator>Hu</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.zhanghu.org/2008/04/02/cstring-lptstr/</guid>
		<description><![CDATA[
1
2
3
4
LVITEM  lvi;
CString temp = m_pFiles-&#62;GetAt&#40;i&#41;.strFileName;
lvi.pszText = temp.GetBuffer&#40;temp.GetLength&#40;&#41;&#41;;
temp.ReleaseBuffer&#40;&#41;;

]]></description>
			<content:encoded><![CDATA[
<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code"><pre class="cpp">LVITEM  lvi;
CString temp = m_pFiles-&gt;GetAt<span style="color: #000000;">&#40;</span>i<span style="color: #000000;">&#41;</span>.<span style="color: #00eeff;">strFileName</span>;
lvi.<span style="color: #00eeff;">pszText</span> = temp.<span style="color: #00eeff;">GetBuffer</span><span style="color: #000000;">&#40;</span>temp.<span style="color: #00eeff;">GetLength</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>;
temp.<span style="color: #00eeff;">ReleaseBuffer</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>;</pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://www.zhanghu.org/2008/04/02/cstring-lptstr/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
