Delphi托盘编程实战演练

很多人认为 Delphi 是一个 RAD 工具,包括我本人在上学的时候对 Delphi 也有偏见,现在走出了“象牙塔”,涉及的面广了,遇到的问题多了,慢慢地也有了自己的一点心得体会。其实 ,Delphi 是基于 Object Pascal 语言的开发工具,也就是说 Delphi 本质上是一种语言工具,并且是真正的面向对象的。下面我举的例子就是用 Delphi 实现的一个托盘小程序。程序短小精悍,脉络分明,我将对关键部分进行详细讲解。就象候俊杰先生把 MFC 一层一层地剥开一样,今天我也来一次“庖丁解牛”。

在 Delphi 中涉及到系统编程的方面毫无例外都要调用 API 函数,在 ShellAPI.pas 单元中有要用到的 API 函数的原型。

实战演练:

一.新建一个应用程序: 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;

毕业快半年了,很多东西在学校总理解不了,认识不够深刻;出到社会,接触了不少道中朋友,受益非浅,每有心得体会,总想写成文字,一来总结自己学的东西,二来和大家共同交流。

E_Mail: [email protected] QQ: 8133413 张家恶少

Published At
Categories with Web编程
Tagged with
comments powered by Disqus