一、 基础知识介绍:
NIData:TNotifyIconData,NIData是非常重要的一个变量,整个程序基本上是围着这个变量在转(uses ShellAPI)。
1>、 TNotifyIconData是一个记录类型(相对于结构体变量)。
// TNotifyIconData和TNotifyIconDataA, _NOTIFYICONDATAA是同种数据类型,
TNotifyIconData = TNotifyIconDataA,
TNotifyIconDataA = _NOTIFYICONDATAA,
type
_NOTIFYICONDATAA = record
cbSize: DWORD; // cbSizes是NIData变量的大小,用SizeOf(TNotifyIconData)可以取得;
Wnd: HWND; // Wnd是一个句柄,指向消息处理的窗体。
uID: UINT; // uID:创建多个托盘小程序时,考ID号来区分。
uFlags: UINT; // uFlags是一个标志位,它表示当前所创建的托盘程序具有哪些性质:
uCallbackMessage: UINT;
hIcon: HICON; // hIcon为托盘图标的句柄,根据句柄可以增加、修改、删除图标。
// szTip就是当你的鼠标放到任务栏托盘的小图标上的时候弹出来的提示信息。
szTip: array [0..63] of AnsiChar;
end;
2>、uFlags是一个标志位,它表示当前所创建的托盘程序具有哪些性质:
NIF_ICON 表示当前所设置的图标(即hIcon的值)是有效的
NIF_MESSAGE 表示当前所设置的系统消息(即uCallBackMessage的值)是有效的
NIF_TIP 表示当前所设置的提示条(即szTip的值)是有效的。
3>、uCallBackMessage这是7个部分里面最重要的一个。这里指定一个回调消息,也就是说
这里定义一个消息名,当你单击或者右击托盘图标的时候就 会向你在Wnd所指向的窗体发送一个在uCallBackMessage中定义的消息名,然后你在程序中定义一个消息出来函数来处理这个消息。这样就把 Windows关于消息的整套流程都处理好了。
二、创建系统托盘的具体步骤
1. 新建一个应用程序:
File->New Applicaton 在Interface部分(全局的)的uses之后,必须定义一个消息常量:const WM_TRAYICON =WM_USER+1000; windows消息规定从WM_USER开始为用户自定义消息。Project->Options,选中Application页面,在Icon项中加载自己喜欢的图标。
定义全局变量:// 如果不定义成全局变量,系统退出时,系统托盘处还是会显示图标。
var
NIData: TNotifyIconData;
2. 定义一个函数,用于操作系统托盘:
procedure TForm1.ModifyTrayIcon(Action: DWORD);//Action 为托盘的操作类型
begin
with NIData do
begin
cbSize := sizeof(TNotifyIconData);
UID := 0;
uFlags := NIF_MESSAGE or NIF_ICON or NIF_TIP;
Wnd := Handle; //指向当前窗体Form1的句柄
uCallBackMessage := WM_TRAYICON;// 对系统托盘区返回的信息进行处理的函数。
HICON := Application.Icon.Handle;// 托盘的图标
StrPCopy(szTip, Application.Title); // 托盘的提升信息
end;
//把设置好的变量NotifyIcon按传入的操作类型进行处理
Shell_NotifyIcon(Action, @NIData);
end;
3. 定义一个消息处理函数
系统给窗体发来了一个消息,就由下面这个函数来处理,每个消息处理函数都是处
理某一类消息的,消息处理函数要在后面加上消息的名称,这样当系统发来WM_TRAYICON
消息时,就是自动触发WM_TRAYICON消息处理函数(Delphi 消息处理技术)。
声明:procedure WMTrayIcon(var message: TMessage); message WM_TRAYICON;
实现:procedure TForm1.WMTrayIcon(var message: TMessage);
var
MousePos: TPoint;
Begin
//判断是否是右击事件,是就显示右击菜单栏
if message.LPARAM = WM_RBUTTONDOWN then
begin
SetActiveWindow(Handle); //该函数激活一个窗口。
GetCursorPos(MousePos);
PopupMenu.Popup(MousePos.X, MousePos.Y); //显示右击菜单栏 PopupMenu 右击菜单的名字
end;
end;
4. 建立托盘程序,进入FormCreate的代码区域:
procedure TForm1.FormCreate(Sender: TObject);
begin
ModifyTrayIcon(NIM_ADD);
end;
5. 释放托盘程序,在FormClose的代码区域,否则会占用系统资源。
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
ModifyTrayIcon(NIM_DELETE);
end;
6. 全部代码
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ShellAPI, Menus, StdCtrls;
const
WM_TRAYICON = WM_APP + 0;
type
TForm1 = class(TForm)
PopupMenu: TPopupMenu;
Hello1: TMenuItem;
Exit1: TMenuItem;
N1: TMenuItem;
There1: TMenuItem;
Label1: TLabel;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormCreate(Sender: TObject);
procedure Exit1Click(Sender: TObject);
private
procedure WMTrayIcon(var message: TMessage); message WM_TRAYICON;
procedure ModifyTrayIcon(Action: DWORD);
public
end;
var
Form1: TForm1;
NIData: TNotifyIconData;
implementation
{$R *.DFM}
procedure TForm1.ModifyTrayIcon(Action: DWORD);
begin
with NIData do
begin
cbSize := sizeof(TNotifyIconData);
uFlags := NIF_MESSAGE or NIF_ICON or NIF_TIP;
Wnd := Handle;
uCallBackMessage := WM_TRAYICON;
HICON := Application.Icon.Handle;
StrPCopy(szTip, Application.Title);
end;
Shell_NotifyIcon(Action, @NIData);
end;
procedure TForm1.WMTrayIcon(var message: TMessage);
var
MousePos: TPoint;
begin
if message.LPARAM = WM_RBUTTONDOWN then
begin
SetActiveWindow(Handle);
GetCursorPos(MousePos);
PopupMenu.Popup(MousePos.X, MousePos.Y);
end;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
ModifyTrayIcon(NIM_DELETE);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
ModifyTrayIcon(NIM_ADD);
end;
procedure TForm1.Exit1Click(Sender: TObject);
begin
Close;
end;
end.