现在很多的应用程序都有这样一种功能,当用户选择最小化窗口时,窗口不是象平常那样最小化到任务栏上,而是“最小化”成一个任务栏图标。象 FoxMail 3.0 NetVampire 3.0等都提供了这样的功能。实现这样的功能实际上并不复杂,在窗口最小化时,窗口会发出WM_SYSCOMMAND消息,你只要需要截取Windows 的WM_SYSCOMMAND消息,在窗口最小化时隐藏窗口并调用WindowsAPI函数Shell_NotifyIcon将定义的图标添加到任务栏 上,Shell_NotifyIcon的函数定义是这样的:function Shell_NotifyIcon(dwMessage:DWORD; lpData: PNotifyIconData): BOOL; stdcall; 其中的参数dwMessage指定Shell_NotifyIcon函数的操作,可以是NIM_ADD NIM_DELETE NIM_MODIFY三个值中的一个,分别对应添加图标、删除图标、修改图标的动作。
---- 参数lpData指向的PNotifyIconData结构的定义如下:
_NOTIFYICONDATAW = record
cbSize: DWORD;
Wnd: HWND;
uID: UINT;
uFlags: UINT;
uCallbackMessage: UINT;
hIcon: HICON;
szTip: array [0..63] of WideChar;
end;
TNotifyIconData = _NOTIFYICONDATAW;
---- 在这个结构中Wnd指明所属的窗口,UCallbackMessage指明回调消息,如果指明了Wnd和 uCallbackMessage,则当用户对任务栏图标有动作(如点击图标,在图标上移动光标等)。系统都会发送uCallbackMessage消息 给Wnd指定的窗口。hIcon是要添加的图标的句柄,szTip 是图标的提示行(就是当移动光标到图标上,出现的一个小黄方框内出现的文字)。消息。实现上面的功能,最主要的是要处理WM_SYSCOMMAND消息和 自定义的图标消息,这些消息在Delphi中并没有相应的事件。这里就需要使用到Delphi的自定义消息处理功能来截取并处理这些消息。
---- 首先看下面的程序。在执行程序之前,首先要改变Form1的Icon属性,给Form1装入一个图标,否则在任务栏上会出现一块空白。
代码如下:
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,ShellAPI;
const
WM_BARICON=WM_USER+200;
type
TMinFrm = class(TForm)
private
{ Private declarations }
//在窗口最小化时,窗口会发出WM_SYSCOMMAND消息
// 最主要的是要处理WM_SYSCOMMAND消息和 自定义的图标消息,
// 这些消息在Delphi中并没有相应的事件。这里就需要使用到Delphi的自定义消息处理功能来截取并处理这些消息
procedure WMSysCommand(var message:TMessage);message WM_SYSCOMMAND;
procedure WMBarIcon(var message:TMessage);message WM_BARICON;
public
{ Public declarations }
end;
var
MinFrm: TMinFrm;
implementation
{$R *.dfm}
{ TForm10 }
procedure TMinFrm.WMBarIcon(var message: TMessage);
var
lpData:PNotifyIconData;
begin
if (Message.LParam = WM_LBUTTONDOWN) then
begin
//如果用户点击任务栏图标则将图标删除并回复窗口。
lpData := new(PNotifyIconDataA);
lpData.cbSize := 88;//SizeOf(PNotifyIconDataA);
lpData.Wnd := MinFrm.Handle;
lpData.hIcon := MinFrm.Icon.Handle;
//UCallbackMessage指明回调消息,如果指明了Wnd和 uCallbackMessage,
//则当用户对任务栏图标有动作(如点击图标,在图标上移动光标等)。
//系统都会发送uCallbackMessage消息 给Wnd指定的窗口
lpData.uCallbackMessage := WM_BARICON;
lpData.uID :=0;
lpData.szTip := 'Samples';
lpData.uFlags := NIF_ICON or NIF_MESSAGE or NIF_TIP;
Shell_NotifyIcon(NIM_DELETE,lpData);
dispose(lpData);
MinFrm.Visible := True;
end;
end;
procedure TMinFrm.WMSysCommand(var message: TMessage);
var
lpData:PNOtifyIconData; //结构体 Wnd指明所属的窗口
begin
if message.WParam=SC_ICON then //系统的 SC_ICON
begin
//如果用户最小化窗口则将窗口 隐藏并在任务栏上添加图标
lpData:=New(pnotifyicondataA);
lpData.cbSize := 88;
//SizeOf(PNotifyIconDataA);
lpData.Wnd := MinFrm.Handle; //当前窗口句柄
lpData.hIcon := MinFrm.Icon.Handle;
lpData.uCallbackMessage := WM_BARICON; // 回调消息
lpData.uID :=0;
lpData.szTip := 'Samples';
lpData.uFlags := NIF_ICON
or NIF_MESSAGE or NIF_TIP;
// function Shell_NotifyIcon(dwMessage:DWORD; lpData: PNotifyIconData): BOOL; stdcall;
//其中的参数dwMessage指定Shell_NotifyIcon函数的操作,可以是NIM_ADD NIM_DELETE NIM_MODIFY
//三个值中的一个,分别对应添加图标、删除图标、修改图标的动作。
Shell_NotifyIcon(NIM_ADD,lpData);
dispose(lpData);
MinFrm.Visible := False; //隐藏窗体
end else
begin
//如果是其它的SystemCommand 消息则调用系统缺省处理函数处理之。
DefWindowProc(MinFrm.Handle,Message.
Msg,Message.WParam,Message.LParam);
end;
end;
end.