阅读:1927回复:6
鼠标编程一问
我想编个程序,用键盘模拟鼠标做一些简单的动作,譬如使用方向键来移动鼠标(都是ps2的)。我看了一下mousedev.c,但是并不是很明白。究竟是怎样放松一个鼠标移动的消息给系统的呢?请大家指点一下我该怎么做啊!谢谢了!
|
|
沙发#
发布于:2003-07-25 15:30
为什么要这么做?有没有现成的例子,发给我一个?
alexyi@kinposh.com.cn |
|
板凳#
发布于:2003-07-28 09:31
只是想看看系统是如何接收键盘鼠标信息。请各位帮忙。
|
|
地板#
发布于:2003-07-31 01:39
GUI的鼠标事件的原理大致是这样的:
当鼠标有中断发生时,驱动程序将事件按发生的先后次序将鼠标按键、鼠标相对于上一次产生的偏移dx,dy组成数据投递到鼠 标设备文件中(ps/2是/dev/psaux,/dev/mouse一般都是建立的软链接), 按键的数据格式如下: #ifdef MMOUSE_SUPPORT #ifdef EMULATE_3_BUTTONS static char button[8] = { 0, 1, 2, 4, 4, 0, 0,0}; #else static char button[8] = { 0, 1, 2, 3, 4, 0, 0,0}; #endif #else static char button[8] = {0, 1, 2, 3, 0, 0, 0, 0}; #endif 我们要做的是打开和初始化鼠标设备,再从设备文件里每次循环读取3个字节进行处理,注意,鼠标的事件是三维的,但目前 我们的鼠标z轴衡为0: static int PS2_Read(int *dx, int *dy, int *dz, char *bp) { static unsigned char buf[3] = {0, 0, 0}; static int nbytes =0; int n; int temp; //int buttons[4] = { 0, 1, 2, 4}; /* 0 没有键(但移动) 4 左键1 右键5 左右键同时 */ while((n = read(mouse_fd, &buf[nbytes], 3 - nbytes))) {/*n 为所读的字节数*/ if(n < 0) { if (errno == EINTR || errno == EAGAIN) return 0; else return -1; } nbytes += n; /*保证读了3 个字节*/ if(nbytes == 3) { /* Check header byte. */ /*buf[0]头两位为头信息标识,第六位dx符号,第七位dy符号*/ if ((buf[0] & 0xc0) != 0) { /*11000000*/ buf[0] = buf[1]; buf[1] = buf[2]; nbytes = 2; return -1; } //得到bp,dx,dy,dz temp = buf[0] & 0x07; // temp = buf[0] & 0x03; *bp =button[temp]; *dx = (buf[0] & 0x10) ? buf[1] - 256 : buf[1]; *dy = (buf[0] & 0x20) ? -(buf[2] - 256) : -buf[2]; *dz = 0; nbytes = 0; return 1; } } return 0; } 接着,GUI会产生鼠标键盘事件,他们都是在一起处理的,在这一层上,鼠标,键盘都是一样的,你可以在这一层进行键盘对 鼠标事件进行模拟,接着,GUI会根据鼠标键盘事件产生出相应的消息,这个过程鼠标移动的偏移经过缩放因子(我们在GUI 设置中调节的鼠标灵敏度就是调节缩放因子),以及和你原来记录的鼠标位置叠加处理成鼠标在屏幕上的位置,即屏幕坐标 ,经过消息循环的处理,投递到相应的GUI窗口上去(屏幕坐标也相宜转换为窗口坐标),你可以到http://www.minigui.com 上下载MINIGUI source code,对照里面的程序,应该就清楚了,当然你完全可以在消息处理这一层做,截获系统的左右按键,将他 们生产鼠标移动的小心,但由于鼠标消息涉及到一个加速的概念,处理起来有点麻烦,最好的就是在产生事件那一层上去做 ,那样会很好做 |
|
地下室#
发布于:2003-07-31 09:57
to stonepine:
十分感谢你的回答! 但是还有两点不太清楚: 1。这个程序可以不在驱动程序的那一层来做,是吗?如果是截获鼠标键盘的事件,那么请问,这些事件是什么呢?譬如在Windows上就有键盘按键或鼠标移动的事件,所以在Windows上实现起来是比较简单的。 2。如果我是想往设备文件中填写数据,请问该怎样做?就是说,其实鼠标并没有移动,但是填了这些数据后,就好像鼠标已经被移动了一样。 因为我想这样做,不知道行不行得通。鼠标并未移动,但是我按了某一个键,就往鼠标的设备文件中填写一些数据,这样我不管上层是如何去读取这些数据的,只要他读到了,就知道是鼠标移动了,然后屏幕上的光标理所当然的就会移动。(不知道说清楚了没,^_^表述得不是很好)。 好像光是这样想想觉得挺容易的,但是,就是不知道怎么去实现。 请大家帮帮忙讨论一下好吗?我很弱,对那些太底层的东西并不太懂。谢了! |
|
5楼#
发布于:2003-07-31 12:18
1、ok,我们就以windows为例,如果你只是想在你建立的窗口中用键盘模拟鼠标玩玩,你应该去截获键盘KEYDOWN和KEYUP消息,另外你需要将重复按键(在windows的CHAR消息中会有域带出重复按键的个数来)处理成鼠标加速,再转换为鼠标消息投递到消息循环中(以上消息名称我记得不清楚,特别是那个CHAR消息,windows不是这么叫的,可我就是想不起来,手头又没有MSDN,你可以查MSDN的SDK编程帮助,很清楚的),如果你要使按键对所有窗口都起模拟作用,我觉得以上办法还是行不通,估计要用消息钩子,把按键消息勾过来,处理之后再送到系统消息循环中。
2、这个想法是好,可惜行不通,也违背了驱动程序的本来含义,呵呵。行不通的道理简单,其一就是你这样做相当于模拟了一个设备,也就是说是两个设备往一个设备文件里写数据,结果自然会乱,起码鼠标会乱飞,也就不是鼠标了,而是飞标,呵呵。 |
|
6楼#
发布于:2003-07-31 16:03
to stonepine:
1.nod。可是我不知道在linux中的那些事件啊。你的意思是不是所用的GUI的不同,消息处理事件也不同? 譬如MiniGUI和X Window。如果我要做下去的话,就得先确定好一个GUI?是这样吗? 2.哦,好像有点明白了。还想弱弱的再问一下。触摸屏的驱动原理又是什么呢?应该和鼠标有点像吧。虽然他和鼠标是往两个设备文件里写数据,但他们两个控制的是同一个屏幕上的同一个光标,为什么光标不会乱飞呢? 很感谢你,这两天我想这些问题都有点头发晕了。 :) |
|