利用Visual C++實現系統托盤程序

自從微軟公司推出Windows 95操作系統以來,系統托盤應用作爲一種極具吸引力的用戶界面設計深受廣大用戶的喜愛。使用系統托盤作爲用戶界面的Windows應用程序數不勝數,比如"金山詞霸"、"Winamp"、"RealPlayer"等等。

這些程序運行時不顯示運行窗口,只在任務欄上顯示一個圖標,表示程序正在運行,用戶可以通過鼠標與應用程序交互,程序開發人員有時也需要編制一些僅在後臺運行的類似程序,爲了不干擾前臺程序的運行界面和不顯示不必要的窗口,應使程序運行時的主窗口不可見。同時將一個圖標顯示在任務欄右端靜態通告區中並響應用戶的鼠標動作。本實例就介紹Visual C++開發這類程序的設計方法,該程序編譯運行後,如果雙擊托盤圖標,程序會彈出一個消息列表窗口,只要鼠標在托盤圖標上移動或點擊(無論是左右鍵的單擊或雙擊),產生的消息都會顯示在這個窗口裏;當鼠標光標移到托盤圖標上時,在圖標附近會顯示提示信息;單擊右鍵時彈出上下文菜單,這個菜單中應包含打開屬性頁的命令或者打開與圖標相關的其它窗口的命令,另外,該程序還可以動態的改變托盤的圖標。參照這個例子,相信讀者能輕鬆自如地在自己的程序中應用系統托盤。

一、實現方法

爲了實現拖盤程序,首先要使程序的主窗口不可見,這點實現起來十分容易,只要調用ShowWindow(SW_HIDE)就可以了,本實例採用的就是這種方法,還有一種思路是通過分別設置主邊框窗口的風格和擴展風格來隱藏主框架:

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
cs.style =WS_POPUP;//使主窗口不可見;
cs.dwExStyle =WS_EX_TOOLWINDOW;//不顯示任務按鈕;
return CFrameWnd::PreCreateWindow(cs);

 在任務條上顯示圖標是利用系統API函數Shell_NotifyIcon()來將一個圖標顯示在任務欄的通告區中。該函數的原型爲:

BOOL Shell_NotifyIcon(DWORD dwMessage, PNOTIFYICONDATA pnid);

該函數的第一個參數dwMessage類型爲DWORD,表示要進行的動作,它可以是下面的值之一:

NIM_ADD: 添加一個圖標到任務欄。

NIM_MODIFY: 修改狀態欄區域的圖標。

NIM_DELETE: 刪除狀態欄區域的圖標。

NIM_SETFOCUS: 將焦點返回到任務欄通知區域。當完成用戶界面操作時,任務欄圖標必須用此消息。例如,如果任務欄圖標正顯示上下文菜單,但用戶按下"ESCAPE"鍵取消操作,這時就必須用此消息將焦點返回到任務欄通知區域。

NIM_SETVERSION:指示任務欄按照相應的動態庫版本工作。

第二個參數pnid是NOTIFYICONDATA結構的地址,其內容視dwMessage的值而定。這個結構在SHELLAPI.H文件中定義如下:

typedef struct _NOTIFYICONDATA {
DWORD cbSize; // 結構大小(sizeof struct),必須設置
HWND hWnd; // 發送通知消息的窗口句柄
UINT uID; // 圖標ID ( 由回調函數的WPARAM 指定)
UINT uFlags;
UINT uCallbackMessage; // 消息被髮送到此窗口過程
HICON hIcon; // 任務欄圖標句柄
CHAR szTip[64]; // 提示文本
} NOTIFYICONDATA;  

該結構中uFlags的值分別爲:

#define NIF_MESSAGE 0x1 // 表示uCallbackMessage 有效
#define NIF_ICON 0x2 // 表示hIcon 有效
#define NIF_TIP 0x4 // 表示szTip 有效 

       在該結構的成員中,cbSize爲該結構所佔的字節數,hWnd爲接受該圖標所發出的消息的窗口的句柄(鼠標在任務欄上程序圖標上動作時圖標將發出消息,這個消息用戶要自己定義),uID爲被顯示圖標的ID,uFlags指明其餘的幾個成員(hIcon、uCallBackMessage和szTip)的值是否有效,uCallbackMessage爲一個用戶自定義的消息,當用戶在該圖標上作用一些鼠標動作時,圖標將嚮應用程序的主框架窗口(hWnd成員中指定的窗口)發出該消息,爲了使程序的主框架得到該通知消息,需要設置NOTIFYICONDATA 結構的flag成員的值爲NIF_MESSAGE。hIcon爲將在任務欄上顯示的圖標句柄,szTip鼠標停留在該圖標上時顯示的提示字符串。

 

儘管Shell_NotifyIcon函數簡單實用,但它畢竟是個Win32 API,爲此本實例將它封裝在了一個C++類中,這個類叫做CTrayIcon,有了它,托盤編程會更加輕鬆自如,因爲它隱藏了NOTIFYICONDATA、消息代碼、標誌以及一些繁瑣的細節。

 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章