天天看點

.Net Micro Framework研究—Windows桌面

今天是2007年最後一天,還有幾個小時就迎來充滿期待的2008年了。元旦放假至今不到48個小時的時間裡,我至少有30多個小時坐在電腦前研究MF相關技術,在缺少必要的硬體的情況下,利用現有的資料,擴充了現有的模拟器功能。也希望像我這樣的窮人們,借助模拟器,能體驗一下以前隻有擁有硬體才能調試的功能。

以前為了介紹MF圖形方面的功能,我做了一個“北京2008奧運場館查詢”程式,現在看來那個程式,已經不足以展示MF整體功能的強大。既然Windows 2000 /XP/vista,Windows CE(Windows Mobile)程式都有Windows桌面和開始菜單,那麼我們的.Net Micro Framework也應該有一個。豈能光說不練,下面就是我們MF Windows的桌面和開始菜單。

<a href="http://blog.51cto.com/attachment/201005/113348928.jpg" target="_blank"></a>

看了這個截圖,也許有的網友會認為,這有什麼難,這不是從windows mobile系統上做了一個截圖嘛。實話實說,這樣認為還真是想簡單了,除了windows圖示和小喇叭外,其它部分全部用代碼實作,光字型就用了兩種不同大小的字庫,此外時鐘也不僅僅做個樣子,也是能正常重新整理顯示的。開始菜單我們也有,不僅能選擇,還能執行對應的功能,不要急,下面我們一一說起。

<a href="http://blog.51cto.com/attachment/201005/113421173.jpg" target="_blank"></a>

在上幾篇blog上我說了,我做的模拟器又擴充了兩個鍵(菜單鍵和傳回鍵),别說,這個程式在微軟的模拟器上運作起來還真有問題,因為它不支援菜單鍵,無法彈出菜單來。

菜單上項目也不僅僅是擺設,和模拟器新增的功能結合在一起,做了一個功能測試大荟萃。讓我們先看看GPIO測試的功能在“windows桌面”是怎樣的?

<a href="http://blog.51cto.com/attachment/201005/113428704.jpg" target="_blank"></a>

菜單上選中“GPIO測試”項,按一下鍵盤上的回車或者單擊模拟器上的“OK”鍵,就進入上圖界面。單擊模拟右下角的“&gt;&gt;&gt;”項,展開模拟器上的GPIO測試面闆。

單擊模拟上的I輸入開關,桌面上顯示的輸入資訊也同步發生了變化,Q輸出是有使用者程式控制的,燈會一一亮起或關滅,桌面上的顯示也和模拟器像對應(插一句,千萬不要以為上面模拟器和模拟LCD中的程式為同一個,兩者彼此獨立,使用者程式通過正常的指令和模拟器互動(當然同樣的代碼對實際硬體也一樣))。

下面我們再看看“AD測試”功能。

<a href="http://blog.51cto.com/attachment/201005/113439607.jpg" target="_blank"></a>

通過開始菜單,我們進入“AD測試”子產品,相應的,我們單擊“&lt;&lt;&lt;”旁邊的“GPIO”字元,彈出選擇菜單,我們單擊“AD”,模拟器呈現AD模拟資料操作面闆。

移動滑塊,我們發現桌面中的資料同步發生了改變,不好意思,模拟出部分被彈出菜單給擋住了,我們再來一張截圖。

<a href="http://blog.51cto.com/attachment/201005/113447273.jpg" target="_blank"></a>

QW0是由使用者程式控制的,看的出來,模拟器忠實的擷取了該資料并顯示了出來。說到這裡我還得多說幾句,其實模拟器的部分程式更像運作在實際硬體系統中的IO驅動程式,spi讀寫指令操作的是位元組數組,是以上傳的資料是否浮點型、是否整形等等,全都需要約定,這也決定了不同的廠家對同樣的實體信号進行采集,傳到MF系統中的資料有可能不同,不過通過特定的換算,最終的結果一定是差不多的。

下面說一下I2C總線,I2C我的了解和序列槽通信、CAN口通信差不多,都是兩個相對獨立的裝置進行資料互動,I2C和CAN通信一樣,需要設定裝置位址,此外還需設定一下時鐘主頻。下圖是測試程式界面。

<a href="http://blog.51cto.com/attachment/201005/113456186.jpg" target="_blank"></a>

前三個資料是使用者程式進行修改的,由于有時間差,二者資料重新整理時刻不同,是以不一緻,後五個資料是模拟輸入的,可以看出桌面上的顯示已經可以同步更新了。用這種方式模拟I2C,我也覺得有些不妥,以後有更好的方案我再修改。

細心的使用者一定會發現MF“Windows 桌面”右上角的時間在不斷的變化,第一幅圖是2007年12月31日21:39:23,最後一幅圖的時間是22:27:33,也就是說,寫這篇文章大概花了我50分鐘,這是我在word寫這篇文章的用時,接着再花一些時間寫到我blog上,我想所有的一切完畢後,我想大概就可以聆聽2008年的第一聲鐘聲了。

祝大家新年快樂!!!

附:部分核心代碼

public override void OnRender(DrawingContext dc)  

