天天看點

.Net Micro Framework研究—模拟器改造

試驗平台:.Net Micro Framework 模拟器

由于Digi提供的開發闆沒有LCD顯示屏,是以有關繪圖方面的操作,隻好在模拟器上進行了。

如果大家參加了9月18日在北京召開的.Net Micro Framework2007技術大會,并且耐心等到最後,大會的禮品U盤裡就有.Net Micro Framework的開發包。

不過微軟這方面對.Net Micro Framework更新很快,如果你到網站上下載下傳,最新的.Net Micro Framework SDK2.0 SP1已經釋出了。

無論怎樣模拟器還是非常難看,估計n個版本之後,才能推出很漂亮的模拟器。正好微軟SDK開發包中,有模拟器外殼的開發程式,是以練練手,給.Net Micro Framework武裝一個“頂級模拟器”。

下面就是我開發的模拟器(應該稱外殼)和微軟自帶的模拟器比較圖,我們先睹為快,接下來我就說說是如何做的。 

(圖:MF071030001.jpg) 

       .Net Micro Framework SDK中的示例程式裡就有一個模拟器外殼開發程式,也就是“SampleEmulator”示例程式,它是一個典型的C#程式(隻不過引用了與.Net Micro Framework相關的幾個庫),你編譯成功後,直接運作,它會彈出下面的提示框。

    (圖:MF071030004.jpg)

    其實它是需要輸入如下指令行參數的:

    "/load:%ProgramFiles%/Microsoft .NET Micro Framework/v2.0.3036/Assemblies/Microsoft.SPOT.TinyCore.pe" "/load:%ProgramFiles%/Microsoft .NET Micro Framework/v2.0.3036/Assemblies/Microsoft.SPOT.Hardware.pe" "/load:../../../../TemperatureSample/TemperatureSample/bin/Debug/TemperatureSample.pe" "/load:%ProgramFiles%/Microsoft .NET Micro Framework/v2.0.3036/Assemblies/Microsoft.SPOT.Graphics.pe" "/load:%ProgramFiles%/Microsoft .NET Micro Framework/v2.0.3036/Assemblies/mscorlib.pe" "/load:%ProgramFiles%/Microsoft .NET Micro Framework/v2.0.3036/Assemblies/Microsoft.SPOT.Native.pe"

     我們先不管這些,我們希望以後.Net Micro Framework程式運作的時候,加載的是我們的模拟器,是以我們要找出系統模拟器的位置,功夫不負有心人,竟然在這個位置:

     C:/Program Files/Microsoft .NET Micro Framework/v2.0.3036/Tools

     檔案名:Microsoft.SPOT.Emulator.Sample.SampleEmulator.exe

     把我們編譯好的模拟器程式(最好先和系統自帶的有所不同)覆寫掉該程式,運作其它程式試試,果然加載的是我們新生成的模拟器。

     好了,看看我是如何做的。

     其實,微軟提供的模拟器外殼程式比較複雜(具體代碼請下載下傳開發包後自行檢視),是以我不僅要換膚,還要對代碼重新進行整理。成績還是斐然的,如button控件,資源圖檔等等統統去掉了,僅添加了一個imagelist控件,就在窗體函數裡實作了該功能。

       詳細代碼如下,有興趣的朋友自己看。

using System;

using System.Drawing;

using System.Threading;

using System.Windows.Forms;

using Microsoft.SPOT.Emulator;

using Microsoft.SPOT.Hardware;

using System.Drawing.Drawing2D;

namespace Microsoft.SPOT.Emulator.Sample

{

    /// <summary>

    /// This is the UI for the LCD sample

    /// </summary>

    public partial class SampleEmulatorForm : Form

    {

        Emulator _emulator;

        //葉帆添加

        Gpio.GpioPort[] _port=new Microsoft.SPOT.Emulator.Gpio.GpioPort[5];

        delegate void PortWriteDelegate(bool fState);

        int intIndex = 0;

        bool[] _pressed = new bool[] {false,false,false,false,false };

        public SampleEmulatorForm(Emulator emulator)

        {

            _emulator = emulator;

            // Initializing the component on the UI form

            InitializeComponent();

        }

        protected override void OnLoad(EventArgs e)

            //Give the buttonCollection focus to allow it to handle keyboard events

            //this.buttonCollection.Select();           

            base.OnLoad(e);

        public void OnInitializeComponent()

            //initialize the lcd control with the lcd emulator component

            this.lcdDisplay.LcdDisplay = _emulator.LcdDisplay;

            //葉帆添加

            _port[0] = _emulator.FindComponentById("Pin_Select") as Gpio.GpioPort;

