详细步骤如下:
一.新建一个应用程序:File->New Applicaton 在Interface部分定义一个消息常量:const WM_NID=WM_USER+1000; 系统规定从WM_USER开始为用户自定义消息。
二.定义一个全局变量: NotifyIcon:TNotifyIconData,NotifyIcon是非常重要的一个变量,整个程序基本上是围着这个变量在转。TNotifyIconData是一个记录类型,按住Ctrl键,在TNotifyIconData 双击即进入ShellAPI.pas单元。(注:在Delphi中,这是一个非常好的对源代码进行分析的方法,源代码说明一切,你要想知道程序背后的内幕,最好的方法就是分析源代码!)此时出现了以下赋值语句:
TNotifyIconData = TNotifyIconDataA,这个意思很明显,就是说TNotifyIconData和TNotifyIconDataA是同种数据类型,接着往下看有:
TNotifyIconDataA = _NOTIFYICONDATAA,意思与刚才的一样,再往下看:
type
_NOTIFYICONDATAA = record
cbSize: DWORD;
Wnd: HWND;
uID: UINT;
uFlags: UINT;
uCallbackMessage: UINT;
hIcon: HICON;
szTip: array [0..63] of AnsiChar;
end;
这可真是“千呼万唤始出来,犹抱琵琶半遮面”。现在大家很清楚了,我们刚才定义的全局变量NotifyIcon其实是一个包含有7个成分的记录类型变量,就相当于C/C++中的结构体变量(C/C++的程序员应该是再熟悉不过了)。下面我们逐个来解释记录类型中的7个部分各有什么功能。
1> cbSize就是你定义的NotifyIcon变量的大小,用SizeOf(TNotifyIconData)可以取得,如果你是一个熟练的C/C++程序员,你应该不会陌生。在C/C++中,每当要为一个结构体变量分配内存的时候都要:通过 SizeOf(Struct type) 来获知存放一个这样的结构体变量要多少内存。
2> Wnd是一个句柄,你希望托盘程序产生的消息有哪个窗体来处理就让Wnd指向那个窗体。
例如:你准备在任务栏的托盘小图标上单击时窗体是窗体在“显示”和“隐藏”之间切换,则把Wnd指向主窗体。
3> uID:如果你要创建多个托盘小程序,那么怎么区分它们呢?就是靠这个ID号来区分。
3> uFlags是一个标志位,它表示当前所创建的托盘程序具有哪些性质:
NIF_ICON 表示当前所设置的图标(即hIcon的值)是有效的
NIF_MESSAGE 表示当前所设置的系统消息(即uCallBackMessage的值)是有效的
NIF_TIP 表示当前所设置的提示条(即szTip的值)是有效的。
4> uCallBackMessage这是7个部分里面最重要的一个。这里指定一个回调消息,也就是说这里定义一个消息名,当你单击或者右击托盘图标的时候就会向你在Wnd所指向的窗体发送一个在uCallBackMessage中定义的消息名,然后你在程序中定义一个消息出来函数来处理这个消息。这样就把Windows关于消息的整套流程都处理好了。
6> hIcon为托盘图标的句柄,根据这个句柄你就可以增加、修改、删除图标。
7> szTip就是当你的鼠标放到任务栏托盘的小图标上的时候弹出来的提示信息。
在这里我花了大量的笔墨介绍TNotifyIconData的内幕,把这部分搞清楚了,后面的东西就顺理成章了。
三. 双击主窗体,进入FormCreate的代码区域:
TForm1.FormCreate(Sender:TObject);
Begin
//NotifyIcon为全局变量,在程序的开头已经定义了
with NotifyIcon do
begin
cbSize:=SizeOf(TNotifyIconData);
Wnd:=Handle; //指向当前窗体Form1的句柄
uID:=1;
uFlags:=NIM_ICON or NIM_MESSAGE or NIM_TIP;
uCallBackMessage:=WM_NID;
hIcon:=Application.Icon.Handle;
szTip:=”张家恶少”;
end;.
//把设置好的变量NotifyIcon加入到系统中以便处理
Shell_NotifyIcon(NIM_ADD,@NotifyIcon);
End;
四.接下来就是定义一个消息处理函数:系统给窗体发来了一个消息,就由下面这个函数来处理。每个消息处理函数都是处理某一类消息的,大家仔细地看看下面函数体的定义和一般的函数定义有什么不一样:消息处理函数要在后面加上消息的名称,这样当系统发来WM_NID消息时,就是自动触发WMNID消息处理函数。
procedure WMNID(var msg:TMessage);message WM_NID;
begin
case msg.LParam of
WM_LBUTTONUp; Form1.Visible:=not Form1.Visible;
WM_RBUTTONUP: ShowMessage(‘您点击的是右键’);
End;
End;
好了,一个最简单的程序诞生了,大家自己设置好自己喜欢的图标.
Project->Options,选中Application页面,在Icon项中加载自己喜欢的图标,这样程序运行时,在任务栏里显示的就是你喜欢的图标了。当你单击图标时,窗体Form1会在可见与不可见之间切换,也就是说单击一下显示,再单击一下又隐藏。当你右击图标的时候会弹出一条消息:“你点击的是右键”。
五.最后要记住在关闭应用程序的时候要释放掉建立的托盘程序,否则会占用系统资源。
TForm1.FormDestroy(Sender:TObject);
Begin
Shell_NotifyIcon(NIM_DELETE,@NotifyIcon);
End;
http://www.xuedelphi.cn/wenzhang/yytg/2008/03/200803052086.htm
如何设置delphi程序托盘图标 2006-11-29 13:03
//单元接口部分引用 SHELLAPI 函数:
//以下注释为我自己添加上去的,如果有描述错误的地方还需要更正
unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, shellapi, Menus, StdCtrls;
constwi_iconeven = wm_user + 1000;//定义消息常量,用来接受系统返回的消息.
type TForm1 = class(TForm) PopupMenu1: TPopupMenu;//有"显示"."隐藏","关闭"三种选项 N1: TMenuItem; N2: TMenuItem; N3: TMenuItem; Label1: TLabel; Label2: TLabel; Label3: TLabel; procedure FormCreate(Sender: TObject); procedure N3Click(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure N1Click(Sender: TObject); procedure N2Click(Sender: TObject); procedure iconclick(var message : TMessage); message wi_iconeven; private { Private declarations } public { Public declarations } end;
var Form1: TForm1; nodedate : Tnotifyicondata;implementation
{$R *.dfm}
//程序运行即显示托盘图标:procedure TForm1.FormCreate(Sender: TObject);begin nodedate.cbSize := sizeof(tnotifyicondata); nodedate.Wnd := handle; nodedate.uID := 1; nodedate.uFlags := Nif_Icon or Nif_Message or Nif_Tip; nodedate.uCallbackMessage := wi_iconeven; nodedate.hIcon := application.Icon.Handle; nodedate.szTip := '托盘图标测试'; Shell_NotifyIcon(NIM_ADD,@nodedate); n1.Checked := true;end;
//"关闭" procedure TForm1.N3Click(Sender: TObject);begin Shell_NotifyIcon(NIM_DELETE,@nodedate); Application.Terminate;end;
procedure TForm1.FormDestroy(Sender: TObject);begin//释放内存 Shell_NotifyIcon(NIM_DELETE,@nodedate);end;
//点击'显示'
procedure TForm1.N1Click(Sender: TObject);begin n1.Checked := true; n2.Checked := false; ShowWindow(Application.Handle,SW_SHOW); ShowWindow(form1.Handle, SW_SHOW);end;
//"隐藏" 窗口procedure TForm1.N2Click(Sender: TObject);begin n1.Checked := false; n2.Checked := true; ShowWindow(Application.Handle, SW_HIDE); ShowWindow(form1.Handle, SW_HIDE);end;
//接受消息 procedure TForm1.iconclick(var message: TMessage);var P: Tpoint;begin if message.LParam = WM_RButtonUP then // 按下鼠标右键:
begin
SetForegroundWindow(From1.Handle); // 这句一定要加,否则弹出菜单不会自动隐藏
GetCursorPos(P);//获取鼠标坐标
PopupMenu1.Popup(P.x, P.y);//将 Popupmenu 与鼠标关联 end; if message.LParam = WM_LButtonUP then begin if form1.Showing then form1.Hide else if not form1.Showing then form1.Show; end;end;
end.
注 : 如果想讓你的托盤圖標可以在想更換的時候更換,可以通過一下方式修改. nodedate.hIcon := icon.Handle; Shell_NotifyIcon(NIM_MODIFY,@nodedate);
另:如何加載自定義的圖片? var icon : Ticon; ..... icon := Ticon.Create; icon.LoadFromFile(extractfilepath(application.ExeName) + '/icon1.ico');//加載本目錄下的ico文件;