C#內(nèi)存Graphics對(duì)象
Windos窗體有很多值得學(xué)習(xí)的地方,這里我們主要介紹C#內(nèi)存Graphics對(duì)象,包括介紹SetBackgroundBitmap函數(shù)。
想必大部分網(wǎng)友都使用過(guò)QQ、MSN等聊天程序,它們的界面都相當(dāng)華麗,尤其是當(dāng)網(wǎng)友上線以及消息提示時(shí)會(huì)有一個(gè)浮動(dòng)的窗體從屏幕的右下方緩慢升起,既美觀又人性化,作為程序員在享受的同時(shí)我們也不禁要問(wèn):這到底是怎么實(shí)現(xiàn)的呢?本文就利用C#內(nèi)存Graphics對(duì)象
SetBackgroundBitmap函數(shù)首先將窗體背景圖像保存到BackgroundBitmap變量中,然后根據(jù)該位圖圖像輪廓和透明色創(chuàng)建Region,BitmapToRegion就用于完成Bitmap到Region的轉(zhuǎn)換,程序再將這個(gè)Region付值給窗體的Region屬性以完成不規(guī)則窗體的創(chuàng)建。
- public void SetBackgroundBitmap(Image image, Color transparencyColor)
 - {
 - BackgroundBitmap = new Bitmap(image);
 - Width = BackgroundBitmap.Width;
 - Height = BackgroundBitmap.Height;
 - Region = BitmapToRegion(BackgroundBitmap, transparencyColor);
 - }
 - public Region BitmapToRegion(Bitmap bitmap, Color transparencyColor)
 - {
 - if (bitmap == null)
 - throw new ArgumentNullException("Bitmap", "Bitmap cannot be null!");
 - int height = bitmap.Height;
 - int width = bitmap.Width;
 - GraphicsPath path = new GraphicsPath();
 - for (int j = 0; j < height; j++)
 - for (int i = 0; i < width; i++)
 - {
 - if (bitmap.GetPixel(i, j) == transparencyColor)
 - continue;
 - int x0 = i;
 - while ((i < width) && (bitmap.GetPixel(i, j) != transparencyColor))
 - i++;
 - path.AddRectangle(new Rectangle(x0, j, i - x0, 1));
 - }
 - Region region = new Region(path);
 - path.Dispose();
 - return region;
 - }
 
通知窗體背景以及文字的繪制在重載的OnPaintBackground方法中完成,而且利用了雙重緩沖區(qū)技術(shù)來(lái)進(jìn)行繪制操作,代碼如下:
- protected override void OnPaintBackground(PaintEventArgs e)
 - {
 - Graphics grfx = e.Graphics;
 - grfx.PageUnit = GraphicsUnit.Pixel;
 - Graphics offScreenGraphics;
 - Bitmap offscreenBitmap;
 - offscreenBitmap = new Bitmap(BackgroundBitmap.Width, BackgroundBitmap.Height);
 - offScreenGraphics = Graphics.FromImage(offscreenBitmap);
 - if (BackgroundBitmap != null)
 - {
 - offScreenGraphics.DrawImage(BackgroundBitmap, 0, 0,
 
BackgroundBitmap.Width, BackgroundBitmap.Height);- }
 - DrawText(offScreenGraphics);
 - grfx.DrawImage(offscreenBitmap, 0, 0);
 - }
 
上述代碼首先返回窗體繪制表面的Graphics并保存在變量grfx中,然后創(chuàng)建一個(gè)C#內(nèi)存Graphics對(duì)象offScreenGraphics和內(nèi)存位圖對(duì)象offscreenBitmap,將內(nèi)存位圖對(duì)象的引用付值給offScreenGraphics,這樣所有對(duì)offScreenGraphics的繪制操作也都同時(shí)作用于offscreenBitmap,這時(shí)就將需要繪制到通知窗體表面的背景圖像BackgroundBitmap繪制到C#內(nèi)存Graphics對(duì)象上,DrawText函數(shù)根據(jù)需要顯示文字的大小和范圍調(diào)用Graphics.DrawString將文字顯示在窗體的特定區(qū)域。***,調(diào)用Graphics.DrawImage將內(nèi)存中已經(jīng)繪制完成的圖像顯示到通知窗體表面。
我們還需要捕獲窗體的鼠標(biāo)操作,有三個(gè)操作在這里進(jìn)行,
1、處理拖動(dòng)窗體操作
2、處理通知窗體的關(guān)閉操作
3、內(nèi)容區(qū)域的單擊操作。
三個(gè)操作都需要檢測(cè)鼠標(biāo)的當(dāng)前位置與每個(gè)Rectangle區(qū)域的包含關(guān)系,只要單擊落在特定區(qū)域我們就進(jìn)行相應(yīng)的處理,代碼如下:
- private void TaskbarForm_MouseDown(object sender, MouseEventArgs e)
 - {
 - if (e.Button == MouseButtons.Left)
 - {
 - if (TitlebarRectangle.Contains(e.Location)) //單擊標(biāo)題欄時(shí)拖動(dòng)
 - {
 - ReleaseCapture(); //釋放鼠標(biāo)捕捉
 - SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
 - //發(fā)送左鍵點(diǎn)擊的消息至該窗體(標(biāo)題欄)
 - }
 - if (CloseBtnRectangle.Contains(e.Location)) //單擊Close按鈕關(guān)閉
 - {
 - this.Hide();
 - currentTop = 1;
 - }
 - if (ContentRectangle.Contains(e.Location )) //單擊內(nèi)容區(qū)域
 - {
 - System.Diagnostics.Process.Start("http://www.Rithia.com");
 - }
 - }
 - }
 
該程序可以很好的進(jìn)行通知窗體的顯示、停留和隱藏操作,并且具備簡(jiǎn)單的換膚機(jī)制,在利用了雙重緩沖區(qū)繪圖技術(shù)后,可以保證窗體的繪制平滑且沒(méi)有閃爍。
【編輯推薦】















 
 
 
 
 
 
 