clever101
驱动牛犊
驱动牛犊
  • 注册日期2007-10-30
  • 最后登录2007-11-01
  • 粉丝0
  • 关注0
  • 积分30分
  • 威望4点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
阅读:1924回复:2

如何使三维鼠标像普通鼠标一样移动

楼主#
更多 发布于:2007-10-30 23:57
          最近做一个测绘方面的程序,涉及到如何用程序控制三维鼠标。该三维鼠标是美国Immersion Corporation出品的。该三维鼠标并没有提供一个驱动程序,而是提供了一个底层的函数库,实际上就是SDK。该SDK提供了一个例子程序。从这个程序可以看出这个三维鼠标实际上是通过串口通讯的方式和程序进行通讯的。


    现在用户要求我们做的是移动这个三维鼠标的效果要像移动普通鼠标一样,比如在桌子上极快地移动普通鼠标10厘米,可以在屏幕上移动很长的距离(如100厘米),但在桌子上极慢地移动普通鼠标10厘米,那么在屏幕上只能移动20厘米。我发现在三维鼠标中很难模拟这个效果。原因是是什么呢?因为三维鼠标的坐标信息是实时监控和实时转递的,比如我设置数据传输速率为9600bit/s。开始我以鼠标移动后的坐标和移动前坐标相减来获取偏移量来模拟移动鼠标,但是效果不理想,因为还是无法区分极快移动鼠标和极慢移动鼠标的区别。我不知道普通鼠标是如何做到这个效果的(极快和极慢移动鼠标在屏幕上显示出不同的移动距离)。大虾们能否给点思路。
clever101
驱动牛犊
驱动牛犊
  • 注册日期2007-10-30
  • 最后登录2007-11-01
  • 粉丝0
  • 关注0
  • 积分30分
  • 威望4点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
沙发#
发布于: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坐标。
AllenZh
驱动老牛
驱动老牛
  • 注册日期2001-08-19
  • 最后登录2015-11-27
  • 粉丝19
  • 关注10
  • 积分1316分
  • 威望2387点
  • 贡献值7点
  • 好评度321点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2007-10-31 18:13
大家都没有用过你这个鼠标
估计要自己研究研究才行
1,承接Windows下驱动/应用开发 2,本人原创虚拟鼠标/键盘,触摸屏,虚拟显卡,Mirror驱动,XP无盘的SCSI虚拟磁盘驱动等 3,windows下有尝技术服务(包括BUG调试,员工培训等) 欢迎深圳和海外企业联系.msn:mfczmh@sina.com
游客

返回顶部