当前位置:   article > 正文

练习:鼠标类设计之1_类内容解析

练习:鼠标类设计之1_类内容解析

前言

        光做理论上的总结,不做练习理解不会那么深刻

        做类的练习,解析类里面的内容有哪些

引入

        电脑使用最频繁的两个外设:鼠标和键盘,他们每时每刻都在和用户交互,试做一个鼠标类

思路

        我们现在要做一个鼠标类,这个类是属于能动类还是资源类呢?鼠标似乎自己做不了什么,需要和其他对象交互才能产生效果,在有的书上也被称作"事件类".他们的使用大概是这个样子的:

  1. class SomeType{ //某个类
  2. private:
  3. ........
  4. public:
  5. RtnType fun(Mouse mouse); //成员方法,鼠标对象作为参数传入
  6. }

鼠标的物理层面

        我们手里使用的鼠标实际上是一个传感器.   他发出了一些信号,比如左键单击,右键单击,左键双击,中键点击,中键上滚(下滚),还有一些鼠标包含左右侧键等等.应该有对应的地址空间去采集这些数据.所以:在鼠标类设计前,应设计一个同步信息类.

        同步信息类的设计

        用途:接收鼠标传来的信号.---标准的资源类.

        说明:笔者并不知道硬件驱动是怎么描述鼠标信息的.做以下假设:

        有5个信号,分别是鼠标左键点击,右键点击,鼠标滚轮滚动,鼠标平移和鼠标升降,他们都是用int存储的.找到他们在内存中的位置,例如0x00,0x04,0x08,0x0c,0x10,定义地址映射

  1. int *lc=(int *)0x00;
  2. int leftClick=*lc; //映射鼠标左键
  3. int *rc=(int *)0x04;
  4. int rightClick=*rc; //映射鼠标右键
  5. int *ro=(int *)0x08;
  6. int roll=*ro; //映射鼠标滚轮
  7. int *m=(int *)0x0c;
  8. int Move=*m; //映射鼠标平移
  9. int *r=(int *)0x10;
  10. int Rise=*r; //映射鼠标升降

        再次声明,因为不知道具体形式,假设部分数据类型所以可能有错---比如左键点击可能只占了1位,而鼠标移动可能是long类型. 还有指针本来不能指向具体内存地址,但关于硬件的部分必须这样做.这里的地址也是假设的,应该由操作系统给出.---------这部分有知道朋友的可以留言讨论

        现在可以创建同步信息类了.

  1. class MouseInfo{
  2. private:
  3. int left_click;
  4. int right_click;
  5. int roll;
  6. int move;
  7. int rise;
  8. public:
  9. MouseInfo(int lc,int rc,int ro,int lm,int rm);
  10. }

        此外,我们还想获取到类属性的状态,例如:中键一定时间内无滚动,一定时间内无左移(右移),视为冻结状态freeze,  添加这部分内容到同步信息类里. 

  1. class MouseInfo{
  2. private:
  3. int left_click; //左键单击
  4. int right_click; //右键单击
  5. int roll; //中键滚动
  6. bool freeze_roll;
  7. int move; //鼠标平移
  8. bool freeze_move;
  9. int rise; //鼠标升降
  10. bool freeze_rise;
  11. bool freeze_all; //全部冻结状态
  12. public:
  13. MouseInfo(int lc,int rc,int ro,int lm,int rm); //构造函数
  14. void freezeJudge(); //冻结状态判断
  15. }

        两个函数实现:        

  1. MouseInfo::MouseInfo(int lc,int rc,int ro,int lm,
  2. int rm):left_click(lc),right_click(rc),roll(ro),
  3. move(lm),rise(rm) //构造函数
  4. {
  5. freeze_roll=true;
  6. freeze_move=true;
  7. freeze_rise=true;
  8. freeze_all=true;
  9. }
  10. void MouseInfo::freezeJudge() //冻结状态判断
  11. {
  12. int rollTemp=roll; //存储当前roll值;
  13. int mTemp=move; //存储当前平移值;
  14. int rTemp=rise; //存储当前升降值;
  15. sleep(50); //延时50毫秒
  16. freeze_roll=(roll==rollTemp)?true:false; //滚动判定
  17. freeze_move=(mTemp==move)?true:false; //平移判定
  18. freeze_rise=(rTemp==rise)?true:false; //升降判定
  19. if(left_click!=1&&right_click!=1&&freeze_roll&&freeze_move&&freeze_rise)
  20. freeze_all=true; //鼠标没输出
  21. else
  22. freeze_all=false;
  23. }

        说明: 定义了几个状态判定变量是否状态发生变化

