|
技術文章 > 編程 > 技術 > Windows API > 視窗編程:SysTray圖示應用
|
視窗編程:SysTray圖示應用
|
|
撰/ahliu
1. 甚麼是SysTray(System Tray)圖示?
SysTray圖示就是Windows工作列的最右方所看到的小圖示,是
為了讓程式能在背景執行時,使用者仍能透過圖像介面來檢視及控制程式。例如ICQ、防毒軟件、音量控制等,都是背景執行程式,在大部份時間內都不需要人手
操作,使用者需要執行該程式的某功能時,便能從SysTray中把它點擊還原至視窗模式。 在視窗編程的角度來看,SysTray圖示是
NotifyIcon
component(提示圖示元件)的一部份,為了讓背景程式能有效地與使用者溝通,整個元件除圖示外,還包括選單(Menu)、工具列
(Toolbar)、工具提示(ToolTip)、回傳訊息處理(Callback message handler)等等。
2. 基本SysTray結構
SysTray
是屬於視窗作業系統的Shell控制元件(i.e. 使用Shell
API),所有關於SysTray圖示的操作,都會發出工作列狀態區域(Taskbar status
area,即右下角載有圖示的區域)的訊息,而這類訊息包含的所有資料,都由NOTIFYICONDATA這個數據結構封裝起來:
typedef struct _NOTIFYICONDATA { DWORD cbSize; HWND hWnd; UINT uID; UINT uFlags; UINT uCallbackMessage; HICON hIcon; TCHAR szTip[64]; DWORD dwState; DWORD dwStateMask; TCHAR szInfo[256]; union { UINT uTimeout; UINT uVersion; }; TCHAR szInfoTitle[64]; DWORD dwInfoFlags; GUID guidItem; } NOTIFYICONDATA, *PNOTIFYICONDATA;
NOTIFYICONDATA內的各項說明,請參閱http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/structures/notifyicondata.asp
3. SysTray圖示應用實例
要使用NOTIFYICONDATA,必須要在程式碼加入shellapi.h #include <shellapi.h> 以下是一程式例子: #include <windows.h>
#include <shellapi.h>
#include <tchar.h>
#include "resource.h"
#define SYSTRAY_ICON_UID 1001
#define WM_SYSTRAYNOTIFY WM_USER + 1
/* Global variables */
NOTIFYICONDATA NotifyIconData;
HICON IconHandle;
/* Global function declaration */
BOOL CALLBACK MainDialogProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam);
/* Function definition */
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) {
IconHandle = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));
DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, (DLGPROC) MainDialogProc);
return 0;
}
BOOL CALLBACK MainDialogProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam) {
switch (Msg) {
case WM_INITDIALOG:
/* Filling in NOTIFYICONDATA */
memset(&NotifyIconData, 0, sizeof(NOTIFYICONDATA));
NotifyIconData.cbSize = sizeof(NOTIFYICONDATA);
NotifyIconData.hWnd = hDlg;
NotifyIconData.uID = SYSTRAY_ICON_UID;
NotifyIconData.hIcon = IconHandle;
NotifyIconData.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
NotifyIconData.uCallbackMessage = WM_SYSTRAYNOTIFY;
_tcscpy(NotifyIconData.szTip, _T("Windows API - SysTray Icon
Tutorial"));
return TRUE;
case WM_SYSTRAYNOTIFY:
NotifyIconData.hWnd = hDlg;
NotifyIconData.uID = SYSTRAY_ICON_UID;
Shell_NotifyIcon(NIM_DELETE, &NotifyIconData);
ShowWindow(hDlg, SW_SHOW);
break;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case WM_DESTROY:
EndDialog(hDlg, 0);
return TRUE;
case ID_SYSTRAY:
/* Call Shell_NotifyIcon to
submit SysTray message */
Shell_NotifyIcon(NIM_ADD,
&NotifyIconData);
/* Hide the main window */
ShowWindow(hDlg, SW_HIDE);
break;
}
}
return FALSE;
}
你必須要加入#include <windows.h>和#include <shellapi.h>,<tchar.h>是為了宣告_tcscpy和_T,若不使用_tcscpy和_T話,則可以省略。 該程式是一Dialog-based應用程序,於WinMain內呼叫程式資源中的IDD_DIALOG1作為主程式版面,在初始化對話盒時(i.e. 發出WM_INITDIALOG訊息),我們填上NOTIFYICONDATA內的資料,最重要的資料包括 hWnd:指定該SysTray圖示的主屬視窗程式
uID:若一程式有多個SysTray圖示時,用來分辨多個圖示
hIcon:圖示的Handle,用來繪製圖示
uCallbackMessage:當滑鼠經過SysTray圖示時所發出的訊息 圖示的Handle可由LoadIcon( )函數獲取,詳情請參閱http://itzone.hk/article/article.php?aid=200406210255103136及http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/resources/icons/iconreference/iconfunctions/loadicon.asp 而uCallbackMessage則是使用者定義的訊息代碼,在該程式中為: #define WM_SYSTRAYNOTIFY WM_USER + 1 其中WM_USER(即0x0400)及以後的數字,均為使用者定義訊息代碼。 當NOTIFYICONDATA
內所有資料都填好後,便可以方進Shell_NotifyIcon(DWORD msg, NOTIFYICONDATA*
nid)裡,其中「msg」的值若是「NIM_ADD」的話,則表示你想把圖示新增至SysTray中;若為「NIM_DELETE」的話,表示你想在
SysTray中,移除屬於該程式的圖示。 呼叫Shell_NotifyIcon( )時並不會把原本的視窗隱藏,你需要自行呼叫ShowWindow( )來隱藏或還原程式視窗。
4. 使用提示
本程式的按鈕會讓程式視窗隱藏起來,並即時設置SysTray圖示,當使用者把滑鼠放上該SysTray圖示時,便會把視窗還原,並且刪除SysTray中的圖示。 當
使用者把滑鼠放上圖示時,WM_SYSTRAYNOTIFY(是一個使用者定義的訊息,其名字可以隨意更改)便會被發出,當時滑鼠的訊息(如
WM_LBUTTONUP、WM_RBUTTONDOWN等等)也會一併送出,並記錄在「lParam」中,而該圖示的uID也會記錄在「wParam」
中,程式員可利用「lParam」及「wParam」作更仔細的SysTray圖示處理,例如功能選單。
5. 後記
根據MSDN(Microsoft Developer Network) Library所提及: The taskbar notification area is sometimes erroneously called the "tray." 因此「SysTray」的正確名稱為「Taskbar Notification Area」
相關文件:
- Demo Program
發表日期:2005-06-21
|
|
|
< 回到分類選單
> 回應此文章
| |