程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 利用Visual C#實現任務欄通知窗口(2)

利用Visual C#實現任務欄通知窗口(2)

編輯:關於C語言

背景知識

通知窗口就是將一般的窗體附加上一層皮膚,這裡所謂的皮膚就是一張位圖圖片,該位圖圖片通過窗體的OnPaintbackground事件被繪制到窗體表面,在附加位圖之前需要調整窗體的可視屬性,由於繪制操作是針對於窗體客戶區域的,所謂客戶區域就是指窗體標題欄下方以及窗體邊框以內的所有區域,所以需要將窗體的邊框和外觀屬性 FormBorderStyle調整為:None,這樣所繪制的圖像就會填充整個窗體。

首先,我們會用到Region對象,Region對象可以精確的描繪出任意形狀的輪廓范圍,通過一個位圖圖像創建Region對象後再將其傳遞給窗體的Region屬性就可以使窗體按照Region所定義的輪廓顯示出來。作為皮膚使用的位圖文件可以通過任何圖像編輯軟件諸如:Photeshop來創建和編輯,只是注意一點,需要將圖片的背景色調成特定顏色以便程序繪制時將其清除,我們在這裡使用的背景色為粉紅色。為了能夠讓Region對象按照圖像中感興趣的內容邊框來創建窗體,我們還需要使用GraphicsPath類將圖像輪廓按照一定路徑標注下來,稍後便按照該路徑創建Region對象。

然後通過窗體的繪圖事件將位圖的內容顯示在窗體表面,我們沒有直接使用OnPaintbackground事件而是重載了該方法,這樣做的好處就是一些低層的繪制操作還繼續交由.Net框架運行時來處理,我們只考慮實際需要的繪制操作即可。在OnPaintbackground方法中我們啟用了雙重緩沖區繪圖技術,所謂該技術就是指先在內存中的一塊畫布上把將要顯示的圖像顯示出來或進行處理,等到操作完成再將該畫布上所顯示的圖像放置到窗體表面,這樣的機制可以非常有效的降低閃爍的出現,使圖像顯示更加平滑。通知窗體從屏幕的右下方進行升起停留一段時間後再慢慢回落,這裡需要用到返回屏幕區域的大小范圍的.Net框架方法 Screen.GetWorkingArea(WorkAreaRectangle),通過一定算法計算出通知窗體顯示前的初始位置。最後,我們將要顯示的文本按照一定格式和Rectangle對象所指定的區域范圍繪制到窗體表面。通知窗體的關閉操作是通過設定一個區域,當用戶用鼠標單擊時檢測單擊坐標是否在該區域內,若在區域內就可以執行隱藏通知窗體的代碼。

我們注意了,當QQ和MSN的通知窗口顯示時其主窗體的焦點沒有丟失,也就是說程序沒有將自身的焦點轉移到顯示的通知窗體上。經過測試,我們無論怎麼樣調用.Net框架提供的窗體顯示例程譬如:Form.Show都無法保證主窗體的焦點不丟失,在VC環境下我們可以使用Win32API的ShowWindows函數來完成復雜的窗體顯示操作,但是.Net框架根本沒有提供類似的方法,那麼我們能否通過.Net框架調用該API函數來顯示窗體呢?幸好.Net框架提供了P/Invoke平台調用,利用平台調用這種服務,托管代碼就可以調用在動態鏈接庫中實現的非托管函數,並可以封送其參數,我們可以輕松的顯示但不獲得焦點的窗體。程序中用到的Windows API以及常量的定義都保存在WinUser.h頭文件中,其對應的動態鏈接庫文件就是user32.dll,使用.Net框架提供的DllImportAttribute類對導入的函數進行定義,然後就可以非常方便的在程序中調用該函數了。

由於我們將通知窗體的標題欄隱藏了,所以對窗體拖動操作還需要我們自己動手進行處理。本文介紹了如何更加高效的進行拖動窗體操作,有些網友在對於非標題欄拖動窗體編程時偏向組合使用鼠標事件來進行,這樣做的本質沒有任何不妥,但是頻繁的事件響應和處理反而使程序性能有所降低。我們將繼續使用Win32API的底層處理方法來解決該問題,就是向窗體發送標題欄被單擊的消息,模擬實際的拖動操作。

我們會通過2個計時器來完成窗體的顯示、停留和隱藏,通過設置速度變量可以改變窗口顯示和隱藏的速度。

程序實現

啟動Visual Studio .Net 2005,創建C# Windows 窗體應用程序,將解決方案命名為TaskbarForm,包含的項目名也為TaskbarForm,首先創建程序的主窗體Form1,在上面添加兩個Button控件,一個用於顯示通知窗體,另一個則終止程序。然後在解決方案管理器中右擊項目,單擊"添加 - Windows 窗體",我們把新創建的窗體命名為TaskbarForm。

在類TaskbarForm定義的下方,我們創建用於顯示的字符串和其顏色的變量,再定義幾個Rectangle對象的變量用於放置標題、提示內容以及可以拖動窗體的區域和關閉按鈕的區域。然後,我們需要保存窗體在浮動時的高度以便計算移動後的新高度,intervalValue變量用來確定窗體顯示和隱藏的速度。進行平台調用時我們需要提前定義好常量的值用來傳遞給函數,WM_NCLBUTTONDOWN和HT_CAPTION常量用於拖動窗體,他們的值都保存在WinUser.h頭文件中,所對應的動態鏈接庫名為:user32.dll。我們用到的Win32API為:SendMessage、ReleaseCapture和ShowWindow,通過使用DllImportAttribute可以導入相應的函數並在程序中重新進行定義,如下:

[DllImportAttribute("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
//發送消息//winuser.h 中有函數原型定義
[DllImportAttribute("user32.dll")]
public static extern bool ReleaseCapture(); //釋放鼠標捕捉winuser.h
[DllImportAttribute("user32.dll")] //winuser.h
private static extern Boolean ShowWindow(IntPtr hWnd, Int32 nCmdShow);

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved