---- 實現原理
---- 任務欄狀態區的圖標添加、刪除、以及修改是通過Windows API函數Shell_NotifyIcon來實現的,該函數是由Windows的SHELL32.DLL動態聯接庫提供的。在Delphi中,Shell_NotifyIcon函數是在ShellAPI單元聲明的,其
---- 函數原型如下:
---- function Shell_NotifyIcon(dwMessage: DWORD; lpData: PNotifyIconData): BOOL; stdcall;
---- 其中參數dwMessage的取值決定函數Shell_NotifyIcon所要進行的操作的類型,它的取值可以是以下三者之壹:
---- NIM_ADD(值為0):在任務欄狀態區插入壹個圖標。
---- NIM_DELETE(值為1):從任務欄狀態區刪除壹個圖標。
---- NIM_MODIFY(值為2):修改任務欄狀態區的圖標、提示信息、或者通知消息。
---- 參數lpData 是壹個記錄類型(結構類型)的指針,記錄類型NotifyIconData的定義如下:
NOTIFYICONDATA = record
cbSize: DWORD;
Wnd: HWND;
uID: UINT;
uFlags: UINT;
uCallbackMessage: UINT;
hIcon: HICON;
szTip: array [0..63] of AnsiChar;
end;
---- cbSize:NOTIFYICONDATA記錄的大小。
---- Wnd:與此狀態區圖標相關聯的窗口句柄,此窗口將負責處理uCallbackMessage消息。
---- uID:程序自定義的狀態區圖標的標識符。
---- uFlags:這個字段指明NOTIFYICONDATA記錄中的成員uCallbackMessage、hIcon和szTip這三者的哪些項的值有效。它的取值可以是下列三者的組合(or運算):
---- NIF_MESSAGE (值為1):uCallbackMessage項包含了有效的信息。
---- NIF_ICON(值為2):hIcon項包含了有效的信息。
---- NIF_TIP(值為4): szTip項包含了有效的信息。
---- uCallbackMessage:程序定義的消息標識符(32位的整數)。當鼠標在狀態區圖標上移動或者點擊(即,發生了鼠標事件)時,操作系統將向Wnd指定的那個窗口發送uCallbackMessage消息。在uCallbackMessage消息中,lParam參數包含了Windows的鼠標消息的類型,而wParam參數則包含了圖標標識(即uID)。有效的鼠標消息包括以下幾個:WM_LBUTTONDOWN、WM_RBUTTONDOWN、WM_MBUTTONDOWN、WM_LBUTTONUP、WM_RBUTTONUP、WM_MBUTTONUP、WM_MOUSEMOVE、WM_LBUTTONDBLCLK、WM_RBUTTONDBLCLK以及WM_MBUTTONDBLCLK。
---- hIcon:指定壹個圖標句柄。
---- szTip:顯示在圖標上的提示信息(少於63個字符)。
---- Delphi中的實現
---- 通過上面的介紹中,我們不難看出,任務欄狀態區的編程主要是處理兩方面的工作:添加、刪除、修改圖標;以及處理通知消息。對於圖標的添加、刪除、修改操作,可以通過調用Shell_NotifyIcon函數來實現。而對於自定義的通知消息,我們就應該在消息循環中給予處理了。
---- 下面的示例給出了狀態區圖標的添加、修改和刪除操作的例子,以及圖標的通知消息的基本處理框架。
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics,
Controls, Forms, Dialogs, ExtCtrls, ShellAPI;
const
WM_TRAYNOTIFY=WM_USER+1;//定義通知消息
type
TForm1 = class(TForm)
Timer1: TTimer;
procedure FormCreate(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure WndProc(var Msg: TMessage); override;
end;
var
Form1: TForm1;
nd0, nd1:NotifyIconData;
hs:array[0..9]of LongWord;
implementation
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
begin
//加載Icon0..Icon9這10個圖標資源,
並且保存它們的句柄。
//圖標Icon0..Icon9分別對應與0..9這9個數字。
hs[0]:=LoadIcon(hInstance, 'Icon0');
hs[1]:=LoadIcon(hInstance, 'Icon1');
hs[2]:=LoadIcon(hInstance, 'Icon2');
hs[3]:=LoadIcon(hInstance, 'Icon3');
hs[4]:=LoadIcon(hInstance, 'Icon4');
hs[5]:=LoadIcon(hInstance, 'Icon5');
hs[6]:=LoadIcon(hInstance, 'Icon6');
hs[7]:=LoadIcon(hInstance, 'Icon7');
hs[8]:=LoadIcon(hInstance, 'Icon8');
hs[9]:=LoadIcon(hInstance, 'Icon9');
//填充NotifyIconData記錄型變量nd0
nd0.cbSize := sizeof(NotifyIconData);
nd0.Wnd := handle;
nd0.uID := 0;
nd0.uFlags := NIF_MESSAGE or NIF_ICON or NIF_TIP;
nd0.uCallbackMessage := WM_TRAYNOTIFY;
nd0.hIcon := hs[0];
StrPLCopy(nd0.szTip, 'Hello, World!', 63);
//填充NotifyIconData記錄型變量nd1
nd1.cbSize := sizeof(NotifyIconData);
nd1.Wnd := handle;
nd1.uID := 1;
nd1.uFlags := NIF_MESSAGE or NIF_ICON or NIF_TIP;
nd1.uCallbackMessage := WM_TRAYNOTIFY;
nd1.hIcon := hs[0];
StrPLCopy(nd1.szTip, 'Simon Loves Daisy', 63);
//在任務欄狀態區添加圖標
Shell_NotifyIcon(NIM_ADD, @nd0);
Shell_NotifyIcon(NIM_ADD, @nd1);
end;
procedure TForm1.Timer1Timer(Sender: TObject);
var
st:SystemTime;
begin
//每秒鐘更新壹次圖標:圖標0顯示秒數的十位,
圖標1顯示秒數的個位。
GetLocalTime(st);
nd0.hIcon := hs[st.wSecond div 10];
nd1.hIcon := hs[st.wSecond mod 10];
//修改任務欄狀態區的圖標
Shell_NotifyIcon(NIM_MODIFY, @nd0);
Shell_NotifyIcon(NIM_MODIFY, @nd1);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
//將圖標從任務欄狀態區刪除
Shell_NotifyIcon(NIM_DELETE, @nd0);
Shell_NotifyIcon(NIM_DELETE, @nd1);
end;
//處理 通知消息
procedure TForm1.WndProc(var Msg: TMessage);
var
IconID:integer;
pt:TPOINT;
begin
if msg.Msg = WM_TRAYNOTIFY then
begin
{
在通知消息中,wParam參數為圖標的uID,
lParam參數為鼠標事件的類型。
}
iconID := msg.WParam;
//獲取鼠標的在屏幕上的位置
GetCursorPos(pt);
//通知消息的處理的基本框架結構如下:
case msg.lParam of
WM_LBUTTONDOWN:
begin
//鼠標右鍵被按下
end;
WM_RBUTTONDOWN:
begin
//鼠標左鍵被按下
end;
WM_LBUTTONUP:
begin
//釋放鼠標左鍵
end;
WM_RBUTTONUP:
begin
//釋放鼠標右鍵
end;
WM_MOUSEMOVE:
begin
//鼠標在圖標上移動
end;
WM_LBUTTONDBLCLK:
begin
//鼠標左鍵雙擊
end;
WM_RBUTTONDBLCLK:
begin
//鼠標右鍵雙擊
end;
end; //end case
end
else//調用父類的WndProc方法處理其它消息
inherited;
end;
end.