生活随笔
收集整理的這篇文章主要介紹了
.Net Micro Framework研究—实现SideShow窗体界面
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
基于MF系統(tǒng)的Windows SideShow界面是非常炫的(如下圖)。既然微軟能用.Net Micro Framework實(shí)現(xiàn)這么棒的界面效果,我想我們也能做到。
(SideShow模擬器界面和游戲程序中的右鍵菜單—注意菜單彈出后,其它的界面變暗了)
現(xiàn)在的任務(wù)是設(shè)計(jì)一套支持鼠標(biāo)(或觸摸屏)的窗體框架(目前MF提供的Window類僅支持按鍵功能),所以正好把SideShow如此炫的界面元素也可以添加進(jìn)來。
用過MF的人知道是用下面的方法來實(shí)現(xiàn)按鍵事件接收的,既然我們要支持鼠標(biāo)功能,所以最好也用類似的機(jī)理實(shí)現(xiàn)。
???
? ????protected?override?void?OnButtonDown(ButtonEventArgs?e) ? ????{ ? ????????switch?(e.Button) ? ????????{ ? ????????????? ????????????case?Button.Select: ? ????????????????break; ? ????????????? ????????????case?Button.Left: ? ????????????????break; ? ????????????? ????????????case?Button.Right: ? ????????????????break; ? ????????????? ????????????case?Button.Up: ? ????????????????break; ? ????????????? ????????????case?Button.Down: ? ????????????????break; ? ????????????? ????????????case?Button.Menu: ? ????????????????break; ? ????????????? ????????????case?Button.Back: ? ????????????????break; ? ????????} ? ????????base.OnButtonDown(e); ? ????} ?用反編譯工具仔細(xì)研究了MF底層庫代碼(.Net FrameWork 太龐大了,一個(gè)人絕對(duì)短時(shí)間內(nèi)看不完,其實(shí)也很難看下去,但是對(duì)剛剛起步的MF來說,.Net Micro FrameWork就簡(jiǎn)單多了),終于理清了頭緒。主要原理是在鼠標(biāo)信息處理線程中通過Application.Current.Windows 屬性(該屬性存放了當(dāng)前實(shí)例所有派生于Window類的窗體)和應(yīng)用實(shí)例的this.Dispatcher屬性的BeginInvoke方法,外部調(diào)用窗體鼠標(biāo)事件函數(shù)。充分利用基類虛函數(shù)的妙處來實(shí)現(xiàn)類似按鍵信息處理的功能。
在YFWindowBase類中聲明如下虛擬鼠標(biāo)事件函數(shù)。
?
? ????public?virtual?void?OnMouseMove(object?sender,?MouseEventArgs?e) ? ????{ ? ????????if?(MouseMove?!=?null)?MouseMove(sender,?e); ? ????} ? ????? ????public?virtual?void?OnMouseClick(object?sender,?MouseEventArgs?e) ? ????{ ? ????????if?(MouseClick?!=?null)?MouseClick(sender,?e); ? ????} ? ????? ????public?virtual?void?OnMouseDown(object?sender,?MouseEventArgs?e) ? ????{ ? ???????if?(MouseDown?!=?null)?MouseDown(sender,?e); ? ????} ? ????? ????public?virtual?void?OnMouseUp(object?sender,?MouseEventArgs?e) ? ????{ ? ????????if?(MouseUp?!=?null)?MouseUp(sender,?e); ? ????} ?? ?在鼠標(biāo)信息處理函數(shù)中執(zhí)行如下的代碼即可。
???
? ????private?static?void?TransactMouse(MouseState?state,?int?x,?int?y,?MouseButtons?button) ? ????{ ? ????????if?(Application.Current?==?null)?return; ? ????????for?(int?i?=?Application.Current.Windows.Count?-?1;?i?>=?0;?i--) ? ????????{ ? ????????????try? ????????????{ ? ????????????????YFWindowBase?mw?=?Application.Current.Windows[i]?as?YFWindowBase; ? ? ? ????????????????if?(mw.Enabled?&&?mw.IsVisible) ? ????????????????{ ? ????????????????????? ????????????????????bool?bReturn?=?false; ? ????????????????????for?(int?j?=?mw.Children.Count?-?1;?j?>=?0;?j--) ? ????????????????????{ ? ????????????????????????? ????????????????????????YFControl?cl?=?mw.Children[j]; ? ????????????????????????if?(!bReturn?&&?cl.Visible?&&?IsRectContains(x,?y,?mw.Left?+?cl.Left,?mw.Top?+?cl.Top,?cl.Width,?cl.Height)) ? ????????????????????????{ ? ????????????????????????????if?(cl.Enable)?? ????????????????????????????{ ? ????????????????????????????????if?(!cl._EnterFlag) ? ????????????????????????????????{ ? ????????????????????????????????????cl._EnterFlag?=?true; ? ????????????????????????????????????_dispatcher.BeginInvoke(new?MouseInputEventHandler(cl.OnMouseEnter),?cl,?new?MouseEventArgs(button,?x?-?cl.Left?-?mw.Left,?y?-?cl.Top?-?mw.Top)); ? ????????????????????????????????} ? ????????????????????????????????if?((state?&?MouseState.Move)?>?0) ? ????????????????????????????????????_dispatcher.BeginInvoke(new?MouseInputEventHandler(cl.OnMouseMove),?cl,?new?MouseEventArgs(button,?x?-?cl.Left?-?mw.Left,?y?-?cl.Top?-?mw.Top)); ? ????????????????????????????????if?((state?&?MouseState.Down)?>?0) ? ????????????????????????????????????_dispatcher.BeginInvoke(new?MouseInputEventHandler(cl.OnMouseDown),?cl,?new?MouseEventArgs(button,?x?-?cl.Left?-?mw.Left,?y?-?cl.Top?-?mw.Top)); ? ????????????????????????????????if?((state?&?MouseState.Up)?>?0) ? ????????????????????????????????????_dispatcher.BeginInvoke(new?MouseInputEventHandler(cl.OnMouseUp),?cl,?new?MouseEventArgs(button,?x?-?cl.Left?-?mw.Left,?y?-?cl.Top?-?mw.Top)); ? ????????????????????????????????if?((state?&?MouseState.Click)?>?0) ? ????????????????????????????????????_dispatcher.BeginInvoke(new?MouseInputEventHandler(cl.OnMouseClick),?cl,?new?MouseEventArgs(button,?x?-?cl.Left?-?mw.Left,?y?-?cl.Top?-?mw.Top)); ? ????????????????????????????} ? ????????????????????????????? ????????????????????????????if?((state?&?MouseState.Event)?>?0) ? ????????????????????????????????_dispatcher.BeginInvoke(new?MouseInputEventHandler(mw.OnMouseEvent),?mw,?new?MouseEventArgs(button,?x?-?mw.Left,?y?-?mw.Top)); ? ????????????????????????????bReturn?=?true; ? ????????????????????????} ? ????????????????????????else? ????????????????????????{ ? ????????????????????????????if?(cl._EnterFlag) ? ????????????????????????????{ ? ????????????????????????????????cl._EnterFlag?=?false; ? ????????????????????????????????_dispatcher.BeginInvoke(new?MouseInputEventHandler(cl.OnMouseLeave),?cl,?new?MouseEventArgs(button,?x?-?cl.Left,?y?-?cl.Top)); ? ????????????????????????????} ?????????????????????????} ?????????????????????} ? ????????????????????if?(bReturn)?return; ? ????????????????} ?? ? ????????????????? ????????????????if?(mw.IsVisible?&&?IsRectContains(x,?y,?mw.Left,?mw.Top,?mw.Width,?mw.Height)) ? ????????????????{ ? ????????????????????if?(!mw.Enabled)?return; ? ? ? ????????????????????if?((state?&?MouseState.Move)?>?0) ? ????????????????????????_dispatcher.BeginInvoke(new?MouseInputEventHandler(mw.OnMouseMove),?mw,?new?MouseEventArgs(button,?x?-?mw.Left,?y?-?mw.Top)); ? ????????????????????if?((state?&?MouseState.Down)?>?0) ? ????????????????????????_dispatcher.BeginInvoke(new?MouseInputEventHandler(mw.OnMouseDown),?mw,?new?MouseEventArgs(button,?x?-?mw.Left,?y?-?mw.Top)); ? ????????????????????if?((state?&?MouseState.Up)?>?0) ? ????????????????????????_dispatcher.BeginInvoke(new?MouseInputEventHandler(mw.OnMouseUp),?mw,?new?MouseEventArgs(button,?x?-?mw.Left,?y?-?mw.Top)); ? ????????????????????if?((state?&?MouseState.Click)?>?0) ? ????????????????????????_dispatcher.BeginInvoke(new?MouseInputEventHandler(mw.OnMouseClick),?mw,?new?MouseEventArgs(button,?x?-?mw.Left,?y?-?mw.Top)); ? ????????????????????if?((state?&?MouseState.Event)?>?0) ? ????????????????????????_dispatcher.BeginInvoke(new?MouseInputEventHandler(mw.OnMouseEvent),?mw,?new?MouseEventArgs(button,?x?-?mw.Left,?y?-?mw.Top)); ? ????????????????????return; ? ????????????????} ?????????????} ? ????????????catch?(Exception?e) ? ????????????{ ? ????????????????throw?new?Exception(e.Message.ToString(),?e); ? ????????????} ?????????} ?????} ?? 用戶程序的窗體類只要派生于YFWindowBase類,就可以直接支持鼠標(biāo)和按鍵功能了。用戶代碼如下:
???
? ???internal?sealed?class?MFWindow?:YFWindowBase ? ???{ ? ???????public?YFLabel?label1; ? ???????YFButton?button1,?button2,?button3,?button4,?button5; ? ???????public?MFWindow() ? ???????{ ? ???????????? ???????????label1?=?new?YFLabel("就緒",?0,?Height?-?25,?Width,?25); ? ???????????label1.TextAlign?=?TextAlignment.Left; ????????????label1.BackColor?=?ColorUtility.ColorFromRGB(189,?235,?255); ????????????label1.BorderStyle?=?BorderStyle.FixedSingle; ? ???????????? ???????????button1?=?new?YFButton("觸摸屏校準(zhǔn)",?30,?35,?90,?40); ? ???????????button1.MouseClick?+=?new?MouseInputEventHandler(button_MouseClick); ? ???????????button2?=?new?YFButton("計(jì)算器",200,?35,?90,?40); ? ???????????button2.MouseClick?+=?new?MouseInputEventHandler(button_MouseClick); ? ???????????button3?=?new?YFButton("簡(jiǎn)易記事本",?30,?135,?90,?40); ? ???????????button3.MouseClick?+=?new?MouseInputEventHandler(button_MouseClick); ? ???????????button4?=?new?YFButton("關(guān)于...",?200,?135,?90,?40); ? ???????????button4.MouseClick?+=?new?MouseInputEventHandler(button_MouseClick); ? ???????????button5?=?new?YFButton("主菜單",?125,?85,?70,?40); ? ???????????button5.MouseClick?+=?new?MouseInputEventHandler(button_MouseClick); ? ???????????Children.Add(button1); ????????????Children.Add(button2); ????????????Children.Add(button3); ????????????Children.Add(button4); ????????????Children.Add(button5); ????????????Children.Add(label1); ? ???????????button3.Enable?=?false; ? ???????????? ???????????? ???????????Menu.AddItem(new?MenuItem("觸摸屏校準(zhǔn)")); ? ???????????Menu.AddItem(new?MenuItem("-")); ? ???????????Menu.AddItem(new?MenuItem("計(jì)算器")); ? ???????????Menu.AddItem(new?MenuItem("簡(jiǎn)易記事本")); ? ???????????Menu.AddItem(new?MenuItem("-")); ? ???????????Menu.AddItem(new?MenuItem("關(guān)于...")); ? ???????????Menu[3].Enabled?=?false; ? ???????????? ???????}???????? ? ???????? ???????void?button_MouseClick(object?sender,?MouseEventArgs?e) ? ???????{ ????????????YFButton?button=((YFButton)sender); ? ???????????switch?(button.Text) ? ???????????{ ? ???????????????case?"主菜單": ? ???????????????????? ???????????????????this.Menu.Show(); ? ???????????????????break; ? ???????????????default: ? ???????????????????OnMenuClick(new?MenuEventArgs(0,?button.Text)); ? ???????????????????break; ? ???????????}?????????????????????????? ????????} ?運(yùn)行后的界面如下:
?
圖1:主界面(按鈕即支持鼠標(biāo)也可以用按鍵切換輸入焦點(diǎn)(right鍵等同于PC平臺(tái)上的Tab鍵),并用OK鍵觸發(fā)按鍵事件)
?
圖2:單擊主菜單按鈕或單擊“Menu”就可以彈出主菜單
?
圖3:不要小看了上圖的藍(lán)色小圓,是我費(fèi)了好大勁才繪制出來的(目前MF僅支持矩形框的填充)。
?
private?void?DrawCircle(Color?c,int?x,?int?y,?int?r,?DrawingContext?dc) ?????{ ? ????????Pen?p=new?Pen(c); ? ????????SolidColorBrush?b?=?new?SolidColorBrush(c); ? ????????int?Offset45=(int)(0.707*r); ? ????????int?Offset30?=?r?/?2; ? ????????int?Offset60?=?(int)(0.866?*?r); ? ? ? ????????for?(int?i?=?Offset45;?i?<?r?+?1;?i++) ? ????????{ ?????????????dc.DrawEllipse(null,?p,?x,?y,?i,?i); ?????????} ?????????dc.DrawRectangle(b,?null,?x?-?Offset45,?y?-?Offset45,Offset45*2,?Offset45*2); ?????????dc.DrawRectangle(b,?null,?x?-?Offset60,?y?-?Offset30,?Offset60?*?2,?Offset30?*?2); ?????????dc.DrawRectangle(b,?null,?x?-?Offset30,?y?-?Offset60,?Offset30?*?2,?Offset60?*?2); ?? ?????????dc.DrawLine(p,?x?-?Offset60,?y?-?Offset30,?x?-?Offset30,?y?-?Offset60); ?????????dc.DrawLine(p,?x+?Offset60?,?y?+?Offset30,?x?+?Offset30?,y?+?Offset60?); ?????????dc.DrawLine(p,?x?-?Offset60,?y?+?Offset30,?x?-?Offset30?,?y?+?Offset60); ?????????dc.DrawLine(p,?x?+?Offset60,?y?-?Offset30,?x?+?Offset30,?y?-?Offset60); ????} ?? ?? ?圖5:終于在MF上實(shí)現(xiàn)了計(jì)算器的功能,目前不僅支持鼠標(biāo),也可以用光標(biāo)鍵和OK鍵進(jìn)行輸入計(jì)算了。
別小看了計(jì)算器程序,由于MF僅有數(shù)字轉(zhuǎn)字符串功能,沒有實(shí)現(xiàn)字符串轉(zhuǎn)數(shù)字的功能,我自己自定義了一些函數(shù),用了一些特殊的用法才編寫完成。
?
? if?(strInput?==?"0.")?dblInput?=?0; ? ????????if?(strInput?!=?"0.") ? ????????{ ?????????????strInput?+=?b.Text; ? ????????????if?(strInput.IndexOf('.')<1) ? ????????????{ ?????????????????dblInput?*=?10; ?????????????????dblInput?+=?ToDouble(b.Text); ?????????????} ? ????????????else? ????????????{ ? ????????????????int?index?=?strInput.Length?-?strInput.LastIndexOf('.')?-?1; ? ????????????????dblInput?+=?ToDouble(b.Text)?/System.Math.Pow(10,index); ?????????????} ?????????} ? ????????else?if?(b.Text?!=?"0") ? ????????{ ?????????????strInput?=?b.Text; ?????????????dblInput?=?ToDouble(b.Text); ??????} ??? 下面是窗體的界面搭建部分,你絕對(duì)想不到用這么短的代碼就實(shí)現(xiàn)了上圖的界面布局(看過我以前.Net Micro Framework研究的網(wǎng)友,應(yīng)該對(duì)MF本身提供的控件有印象,正是因?yàn)橄到y(tǒng)的控件不好用,我專門重新寫了一套MF控件類)。
???
?YFButton[]?button=new?YFButton[20]; ? ????YFLabel?lblInput?=?null; ? ????string[]?strText?=?new?string[]?{?"7",?"8",?"9",?"/",?"CE",?"4",?"5",?"6",?"*",?"%",?"1",?"2",?"3",?"-",?"1/x",?"0",?"+/-",?".",?"+",?"="?}; ? ????public?YFCalc(string?Title,int?Width,int?Height,YFWindowBase?Parent) ? ????????:?base(Title,?Width,?Height,?Parent) ? ????{ ? ????????int?x=ClientRect.X,y=ClientRect.Y; ? ? ? ????????lblInput?=?new?YFLabel("0.",?x?+?5,?y?+?5,?ClientRect.Width?-?10,?20); ? ????????lblInput.TextAlign?=?TextAlignment.Right; ?????????Children.Add(lblInput);? ? ????????for?(int?i?=?0;?i?<?20;?i++) ? ????????{ ? ????????????if(i?%?5==0?&&?i!=0) ? ????????????{ ?????????????????x?=?ClientRect.X; ?????????????????y?=?y?+?32; ?????????????} ? ????????????button[i]?=?new?YFButton("",?x?+?5,?y?+?32,?32,?28); ? ????????????button[i].Text?=?strText[i]; ? ????????????button[i].MouseClick?+=?new?MouseInputEventHandler(button_MouseClick);? ? ????????????x?+=?37; ?????????????Children.Add(button[i]);? ?????????}??????????????? ?????} ? ????? ????void?button_MouseClick(object?sender,?MouseEventArgs?e) ? { ?} ?其實(shí)這段時(shí)間以來,我一直在研究MF,雖然目前它還不是很成熟,但是隨著研究的深入,越來越對(duì)它癡迷,越來越發(fā)現(xiàn)很多MF的寶藏(如果你有耐心的話,一定要看看MF底層框架的源碼(通過反編譯工具Reflector),你會(huì)發(fā)現(xiàn)很多很有意思的功能)。
MF相對(duì)于Windows XP/Vista、Windows CE而言,還只能算一個(gè)嬰孩,但就是這樣,就如一個(gè)偉人所說:孩子就是未來的希望。所以有理由相信MF的明天會(huì)更好
本文轉(zhuǎn)自yefanqiu51CTO博客,原文鏈接:http://blog.51cto.com/yfsoft/322900,如需轉(zhuǎn)載請(qǐng)自行聯(lián)系原作者
總結(jié)
以上是生活随笔為你收集整理的.Net Micro Framework研究—实现SideShow窗体界面的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。