Microsoft CSIP WindowsMobile MEDC 合作伙伴 体验中心
设Winbile为首页    |    加Winbile到收藏夹          
欢迎光临

[转].Net Micro Framework研究—让MF支持鼠标

第1楼
2008-06-26
男
职务:普通用户
积分:407
等级: 初级程序员三级
金钱: 0
精华: 0
帖子数:27
发帖数前100位(97)

来自:叶帆工作室             作者:叶帆
 
 
      MF的标准模块仅支持按键,并不支持鼠标功能。但是对一些常见应用来说,如果没有鼠标(或触摸屏)用起来就太不习惯了。有什么办法可以让MF支持鼠标功能呢?第一,外部设备必须把鼠标信息传到MF应用程序,应用程序根据这些信息绘制鼠标及执行相应的动作。鼠标信息最少包含三种,鼠标按键状态(按下或放开),鼠标坐标(x,y)。

      目前,Spi通道可以非常方便地建立设备和用户程序之间的联系,所以就考虑用Spi来实现该功能。

      第一步,还是从我编写的模拟器入手,添加了一个Spi驱动类。

//MouseDevice
   publicclassMouseComponent:SpiDevice
    {
       publicstaticInt16State = 0;
       publicstaticInt16X = 0;
       publicstaticInt16Y = 0;
 
       protectedoverridebyte[] Write(byte[] data)
        {
           //------------
           //改写坐标值
           try
            {
               //State = (Int16)((data[0] << 8) + data[1]);
               //X = (Int16)((data[2] << 8) + data[3]);
               //Y = (Int16)((data[4] << 8) + data[5]);
            }
           catch{ }
            //------------
           //返回当前值
           byte[] bytes =newbyte[6];
            bytes[0] = (byte)(State >> 8);
            bytes[1] = (byte)(State & 0xff);
            bytes[2] = (byte)(X >> 8);
            bytes[3] = (byte)(X & 0xff);
            bytes[4] = (byte)(Y >> 8);
            bytes[5] = (byte)(Y & 0xff);
           returnbytes;
        }
       protectedoverrideushort[] Write(ushort[] data)
        {
           //------------
           //改写坐标值
           try
            {
                //State = (Int16)data[0];
               //X = (Int16)data[1];
               //Y = (Int16)data[2];
            }
           catch{ }
           //------------
           //返回当前值
           ushort[] Int16s =newushort[3];
            Int16s[0] = (ushort)State;
            Int16s[1] = (ushort)X;
            Int16s[2] = (ushort)Y;
           returnInt16s;
        }
}
第二步:编写鼠标应用程序
为了通用,我封装了一个windowbase基类
//鼠标事件
       publicclassMouseEventArgs:EventArgs
        {
           publicintX;
           publicintY;
           publicintButton;
           publicMouseEventArgs()
            {
                X = 0;
                Y = 0;
                Button = 0;
                State =MouseState.None;
            }
           publicMouseEventArgs(intx,inty)
            {
                X = x;
                Y = y;
                Button = 0;
                State =MouseState.None;
            }
           publicMouseEventArgs(intx,inty,intbutton)
            {
                X = x;
                Y = y;
                Button = button;
                State =MouseState.None;
            }
        }
       
       //窗体基类
       internalclassWindowBase:Window
        {
           protectedYFWinAppm_app;
            ThreadMouseThread;          
           privateushortstate=0, x = 0, y = 0;
           SPI_spi=null;
 
           protectedWindowBase(YFWinAppapp)
            {
                m_app = app;
               this.Visibility =Visibility.Visible;
               this.Width =SystemMetrics.ScreenWidth;
               this.Height =SystemMetrics.ScreenHeight;
               Buttons.Focus(this);
 
               //SPI的pin定义
                _spi =newSPI(newSPI.Configuration((Cpu.Pin)127,true, 0, 0,false,false, 4000,SPI.SPI_module.SPI1));
                x =(ushort)(this.Width/2);
                y =(ushort)(this.Height/2);
                MouseThread =newThread(newThreadStart(MouseInfo));
                MouseThread.Start();
            }
           
           protectedoverridevoidOnButtonDown(ButtonEventArgse)
            {
               this.Close();
                m_app.GoHome();
            }
           
           //获得鼠标信息
           privatevoidMouseInfo()
            {
               ushort[] bout =newushort[3];
               ushort[] bin =newushort[3];
               ushortmX, mY, mState;
               while(true)
                {
                    //----------------------------------
                   //通过spi通道获取鼠标信息 这部分信息解析和模拟器相对应                   
                    _spi.WriteRead(bout, bin); 
                    mState = bin[0];      //鼠标的状态 1- 按下 0 - 放开
                    mX = bin[1];          //鼠标X坐标
                    mY = bin[2];          //鼠标Y坐标
                   //----------------------------------
 
                   if(x != mX|| y != mY)
                    {
                        x = mX; y = mY;
                        OnMouseMove(newMouseEventArgs(mX, mY, mState));
                    }
                   if(state != mState)
                    {
                        state = mState;
                       if(state == 1)
                        {
                            OnMouseDown(newMouseEventArgs(mX, mY, mState));
                        }
                       elseif(state==0)
                        {
                            OnMouseUp(newMouseEventArgs(mX, mY, mState));
                            OnMouseClick(newMouseEventArgs(mX, mY, mState));                          
                        }
                    }
                }
            }
          
           //鼠标移动
           protectedvirtualvoidOnMouseMove(MouseEventArgse)
            {
               Debug.Print("MouseMove:"+ e.X.ToString() +","+ e.Y.ToString() +","+ e.Button.ToString());
            }
 
           //鼠标单击
           protectedvirtualvoidOnMouseClick(MouseEventArgse)
            {
               Debug.Print("MouseClick:"+ e.X.ToString() +","+ e.Y.ToString() +","+ e.Button.ToString());
            }
 
           //按下
           protectedvirtualvoidOnMouseDown(MouseEventArgse)
            {
               Debug.Print("MouseDown:"+ e.X.ToString() +","+ e.Y.ToString() +","+ e.Button.ToString());
            }
 
           //抬起
           protectedvirtualvoidOnMouseUp(MouseEventArgse)
            {
               Debug.Print("MouseUp:"+ e.X.ToString() +","+ e.Y.ToString() +","+ e.Button.ToString());
            }
           //绘制鼠标
           publicoverridevoidOnRender(DrawingContextdc)
            {
               if(state == 1)
                {
                   Penpp=newPen(ColorUtility.ColorFromRGB(255,255,0));
                    dc.DrawLine(pp, x, y - 5, x, y + 5);
                    dc.DrawLine(pp, x-5, y, x+5, y);
                }
               int[] points = { x, y, x+10, y+4, x+5,y+5, x+4,y+10};
               Penp =newPen(Color.White, 1);
                dc.DrawPolygon(null, p, points);
            }
           //窗体刷新
           protectedvoidRefresh()
            {
               this.Left =this.Left;
               this.UpdateLayout();  
            }
     }
下面是我们实际运行的效果图,已经非常完美的支持鼠标了(并且模拟器可两种方式提供鼠标信息,一种是鼠标直接在LCD屏上操作,一种是通过扩展面板上的滑块进行移动)。
 

直接用外部鼠标操作。

 

通过滑块进行鼠标操作。
 
2008-07-22 10:48 回复 | 引用 | 编辑 | Top