win10注册表怎么备份:输入:键盘、鼠标和触摸屏 3.2 鼠标和触摸屏

来源:百度文库 编辑:中财网 时间:2024/04/29 10:08:48

鼠标和触摸屏

和桌面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里的应用程序使用的方式一样。

 

手写笔消息

当用户用手写笔在屏幕上压触时,压触点下的顶层窗口如果此前没有输入焦点的话就会收到焦点,随后收到WM_LBUTTONDOWN消息。当用户抬起手写笔时,窗口会收到WM_LBUTTONUP消息。在手写笔按下的同时在同一个窗口内移动它,窗口就会收到WM_MOUSEMOVE消息。

电子墨水

对手持设备来说最典型的应用是捕捉屏幕上用户在的笔迹并存储下来。这个过程不是手写识别,只是简单的墨迹存储。在开始阶段,完成这个功能的最好方法应该是存储由WM_MOUSEMOVE消息传入的手写笔的各个点。但有个问题,就是有时候这些小型CE设备不能快速的发送消息,导致不能获得满意的分辨率。因此在 Windows CE下,增加了一个函数来帮助程序员追踪手写笔。

1            
BOOL GetMouseMovePoints (PPOINT pptBuf, UINT nBufPoints,UINT *pnPointsRetrieved);

GetMouseMovePoints 返回一批手写笔点,而没有产生WM_MOUSEMOVE消息。函数参数包括点数组、数组大小和一个指向整数的指针,用来接收返回给应用程序的点数。一旦接收完,这些附加的点可以用来填充上一个WM_MOUSEMOVE消息和当前WM_MOUSEMOVE消息之间的空白。

GetMouseMovePoints 产生一条曲线。它是按触摸板的分辨率返回点的,而不是按屏幕的。触摸板的分辨率通常设置为屏幕分辨率的4倍,所以您需要把 GetMouseMovePoints返回的坐标除以4来转换成屏幕坐标。额外的分辨率是用在手写识别之类的程序中的。

在简短的示例程序PenTrac中,演示了GetMouseMovePoints带来的不同之处。图3-4显示了PenTrac窗口。注意观察窗口上的两条点线。上面的线是仅仅使用来自WM_MOUSEMOVE的点绘制的。底下的线则是包括了用GetMouseMovePoints查询到的点,其中黑色点是来自 WM_MOUSEMOVE,而红色(浅色)点是来自GetMouseMovePoints。

 

 

图3-4:显示了两条线的PenTrac窗口 (暂略)

 

 

清单3-2给出了PenTrac的源代码。该程序为每个接收到的WM_MOUSEMOVE或WM_LBUTTONDOWN消息在屏幕上绘制一个点。如果在鼠标移动期间Shift键被按下,PenTrac会调用GetMouseMovePoints并把获得的这些点显示成红色,用于和来自鼠标消息的点进行区分。

为了加强GetMouseMovePoints的效果,PenTrac做了一些手脚。在处理WM_MOUSEMOVE和 WM_LBUTTONDOWN消息的DoMouseMain例程里,调用了sleep函数来消耗掉一些毫秒时间。这个延迟模拟了那些没有时间及时处理每个鼠标移动消息的响应缓慢的应用程序。

清单3-2:PenTrac程序

[程序暂略]

输入焦点和鼠标消息

对于如何以及何时把手写笔产生的鼠标消息发送到不同的窗口,这个过程中涉及的相关规则是需要关注一下的。正如我前面提到的,当手写笔压触到一个窗口上时,系统的输入焦点将发生变化。但是,把手写笔从一个窗口拖动到另一个窗口并不会使新窗口获得输入焦点。因为是下压时才设置焦点,而拖动手写笔滑过窗口是不会设置的。当手写笔拖动出窗口时,该窗口就停止接收WM_MOUSEMOVE消息了,但会继续保持输入焦点。因为手写笔的笔尖依然下压,所以没有其它窗口会接收WM_MOUSEMOVE消息了。这一点与保持鼠标按键按下并拖动出一个窗口很类似。

