阅读:1924回复:2
如何使三维鼠标像普通鼠标一样移动
最近做一个测绘方面的程序,涉及到如何用程序控制三维鼠标。该三维鼠标是美国Immersion Corporation出品的。该三维鼠标并没有提供一个驱动程序,而是提供了一个底层的函数库,实际上就是SDK。该SDK提供了一个例子程序。从这个程序可以看出这个三维鼠标实际上是通过串口通讯的方式和程序进行通讯的。
现在用户要求我们做的是移动这个三维鼠标的效果要像移动普通鼠标一样,比如在桌子上极快地移动普通鼠标10厘米,可以在屏幕上移动很长的距离(如100厘米),但在桌子上极慢地移动普通鼠标10厘米,那么在屏幕上只能移动20厘米。我发现在三维鼠标中很难模拟这个效果。原因是是什么呢?因为三维鼠标的坐标信息是实时监控和实时转递的,比如我设置数据传输速率为9600bit/s。开始我以鼠标移动后的坐标和移动前坐标相减来获取偏移量来模拟移动鼠标,但是效果不理想,因为还是无法区分极快移动鼠标和极慢移动鼠标的区别。我不知道普通鼠标是如何做到这个效果的(极快和极慢移动鼠标在屏幕上显示出不同的移动距离)。大虾们能否给点思路。 |
|
沙发#
发布于:2007-10-30 23:58
例子程序的代码大致如下:
在WinMain函数的代码: /* Get ID value for iboxMsgVal message */ iboxMsgVal = RegisterWindowMessage(IBOX_MESSAGE); // 取得鼠标消息ID值 /* 启动和连接3D鼠标,并进行消息循环*/ if (IboxStart(h, N_ANALOGS, N_ENCODERS) == IBOX_SUCCESS){ MessageBox(NULL, "Ibox Started", "Status", MB_OK); if (IboxConnect(0,0) == IBOX_SUCCESS) { ShowWindow(h,nCmdShow); UpdateWindow(h); while (GetMessage(&msg,NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); } } else { // Handle Connect Fail MessageBox(NULL,"Ibox Connect Failed","Status",MB_OK); } } else { // Handle Start Fail MessageBox(NULL,"Ibox Start Fail","Status",MB_OK); } 在消息处理函数的代码: /**************************************************************** MainWndProc This is the windows procedure to handle all messages for this process. *****************************************************************/ LRESULT WINAPI MainWndProc(HWND win, UINT msg, WPARAM w, LPARAM l) { ibox_rec *ibox; // 这个ibox_rec结构体表示了三维鼠标上多个按钮和按键的信息 char buffer[120]; int j; float count0, count1, count2; /* if the message is an iboxMsgVal, then print out info */ if (msg == iboxMsgVal) { // get the ibox_rec ibox = (ibox_rec *) l; // print out HCI type and serial number sprintf(buffer,"Type: %s Serial Number: %s", (ibox->product_id), ibox->serial_number); TextOut(hdc,10,0,buffer,strlen(buffer)); sprintf(buffer,"Channel:"); TextOut(hdc,10,25,buffer,strlen(buffer)); for (j = 0; (j < max (max(N_ANALOGS, N_ENCODERS),N_BUTTONS)); j++) { sprintf(buffer,"%d ",j); TextOut(hdc,100 + 70*j,25,buffer,strlen(buffer)); } // print out encoders, analogs, buttons if (N_ENCODERS) { sprintf(buffer,"Encoders:"); TextOut(hdc,10,45,buffer,strlen(buffer)); for (j = 0; j < N_ENCODERS; j++) { sprintf(buffer,"%d ",ibox->encoder[j]); TextOut(hdc,100 + 70*j,45,buffer,strlen(buffer)); } } if (N_ANALOGS) { sprintf(buffer,"Analogs:"); TextOut(hdc,10,65,buffer,strlen(buffer)); for (j = 0; j < N_ANALOGS; j++) { sprintf(buffer,"%d ",ibox->analog[j]); TextOut(hdc,100 + 70*j,65,buffer,strlen(buffer)); } } if (N_BUTTONS) { sprintf(buffer,"Buttons:"); TextOut(hdc,10,85,buffer,strlen(buffer)); for (j = 0; j < N_ANALOGS; j++) { sprintf(buffer,"%s ",(ibox->button[j] ? "ON ":"OFF")); TextOut(hdc,100 + 70*j,85,buffer,strlen(buffer)); } } /* If used with softmouse, calculate X, Y, Z position */ if (SOFTMOUSE) { /* Handle rollover, convert encoder counts to inches */ if (ibox->encoder[0] >= 8192) count0= (float) (ibox->encoder[0]-16384); else count0= (float) ibox->encoder[0]; count0= count0/382; if (ibox->encoder[1] >= 8192) count1= (float) (ibox->encoder[1]-16384); else count1= (float)ibox->encoder[1]; count1=count1/382; if (ibox->encoder[2] >= 8192) count2= (float) (ibox->encoder[2]-16384); else count2= (float)ibox->encoder[2]; count2=count2/382; /* sprintf(buffer,"%6.4f %6.4f", count0, count1); TextOut(hdc,10,100,buffer,strlen(buffer)); */ sprintf(buffer," X Y Z "); TextOut(hdc,100,120,buffer,strlen(buffer)); sprintf(buffer,"Softmouse:"); TextOut(hdc,10,135,buffer,strlen(buffer)); /* Calculate cartesian positions from diagonal coordinates */ // 计算笛卡尔坐标系坐标并显示在屏幕上 sprintf(buffer," %6.3f ", (.707*(count0) + 0.707*(count1))); TextOut(hdc,100,135,buffer,strlen(buffer)); sprintf(buffer," %6.3f ", (.707*(count0) - 0.707*(count1))); TextOut(hdc,170,135,buffer,strlen(buffer)); sprintf(buffer," %6.3f ", count2); TextOut(hdc,240,135,buffer,strlen(buffer)); } } else { switch (msg) { case WM_DESTROY : PostQuitMessage(0); break; default : break; } } return (DefWindowProc(win,msg,w,l)); } 实际上该程序就是以串口通讯,实时监控的方式来实时反映三维鼠标的X、Y、Z坐标。 |
|
板凳#
发布于:2007-10-31 18:13
大家都没有用过你这个鼠标
估计要自己研究研究才行 |
|
|