• Hello China GUI模块鼠标指针的实现


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

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

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

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

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

     

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

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

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

     

    下面是Hello China V1.6版本的GUI模块中,鼠标的指针形状:

     

     

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

     

    static int MouseMap[16][16] = {

           {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},

           {1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0},

           {1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0},

           {1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0},

           {1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0},

           {1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0},

           {1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0},

           {1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0},

           {1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0},

           {1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0},

           {1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0},

           {1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0},

           {1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0},

           {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},

           {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},

           {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},

    };

     

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

     

    static VOID DrawMouse(__VIDEO* pVideo,int x,int y)

    {

           int i,j;

           //Save the rect occupied by mouse first.

           SaveMouseRect(pVideo,x,y);

           for(i = 0;i < 16;i ++)

           {

                  if(y + i >= (int)pVideo->dwScreenHeight)

                  {

                         break;

                  }

                  for(j = 0;j < 16;j ++)

                  {

                         if(MouseMap[i][j])  //Should draw.

                         {

                                if(x + j >= (int)pVideo->dwScreenWidth)

                                {

                                       break;

                                }

                                DrawPixel(pVideo,x + j,y + i,COLOR_BLACK);

                         }

                  }

           }

    }

     

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

     

    static VOID SaveMouseRect(__VIDEO* pVideo,int x,int y)

    {

           int i,j;

           for(i = 0;i < 16;i ++)

           {

                  if(y + i >= (int)pVideo->dwScreenHeight)

                  {

                         break;

                  }

                  for(j = 0;j < 16;j ++)

                  {

                         if(x + j >= (int)pVideo->dwScreenWidth)

                         {

                                break;

                         }

                         if(MouseMap[i][j])

                         {

                                MouseRect[i][j] = GetPixel(pVideo,x + j,y + i);

                         }

                  }

           }

    }

     

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

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

     

    static VOID DoMouseMove(int x,int y)  //x and y is the coordinate of mouse.

    {

           static int xppos = 0;  //Previous position of x.

           static int yppos = 0;  //Previous position of y.

           int xpos,ypos;

     

           MouseToScreen(&Video,x,y,&xpos,&ypos);

           RestoreMouseRect(&Video,xppos,yppos);  //Restore previous screen rectangle.

           DrawMouse(&Video,xpos,ypos);  //Draw mouse in the new location.

           xppos = xpos;

           yppos = ypos;

    }

     

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

     

  • 相关阅读:
    python易错点2
    python易错点1
    Spring:注解组件注册
    KubeSphere建立多租户系统
    Centos7.7下KubeSphere最小化安装和定制化配置安装
    安装create-react-app
    查看react版本等信息
    react自动生成React组件命令
    sqlserver 随机数
    Error while downloading 'http://java.sun.com/xml/ns/javaee/javaee_web_services_client_1_2.xsd'
  • 原文地址:https://www.cnblogs.com/new0801/p/6176095.html
Copyright © 2020-2023  润新知