            _port[1] = _emulator.FindComponentById("Pin_Up") as Gpio.GpioPort;

            _port[2] = _emulator.FindComponentById("Pin_Left") as Gpio.GpioPort;

            _port[3] = _emulator.FindComponentById("Pin_Down") as Gpio.GpioPort;

            _port[4] = _emulator.FindComponentById("Pin_Right") as Gpio.GpioPort;

        //按下葉帆添加

        private void picKey_MouseDown(object sender, MouseEventArgs e)

            //OK

            Rectangle rect = new Rectangle(31, 40, 70, 50);

            intIndex = 0;      

            if (rect.Contains(e.X, e.Y))

            {

                intIndex = 0;

            }

            //UP        

            GraphicsPath path = new GraphicsPath();

            path.AddPolygon(new Point[] {new Point(0,0),new Point(129,0),new Point(100,40),new Point(30,40) });

            if (path.IsVisible(e.X, e.Y))

                intIndex = 1;

            //LEFT

            path.Reset();

            path.AddPolygon(new Point[] { new Point(0, 0), new Point(0, 130), new Point(31, 90), new Point(31, 40) });

                intIndex = 2;

            //DOWN

            path.AddPolygon(new Point[] { new Point(0, 130), new Point(129, 130), new Point(100, 90), new Point(30, 90) });

                intIndex = 3;

            //RIGHT

            path.AddPolygon(new Point[] { new Point(129, 0), new Point(129, 130), new Point(100, 90), new Point(100, 40) });

                intIndex = 4;

            picKey.BackgroundImage = imgKey.Images[intIndex+1];

            OnButtonStateChanged(intIndex, true);

        //彈起葉帆添加

        private void picKey_MouseUp(object sender, MouseEventArgs e)

            picKey.BackgroundImage = imgKey.Images[0];

            OnButtonStateChanged(intIndex, false);

        //按下(無法捕捉方向鍵)

        private void SampleEmulatorForm_KeyDown(object sender, KeyEventArgs e)

        {

        //擡起

        private void SampleEmulatorForm_KeyUp(object sender, KeyEventArgs e)

        //捕捉方向鍵

        protected override bool ProcessDialogKey(Keys keyData)

            switch (keyData)

                case Keys.Enter:

                    intIndex = 0;

                    break;

                case Keys.Up:

                    intIndex = 1;

                case Keys.Left:

                    intIndex = 2;

                case Keys.Down:

                    intIndex = 3;

                case Keys.Right:

                    intIndex = 4;

            picKey.BackgroundImage = imgKey.Images[intIndex + 1];

            return base.ProcessDialogKey(keyData);

        //按鍵狀态改變

        private void OnButtonStateChanged(int index,bool pressed)

            if (_port[index] != null)

                if (_pressed[index] != pressed)

                {

                    _pressed[index] = pressed;

                    bool val = false;

                    switch (_port[index].Resistor)

                    {

                        case Microsoft.SPOT.Emulator.Gpio.GpioResistorMode.Disabled:

                        case Microsoft.SPOT.Emulator.Gpio.GpioResistorMode.PullUp:

                            val = pressed;

                            break;

                        case Microsoft.SPOT.Emulator.Gpio.GpioResistorMode.PullDown:

                            val = !pressed;

                    }

                    //Marshal to MicroFramework thread. 

                    //No need to wait for a response.  Just post the message

                    _port[index].BeginInvoke(new PortWriteDelegate(_port[index].Write), !val);

                }

        }      

    }

}

在下面的網站上,我們還可以下載下傳最新的.Net Micro Framework示例程式,其中“NewPresentation”程式比“Presentation”已高了一個層次,如下圖: 

    (圖:MF071030002.jpg) 

此外這個溫度顯示的示例程式也不錯,我們可以用上下按鈕修改溫度值,如下圖。

(圖:MF071030003.jpg)

不過總體來說,示例程式還是很簡陋的,有時間我自己做一個最炫的(當然網友有做得更好的,别忘了與我分享)。

附錄:經典.Net Micro Framework應用欣賞 

     (圖:MF071030005.jpg)

我做的模拟器外殼,就是從上圖“偷”來的J,不過按鈕單擊效果倒是費了我不少周折。

想想看,用.Net Micro Framework開發MP3/MP4,電子詞典該是多麼容易和簡單,并且效果一定很炫。(上網查了查 Digi核心小子產品要$199,幾千兩銀子呢,介入的廠商越多,相信硬體平台一定會越來越便宜的)。

下面是我開發的模拟器下載下傳位址,有興趣的朋友可以試一試

<a href="http://download.csdn.net/source/274337">http://download.csdn.net/source/274337</a>

繼續閱讀