前言: 介面很重要,他是使用者對你的作品第一印象,雖然大家看慣了那方方正正,藍標題灰視窗的軟體介面,但是案頭上那炫彩的小視窗永遠讓使用者賞心悅目,從學習編程至今,一直都埋頭於各種內部的實現,直到有一天,感覺是有個蘋果砸了自己腦袋一下,我突然問自己,這些好看的介面是怎麼做的呢?於是,說幹就幹!然後,便開始了我的探索~
一 "Hellow window"
俗,這個名字確實俗,但是當我碰碰撞撞好不容易完成自己的第一份作品時,總是緊張的不知道說什麼好,所以先從"Hello"說起吧:)
windows是典型的也是最成功的視窗作業系統,他的靈魂是視窗,進入了windows與你互動的90%都是視窗,那麼我們先從視窗說起.先看下如下的例子:
這個一個背景透明,完全自繪的視窗.下面來分析下它:首先,視窗的外形是圓角矩形,並且上端兩個角弧度小,低端的兩個角弧度大.而正常的表單則是一個方方正正的矩形.其次,我們的表單是透明,在表單後面的東西並沒有被表單遮擋,從可以看出效果(為了示範透明效果,所以沒有截效果更好的純視窗圖).再次,標題列的顏色是硃紅色的,這可不是我修改windows Themes得到的結果,理由是視窗右上方三個標題列快捷按鈕的的排列,正常的是(按照從左至右的順序):最小化,最大化,關閉.而我們的則正好相反.最後還有些細節比如沒有邊框,表單顏色這些不屬於重畫的重點,就不細說了.
分析之後,就讓我們開始動手實驗吧(這也是你看本文的最直接的目的):
1.開啟你的編譯器,建立一個視窗工程;
2.工程自動建立後,讓你的表單(一般情況下是"Form1")獲得焦點,然後開啟屬性欄,找到視窗的"FormBoderStyle"屬性並設定為"None".此時你發現你的Form1變成了沒有邊框的視窗,em...視窗外形的問題解決了;
3.下面就要畫我們的視窗了,怎麼畫?大家知道windows是訊息驅動型的作業系統,任何事件都通過訊息來響應.視窗的繪製就要通過WM_PAINT訊息來響應,但是我們現在討論的是C#,是.net,我想要拋開那負責的MFC,訊息映射宏,甚至是對很多首先接觸.NET而不是native win32編程的人來說很陌生的WndProc.這個也好辦,我們的視窗事件列表裡,就有Paint這個事件,他對應的就是WM_PAINT訊息.在這個事件中,我們來畫我們的視窗.
添加如下代碼就搞定:
private void Form1_Paint(object sender, PaintEventArgs e) { e.Graphics.SmoothingMode = SmoothingMode.HighQuality; drawWndBody(e.Graphics); drawWndTitle(e.Graphics); } private void drawWndBody(Graphics grfx) { Rectangle clientRec = new Rectangle(0, 0, this.Size.Width, this.Size.Height); Brush bgbr1 = Brushes.Black; GraphicsPath wndShape = new GraphicsPath(); wndShape.StartFigure(); //left top wndShape.AddArc(0, 0, 10f, 10f, 180, 90); //topline wndShape.AddLine(new Point(0, 0), new Point(clientRec.Width, 0)); //right top wndShape.AddArc(clientRec.Width - 10, 0, 10f, 10f, 270, 90); //right line wndShape.AddLine(new Point(clientRec.Width, 0), new Point(clientRec.Width, clientRec.Height)); //right bottom wndShape.AddArc(clientRec.Width - 30, clientRec.Height - 30, 30f, 30f, 0, 90); //bottom line wndShape.AddLine(new Point(clientRec.Width, clientRec.Height), new Point(0, clientRec.Height)); //left bottom wndShape.AddArc(0, clientRec.Height - 30, 30f, 30f, 90, 90); //leftline wndShape.AddLine(new Point(0, clientRec.Height), new Point(0, 0)); wndShape.CloseAllFigures(); this.Region = new Region(wndShape); grfx.FillPath(bgbr1, wndShape); } private void drawWndTitle(Graphics grfx) { Rectangle titleRec = new Rectangle(0, 0, this.Size.Width, 20); Brush titleBr = Brushes.Brown; grfx.FillRectangle(titleBr, titleRec); //title info grfx.DrawString("Baesky UI 2010 Demo", this.Font, Brushes.White, new PointF(5f, 5f)); //close box drawCloseBox(grfx, Pens.White); //max box drawMaxBox(grfx, Pens.White); //min box drawMinBox(grfx, Pens.White); }
完了之後編譯運行,看看效果如何?!不是透明的表單?呵呵,試著在視窗初始化裡添加如下命令:
this.Opacity = 0.8;
再試試!