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屏上操作,一种是通过扩展面板上的滑块进行移动)。

直接用外部鼠标操作。

通过滑块进行鼠标操作。