类的内容      

        类的内容有属性和方法,属性表示对象由什么组成,以及处于某种状态.

        属性是对于对象组成部分对象状态的描述.

        属性和对象的关系如下:

        1>对象被看成一个个体,属性表示个体的组成部分

        举例:有一个抽奖箱,里面装了一些矩形纸片.那么抽奖箱的类里有两个对象:抽奖箱盒子和纸片集合---容器类对象,容器里是纸片.

        2>对象属性可以描述对象.

        举例:纸片对象可以用顶点坐标和长度宽度来描述,所以纸片类属性包括坐标和长度,宽度.具体描述可以用构造方法来说明.  但设计属性时可以先不关注,只需要知道对象和属性必然相关就可以.

        3>对象属性可以描述对象状态

       对象个体必然处于某几种状态之一时,可以把状态设置在属性里,并随时查询.

         举例:鼠标必然处于下列状态之一:左键单击,右键单击,滚轮滚动,鼠标左右移动,鼠标上下移动,冻结状态。下面的鼠标类设计中,鼠标状态是属性内容之一。

鼠标类设计之1:鼠标状态

        考虑到多个状态,使用枚举来描述。具体原因可查看“白话编程--数据篇(4)枚举”

        枚举在c++中作为静态数据,先于对象存在。

        定义一个属性,类型为枚举型。

        定义一个方法,可以获取到枚举值

  1. class Mouse{
  2. public:
  3. /*下列状态表示左击,右击,双击,拖拽,卷动,鼠标平移,升降,冻结*/
  4. enum State{LCLICK,RCLICK,DCLICK,DRAG,ROLL,MOVE,RISE,FREEZE};
  5. private:
  6. State state;
  7. public:
  8. Mouse();
  9. State getState(MouseInfo mi); //传入鼠标信息类对象,获取状态
  10. }

        说明:由于尚未完善程序,所以构造方法可以忽略

 *******************************以下内容已废弃*************************************************************

        实现状态查询方法getState

  1. State getState(MouseInfo mi){
  2. if(mi.left_click==1){
  3. mi.left_click==0; //人为将该值置0
  4. sleep(500);
  5. if(mi.left_click==1)
  6. return DCLICK;
  7. else
  8. return LCLICK; //左键单击或双击判定
  9. if(mi.right_click==1)
  10. return RCLICK;
  11. mi.freezeJudge();
  12. if(!mi.freeze_roll)
  13. return ROLL;
  14. if(!mi.freeze_move)
  15. return MOVE;
  16. if(!mi.freeze_rise)
  17. return RISE;
  18. if(!mi.freeze_all)
  19. return FREEZE;
  20. }

说明:其间顺序不是绝对的,优先级可以自己定义。

细心的朋友可能还会发现问题:没有定义长按鼠标,以及长按后拖拽。---这部分需要硬件支持,笔者设定中按下后一个映射的寄存器为1,抱歉!

 *******************************以上内容已废弃*************************************************************

=========================2024.2.12update===================================

   实现状态查询方法getState

    说明:增加了拖拽判定。

     ------------程序有时候不是一蹴而就的。初贴于2月9日(年三十),开始没想到解决办法,2月12日(初三)作了补充。原来的痕迹留下来,作为记录

  1. State getState(MouseInfo mi){
  2. if(mi.left_click==1){
  3. mi.left_click==0; //人为置0
  4. sleep(500); //延时0.5
  5. if(mi.left_click==1) //采集信息,如果双击或长按将采集到1
  6. mi.left_click==0; //再次人为置0
  7. if(mi.left_click==0) //如果采集到0
  8. return DCLICK; //双击状态确定
  9. else //如果采集到1,作为长按确定,长按不作为单独状态
  10. mi.freezeJudge(); //冻结判定
  11. if(!mi.freeze_move||!mi.freeze_rise)
  12. return DRAG; //拖拽确定
  13. else
  14. return LCLICK; //单击确定
  15. }
  16. if(mi.right_click==1)
  17. return RCLICK; //右键单击确定
  18. mi.freezeJudge();
  19. if(!mi.freeze_roll)
  20. return ROLL; //中键卷动确定
  21. if(!mi.freeze_move)
  22. return MOVE; //鼠标左右移动确定
  23. if(!mi.freeze_rise)
  24. return RISE; //鼠标升降移动确定
  25. if(!mi.freeze_all)
  26. return FREEZE; //鼠标处于冻结状态确定
  27. }

说明:其间顺序不是绝对的,优先级可以自己定义。

再次声明:代码非可直接使用主要是思路!

未完待续。。。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/91784
推荐阅读
相关标签
  

闽ICP备14008679号