{  

    //繪制背景                 

    dc.DrawRectangle(new SolidColorBrush(ColorUtility.ColorFromRGB(41,113,189)),null , 0, 0, Width, Height);  

    //菜單條  

    LinearGradientBrush lgb = new LinearGradientBrush(ColorUtility.ColorFromRGB(51,160,241), ColorUtility.ColorFromRGB(16,75,161), 0, 0, Width, 0);  

    dc.DrawRectangle(lgb, null, 0, 0, Width, 26);  

    //開始菜單  

    dc.DrawImage(Resources.GetBitmap(Resources.BitmapResources.Win), 0, 0);   

    //分割線  

    dc.DrawLine(new Pen(Color.White), 26, 0, 26, 25);   

    //顯示“開始”  

    dc.DrawText("開始", YFFont, Color.White, 29, 7);  

    //顯示小喇叭  

    dc.DrawImage(Resources.GetBitmap(Resources.BitmapResources.Sound), 320 - 75, 6);   

    //狀态區  

    dc.DrawRectangle(new SolidColorBrush(ColorUtility.ColorFromRGB(189, 235, 255)), new Pen(Color.Black), 0, Height-26, Width, 26);  

    //辨別  

    dc.DrawText("葉帆工作室榮譽出品", YFFont, Colors.Gray, 200, 220);  

    switch (txtState.TextContent)  

    {  

        case "GPIO測試":  

            string strPace = "   ";  

            dc.DrawText("輸入: I0 I1 I2 I3 I4 I5 I6 I7", YFFont, Colors.Black , 40, 50);  

            dc.DrawText((input[0].Read() ? "1" : "0") + strPace + (input[1].Read() ? "1" : "0") + strPace + (input[2].Read() ? "1" : "0") + strPace + (input[3].Read() ? "1" : "0") + strPace + (input[4].Read() ? "1" : "0") + strPace + (input[5].Read() ? "1" : "0") + strPace + (input[6].Read() ? "1" : "0") + strPace + (input[7].Read() ? "1" : "0"), YFFont, ColorUtility.ColorFromRGB(255, 255, 0), 78, 75);  

            dc.DrawText("輸出: Q0 Q1 Q2 Q3 Q4 Q5 Q6 Q7", YFFont, Colors.Black, 40, 100);  

            dc.DrawText((output[0].Read() ? "1" : "0") + strPace + (output[1].Read() ? "1" : "0") + strPace + (output[2].Read() ? "1" : "0") + strPace + (output[3].Read() ? "1" : "0") + strPace + (output[4].Read() ? "1" : "0") + strPace + (output[5].Read() ? "1" : "0") + strPace + (output[6].Read() ? "1" : "0") + strPace + (output[7].Read() ? "1" : "0"), YFFont, ColorUtility.ColorFromRGB(255, 255, 0), 78, 125);  

            break;  

        case "AD測試":  

            dc.DrawText("AD: AW0=" + ReadWriteAD((Int16)QAW).ToString() + "   QW0=" + QAW.ToString(), YFFont, Colors.White, 60, 100);  

        case "I2C測試":  

            //I2C讀寫  

            byte[] bytRData = new byte[8];  

            byte[] bytWData = new byte[3];  

            bytWData[0] = (byte)IntI2CNum;  

            bytWData[1] = (byte)(IntI2CNum * 2);  

            bytWData[2] = (byte)(IntI2CNum * 3);  

            I2CDevice.I2CTransaction[] i2c = new I2CDevice.I2CTransaction[2];  

            i2c[0] = I2CBus.CreateReadTransaction(bytRData);  

            i2c[1] = I2CBus.CreateWriteTransaction(bytWData);  

            I2CBus.Execute(i2c, 100);   //執行  

            string strPace1 = " ";  

            dc.DrawText("I2C(位元組0-7):", YFFont, Colors.Black, 50, 80);  

            string strInfo = bytRData[0].ToString() + strPace1 + bytRData[1].ToString() + strPace1 + bytRData[2].ToString() + strPace1 + bytRData[3].ToString() + strPace1 + bytRData[4].ToString() + strPace1 + bytRData[5].ToString() + strPace1 + bytRData[6].ToString() + strPace1 + bytRData[7].ToString();  

            dc.DrawText(strInfo, YFFont, ColorUtility.ColorFromRGB(255, 255, 0), 50, 105);  

        default:  

            //.Net Micro Framework  

            dc.DrawRectangle(new SolidColorBrush(Color.White), new Pen(Color.White), 55, 90, Width - 110, 50);  

            dc.DrawText(".Net Micro Framework", Resources.GetFont(Resources.FontResources.MF), Colors.Black, 60, 105);  

            break;   

    }  

    //菜單顯示  

    if (bShowMenu)  

        menu.DrawMenu(dc);   

     }  

 }  

//按鍵資訊  

protected override void OnButtonDown(ButtonEventArgs e)  

    switch (e.Button)  

        //按下确定鍵  

        case Button.Select:  

            if (bShowMenu)  

            {  

                txtState.TextContent = menu.Text;  

                bShowMenu = false;  

                this.UpdateLayout();  

            }  

        //按下左鍵  

        case Button.Left:  

        //按下右鍵  

        case Button.Right:  

        //按向上  

        case Button.Up:  

                menu.SelectIndex--;  

        //按向下  

        case Button.Down:  

                menu.SelectIndex++;  

        //按下菜單  

        case Button.Menu:  

            bShowMenu = !bShowMenu;  

            if (bShowMenu) menu.SelectIndex = 0;  

            this.UpdateLayout();   

        //按下傳回鍵  

        case Button.Back:  

            txtState.TextContent = "就緒";  

}  

本文轉自yefanqiu51CTO部落格,原文連結:http://blog.51cto.com/yfsoft/322933,如需轉載請自行聯系原作者

繼續閱讀