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

简介: MF的标准模块仅支持按键,并不支持鼠标功能。但是对一些常见应用来说,如果没有鼠标(或触摸屏)用起来就太不习惯了

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

直接用外部鼠标操作。
image.png

通过滑块进行鼠标操作。

相关文章
|
1月前
使用的是.NET Framework 4.0,并且需要使用SMTP协议发送电子邮件
使用的是.NET Framework 4.0,并且需要使用SMTP协议发送电子邮件
39 1
|
21天前
|
开发框架 缓存 监控
NET Framework 到 .NET 5/6 的迁移是重大的升级
本文详细介绍了从 .NET Framework 4.8 迁移到 .NET 5/6 的过程,通过具体案例分析了迁移策略与最佳实践,包括技术栈评估、代码迁移、依赖项更新及数据库访问层的调整,强调了分阶段迁移、保持代码可维护性及性能监控的重要性。
44 3
|
29天前
|
机器学习/深度学习 编解码 算法
【小样本图像分割-4】nnU-Net: Self-adapting Framework for U-Net-Based Medical Image Segmentation
《nnU-Net: 自适应框架用于基于U-Net的医学图像分割》是一篇2018年的论文,发表在Nature上。该研究提出了一种自适应的医学图像分割框架nnU-Net,能够自动调整模型的超参数以适应不同的数据集。通过2D和3D U-Net及级联U-Net的组合,nnU-Net在10个医学分割数据集上取得了卓越的性能,无需手动调整。该方法强调数据增强、预处理和训练策略等技巧,为医学图像分割提供了一个强大的解决方案。
59 0
【小样本图像分割-4】nnU-Net: Self-adapting Framework for U-Net-Based Medical Image Segmentation
winform .net6 和 framework 的图表控件,为啥项目中不存在chart控件,该如何解决?
本文讨论了在基于.NET 6和.NET Framework的WinForms项目中添加图表控件的不同方法。由于.NET 6的WinForms项目默认不包含Chart控件,可以通过NuGet包管理器安装如ScottPlot等图表插件。而对于基于.NET Framework的WinForms项目,Chart控件是默认存在的,也可以通过NuGet安装额外的图表插件,例如LiveCharts。文中提供了通过NuGet添加图表控件的步骤和截图说明。
winform .net6 和 framework 的图表控件,为啥项目中不存在chart控件,该如何解决?
|
3月前
|
开发框架 缓存 前端开发
实战.NET Framework 迁移到 .NET 5/6
从.NET Framework 迁移到.NET 5/6 是一次重要的技术革新,涵盖开发环境与应用架构的全面升级。本文通过具体案例详细解析迁移流程,包括评估现有应用、利用.NET Portability Analyzer 工具识别可移植代码、创建新项目、逐步迁移代码及处理依赖项更新等关键步骤。特别关注命名空间调整、JSON 序列化工具更换及数据库访问层重构等内容,旨在帮助开发者掌握最佳实践,确保迁移过程平稳高效,同时提升应用性能与可维护性。
112 2
|
3月前
|
开发框架 JSON 监控
实战指南:从 .NET Framework 迁移到 .NET 5/6 的策略与最佳实践
【8月更文挑战第28天】从 .NET Framework 迁移到 .NET 5/6 是一次重要的技术升级,涉及开发环境与应用架构的改进。本文通过具体案例分析,介绍迁移策略与最佳实践,帮助开发者顺利完成转变。
74 1
|
3月前
|
缓存 程序员
封装一个给 .NET Framework 用的内存缓存帮助类
封装一个给 .NET Framework 用的内存缓存帮助类
|
3月前
|
XML JSON 程序员
总结一下 .NET FrameWork 和 .NET Core 创建的项目的不同点
总结一下 .NET FrameWork 和 .NET Core 创建的项目的不同点
|
3月前
分享一份 .NET Core 简单的自带日志系统配置,平时做一些测试或个人代码研究,用它就可以了
分享一份 .NET Core 简单的自带日志系统配置,平时做一些测试或个人代码研究,用它就可以了