首页 理论教育 操作系统实现之路:鼠标指针

操作系统实现之路:鼠标指针

时间:2023-10-21 理论教育 版权反馈
【摘要】:在介绍消息传递机制之前,先简单介绍一下GUI模块的另外一个重要内容—绘制鼠标指针。鼠标指针的处理,都是在RAWIT线程中实现的。鼠标指针是通过Video对象的画点函数来实现的。每次接收到屏幕更新需求,Video对象首先判断该更新对象是否在鼠标覆盖位置。图11-4 GUI模块的鼠标指针形状鼠标实际上是一个16×16像素的图标,这16×16个像素,并不是都要画出来的,而只是画出需要的一些像素,反映出一个箭头形状即可。

操作系统实现之路:鼠标指针

在介绍消息传递机制之前,先简单介绍一下GUI模块的另外一个重要内容—绘制鼠标指针。鼠标指针的绘制,不但与主动绘制机制有关,而且还与消息传递机制有关联,而消息传递机制是接下来的重点内容。但鼠标绘制的大部分工作,还是绘制本身,因此我们放在这里进行讲解。其中涉及的消息传递机制及RAWIT等线程,暂时不用理会,阅读本章后续内容后,读者自然会明白。

在图形系统中,需要通过鼠标指针动态跟踪鼠标的位置,来实现鼠标的点击输入。在Hello China当前版本的实现中,是通过下列简单的方式实现的:

(1)在RAWIT线程中,实时处理鼠标移动事件(Mouse Move),在鼠标移动事件中,画出鼠标指针。

(2)在画鼠标指针前,首先保存被鼠标图标覆盖的当前屏幕区域,使鼠标在更换位置的时候,能够恢复窗口原有位置的信息。

(3)保存鼠标覆盖区域后,再通过画点的方式,把鼠标图形画到屏幕上。

(4)在鼠标移出当前位置的时候,恢复原来保存的屏幕信息。

鼠标指针的处理,都是在RAWIT线程中实现的。这样可实现如下功能:

(1)鼠标指针的处理,跟实际应用程序无关,是系统级别的处理。这样即使应用程序出现故障,也不会影像鼠标在屏幕上的移动。

(2)鼠标指针是通过Video对象的画点函数(DrawPixel)来实现的。而所有使用GUI功能的应用程序,也都是调用Video对象提供的函数来画出窗口,因此可处理动态屏幕更新的情况:鼠标覆盖住的屏幕位置是动态变化的。比如,鼠标覆盖了一个不断变化的计数器,在鼠标覆盖期间,计数器的数值已经变化。若鼠标移开以后,仍然按照鼠标进入的内容恢复屏幕,则会出现内部不一致的问题。解决这个问题的办法,就是通过Video对象,实时更新鼠标位置。每次接收到屏幕更新需求,Video对象首先判断该更新对象是否在鼠标覆盖位置。若不是,则直接更新,否则,需要在更新数据后,同时保存屏幕更新的数据,并再次画出鼠标指针(鼠标指针永远位于所有屏幕内容之上)。

图11-4是Hello China V1.75版本的GUI模块中,鼠标的指针形状。

978-7-111-41444-5-Chapter11-22.jpg

图11-4 GUI模块的鼠标指针形状

鼠标实际上是一个16×16像素的图标,这16×16个像素,并不是都要画出来的,而只是画出需要的一些像素,反映出一个箭头形状即可。因此,采用一个bit数组,来指明这个16×16像素的方块中,哪些像素需要画出。如下:(www.xing528.com)

978-7-111-41444-5-Chapter11-23.jpg

在上面这个二维数组中,只有标志为1的像素,需要画出。画鼠标指针的代码如下所示:

978-7-111-41444-5-Chapter11-24.jpg

978-7-111-41444-5-Chapter11-25.jpg

在上述代码中,x和y是当前鼠标指针的位置,以x、y坐标为鼠标指针的左上角,画出鼠标指针。该函数在执行前,首先调用SaveMouseRect函数,保存了鼠标矩形所覆盖的屏幕信息,以便后续恢复。SaveMouseRect的代码如下:

978-7-111-41444-5-Chapter11-26.jpg

978-7-111-41444-5-Chapter11-27.jpg

上述代码与DrawMouse代码类似,就是根据鼠标位图(MouseMap),来保存特定的屏幕信息,而不是保存整个16×16像素大小的矩形。

这样就很容易实现鼠标指针的移动了:

978-7-111-41444-5-Chapter11-28.jpg

上述代码中,首先把鼠标位置转换为屏幕位置(因为屏幕分辨率是可以变化的,而鼠标的坐标范围却一直固定),然后调用RestoreMouseRect函数,恢复被鼠标覆盖的矩形。最后再调用DrawMouse函数,在新的位置上画出鼠标指针。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