MF的标准模块仅支持按键,并不支持鼠标功能。但是对一些常见应用来说,如果没有鼠标(或触摸屏)用起来就太不习惯了。有什么办法可以让MF支持鼠标功能呢?第一,外部设备必须把鼠标信息传到MF应用程序,应用程序根据这些信息绘制鼠标及执行相应的动作。鼠标信息最少包含三种,鼠标按键状态(按下或放开),鼠标坐标(x,y)。
目前,Spi通道可以非常方便地建立设备和用户程序之间的联系,所以就考虑用Spi来实现该功能。
第一步,还是从我编写的模拟器入手,添加了一个Spi驱动类。
//MouseDevice public class MouseComponent : SpiDevice { public static Int16 State = 0; public static Int16 X = 0; public static Int16 Y = 0; protected override byte[] 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 = new byte[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); return bytes; } protected override ushort[] Write(ushort[] data) { //------------ //改写坐标值 try { //State = (Int16)data[0]; //X = (Int16)data[1]; //Y = (Int16)data[2]; } catch { } //------------ //返回当前值 ushort[] Int16s = new ushort[3]; Int16s[0] = (ushort)State; Int16s[1] = (ushort)X; Int16s[2] = (ushort)Y; return Int16s; } } 第二步:编写鼠标应用程序 为了通用,我封装了一个windowbase基类 //鼠标事件 public class MouseEventArgs : EventArgs { public int X; public int Y; public int Button; public MouseEventArgs() { X = 0; Y = 0; Button = 0; State = MouseState.None; } public MouseEventArgs(int x, int y) { X = x; Y = y; Button = 0; State = MouseState.None; } public MouseEventArgs(int x, int y, int button) { X = x; Y = y; Button = button; State = MouseState.None; } } //窗体基类 internal class WindowBase : Window { protected YFWinApp m_app; Thread MouseThread; private ushort state=0, x = 0, y = 0; SPI _spi=null; protected WindowBase(YFWinApp app) { m_app = app; this.Visibility = Visibility.Visible; this.Width = SystemMetrics.ScreenWidth; this.Height = SystemMetrics.ScreenHeight; Buttons.Focus(this); //SPI的pin定义 _spi = new SPI(new SPI.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 = new Thread(new ThreadStart(MouseInfo)); MouseThread.Start(); } protected override void OnButtonDown(ButtonEventArgs e) { this.Close(); m_app.GoHome(); } //获得鼠标信息 private void MouseInfo() { ushort[] bout = new ushort[3]; ushort[] bin = new ushort[3]; ushort mX, 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(new MouseEventArgs(mX, mY, mState)); } if (state != mState) { state = mState; if (state == 1) { OnMouseDown(new MouseEventArgs(mX, mY, mState)); } else if(state==0) { OnMouseUp(new MouseEventArgs(mX, mY, mState)); OnMouseClick(new MouseEventArgs(mX, mY, mState)); } } } } //鼠标移动 protected virtual void OnMouseMove(MouseEventArgs e) { Debug.Print("MouseMove:" + e.X.ToString() + "," + e.Y.ToString() + "," + e.Button.ToString()); } //鼠标单击 protected virtual void OnMouseClick(MouseEventArgs e) { Debug.Print("MouseClick:" + e.X.ToString() + "," + e.Y.ToString() + "," + e.Button.ToString()); } //按下 protected virtual void OnMouseDown(MouseEventArgs e) { Debug.Print("MouseDown:" + e.X.ToString() + "," + e.Y.ToString() + "," + e.Button.ToString()); } //抬起 protected virtual void OnMouseUp(MouseEventArgs e) { Debug.Print("MouseUp:" + e.X.ToString() + "," + e.Y.ToString() + "," + e.Button.ToString()); } //绘制鼠标 public override void OnRender(DrawingContext dc) { if (state == 1) { Pen pp=new Pen(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}; Pen p = new Pen(Color.White, 1); dc.DrawPolygon(null, p, points); } //窗体刷新 protected void Refresh() { this.Left = this.Left; this.UpdateLayout(); } } 下面是我们实际运行的效果图,已经非常完美的支持鼠标了(并且模拟器可两种方式提供鼠标信息,一种是鼠标直接在LCD屏上操作,一种是通过扩展面板上的滑块进行移动)。 直接用外部鼠标操作。 通过滑块进行鼠标操作。