要想在手写笔即使被移动到窗口外时继续接收手写笔消息,应用程序只要用接收鼠标消息的窗口句柄做参数,调用

  HWND SetCapture (HWND hWnd)

函数就可以了。该函数返回前一个捕捉鼠标消息的窗口的句柄,如果之前没有捕捉过则返回NULL。要停止接收手写笔输入产生的鼠标消息,窗口可以调用

 BOOL ReleaseCapture (void);

函数。任何时候都只有一个窗口可以捕捉手写笔的输入。要判断手写笔是否被捕捉了,可以调用

 HWND GetCapture (void);

函数,它返回捕捉手写笔的窗口的句柄,如果没有窗口捕捉手写笔的输入,则返回0(不过要注意一个警告:返回0只是表示该线程没有捕捉鼠标,并不表示其它线程或进程没有捕捉鼠标)。捕捉手写笔的窗口必须和调用该函数的的窗口在同样的线程环境里。这个限制意味着,如果手写笔被另一个应用里的窗口捕捉了,GetCapture依然返回0。

如果一个窗口捕捉了手写笔而另一个窗口调用了GetCapture,那么最初捕捉手写笔的窗口会收到一个WM_CAPTURECHANGED消息。消息的lParam参数中包含了获得手写笔捕捉的窗口的句柄。您不应该试图调用 GetCapture来取回捕捉。通常,因为手写笔是共享资源,应用程序应该小心谨慎的捕捉手写笔一段时间,并且应该能够优雅地处理捕捉丢失的情况。

另外一个有趣的事情是:正因为窗口捕捉了鼠标,所以它不能阻止在另一个窗口上点击来获得输入焦点。您可以使用其它方法来防止输入焦点的更换,但几乎在所有情况下,最好是让用户而不是程序来决定哪个顶层窗口应该拥有输入焦点。

点击右键

在Windows 系统里,当您在一个对象上单击鼠标右键,通常地会调出上下文相关的、独立的菜单,显示针对该具体对象能做什么的功能项集合。在有鼠标的系统中, Windows发送WM_RBUTTONDOWN和WM_RBUTTONUP消息,指出右键点击了。但是当使用手写笔的时候,不会有右键。不过 Windows CE指导方针中允许您使用手写笔模拟右键点击。指导方针规定,如果用户按下Alt键的同时用手写笔点击屏幕,程序会当成是右键鼠标被点击,并显示相关的上下文菜单。在WM_LBUTTONDOWN的wParam中没有MK_ALT标志,所以判断Alt键是否被按的最好方法是用VK_MENU做参数调用 GetKeyState,并测试返回值的相关位是否被设置了。在这种情况下,GetKeyState是最合适的,因为返回的是鼠标消息从消息队列里取出时的键的状态。

在没有键盘的系统上,采取压下并保持这一姿势来模拟鼠标右键点击。SHRecognizeGesture函数可以用在Pocket PC和具有适当Shell组件的嵌入式Windows CE系统中,用来检查压下并保持这一姿势。函数原型如下:

WINSHELLAPI DWORD SHRecognizeGesture(SHRGINFO *shrg);

唯一的参数是一SHRGINFO结构的地址,该结构定义如下:

typedef struct tagSHRGI{DWORD cbSize;HWND hwndClient;POINT ptDown;DWORD dwFlags;}SHRGINFO,*PSHRGINFO;

cbSize 需要用结构体的大小来填充。hwndClient则需要设置为调用该函数的窗口的句柄。ptDown项需要用识别出姿势时的点结构体来填充。dwFlags则包 含许多标志。SHRG_RETURNCMD标志表示如果用户做出正确的下压保持姿势,则让函数返回GN_CONTEXTMENU;否则就返回0。 SHRG_NOTIFYPARENT标志表示如果识别出正确姿势的话,就给父窗口发送一个WM_NOTIFY消息。SHRG_LONDELAY消息要求在识别出姿势之前,用户需要保持点压一段时间。