在我们平常设计项目时通常把一些常驻内存或使用频率比较高的程序做成托盘的形式,一来能使程序外观得到整洁性,二来能使程序更具专业性。 在设计任务栏中的托盘程序时主要用到了一个WIN API函数Shell_NotifyIcon,大部分功能的实现都是在此函数基础上来实现的,该函数的原型如下: WINSHELLAPI BOOL WINAPI Shell_NotifyIcon( DWORD dwMessage, // message identifier PNOTIFYICONDATA pnid // pointer to structure ); 通过看到参数我们知道要传递一个dwMessage消息参数的标识类型和一个指向具体修改信息的结构pnid,第一个参数的具体取值如下: dwMessage Identifier of the message to send. This parameter can be one of these values: NIM_ADD Adds an icon to the status area.{添加图标} NIM_DELETE Deletes an icon from the status area.{删除图标} NIM_MODIFY Modifies an icon in the status area. {修改图标} 即为添加一个图标,删除一个图标和修改一个图标在任务栏的右部区域中。可以通过第一个参数的内容来定制对任务栏状态区的操作,第二个参数的具体取值如下: pnid Pointer to a NOTIFYICONDATA structure. The content of the structure depends on the value of dwMessage. 此参数为一个指向NOTIFYICONDATA结构的指针,通过这个结构来对设计者想要的操作进行定义,结构成员定义如下: typedef struct _NOTIFYICONDATA { // nid DWORD cbSize; {结构的大小} HWND hWnd; {关联状态区图标的窗口句柄,用来处理回调函数} UINT uID; {应用程序定义的状态区图标的标识符} UINT uFlags; {此成员表明NOTIFYICONDATA记录中的成员uCallbackMessage、hIcon和szTip这三者的哪些项的值有效} UINT uCallbackMessage; {程序定义的消息标识符,例如当鼠标在状态区图标上移动或者左右点击所发生的事情时,操作系统将向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 hIcon; {指定一个应用程序定义的图标的句柄} char szTip[64];{在图标上显示的提示信息} } NOTIFYICONDATA, *PNOTIFYICONDATA; 通过前面对Shell_NotifyIcon函数的基本认识,我们知道了具体的操作有添加,删除和修改图标,下面我们以一个实例来具体的去实现托盘程序的效果。 新建一个工程,然后放入ApplicationEvents1控件,在additional控件面板中,本例程带有弹出菜单功能。 代码如下: unit Unit1; interfaceuses Windows,shellapi, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,AppEvnts, ImgList, Menus; {一定要uses shellapi单元} const ghy_tray=wm_user+2; type TForm1 = class(TForm) ImageList1: TImageList; ApplicationEvents1: TApplicationEvents; PopupMenu1: TPopupMenu; N1: TMenuItem; N2: TMenuItem; N3: TMenuItem; procedure ApplicationEvents1Minimize(Sender: TObject); procedure ApplicationEvents1Restore(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure N1Click(Sender: TObject); procedure N2Click(Sender: TObject); procedure N3Click(Sender: TObject); procedure FormCreate(Sender: TObject); private procedure WMSysCommand(var msg: TMessage);message wm_syscommand; { Private declarations } public procedure mytray(var Msg: TMessage); message ghy_tray; { Public declarations } end;var Form1: TForm1; tray1,tray2:TNotifyIconData; ico1,ico2:ticon; tags:boolean; implementation{$R *.DFM} procedure Tform1.WMSysCommand(var msg: TMessage); begin if msg.WParam = SC_MINIMIZE then begin showwindow(application.handle,sw_hide); inherited; end else inherited; end;procedure tform1.mytray(var Msg: TMessage); var pt:tpoint; begin GetCursorPos(pt);case msg.lParam of WM_LBUTTONDOWN: begin //鼠标左键被按下 if tags=true then begin application.Minimize; form1.Hide; end else begin application.Restore; end; end;WM_LBUTTONUP: begin //释放鼠标左键 end; wm_rbuttondown: begin //鼠标右键被按下 SetForegroundWindow(Form1.Handle); form1.PopupMenu1.Popup(pt.x,pt.y); end else//调用父类的WndProc方法处理其它消息 inherited; end; end;procedure TForm1.ApplicationEvents1Minimize(Sender: TObject); begin tags:=false; ShowWindow(Application.Handle,SW_HIDE); tray2.cbSize:=sizeof(tray2); tray2.Wnd:=form1.Handle; tray2.uID:=0; tray2.uFlags:=NIF_ICON or NIF_TIP or NIF_MESSAGE; tray2.uCallbackMessage:=ghy_tray; tray2.hIcon:=ico2.Handle; tray2.szTip:='我的托盘程序'; if not Shell_NotifyIcon(NIM_modify,@tray2) then begin ShowMessage('no'); end; end;procedure TForm1.ApplicationEvents1Restore(Sender: TObject); begin tags:=true; form1.show;ico1:=ticon.Create; ico2:=ticon.create; imagelist1.GetIcon(0,ico1); imagelist1.geticon(1,ico2); tray1.cbSize:=sizeof(tray1); tray1.Wnd:=form1.Handle; tray1.uID:=0; tray1.uFlags:=NIF_ICON or NIF_TIP or NIF_MESSAGE; tray1.uCallbackMessage:=ghy_tray; tray1.hIcon:=ico1.Handle; tray1.szTip:='我的托盘程序'; if not Shell_NotifyIcon(NIM_modify,@tray1) then begin ShowMessage('no'); end; end;procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin ico1:=ticon.Create; ico2:=ticon.create; imagelist1.GetIcon(0,ico1); imagelist1.geticon(1,ico2); tray1.cbSize:=sizeof(tray1); tray1.Wnd:=form1.Handle; tray1.uID:=0; tray1.uFlags:=NIF_ICON or NIF_TIP or NIF_MESSAGE; tray1.uCallbackMessage:=ghy_tray; tray1.hIcon:=ico1.Handle; tray1.szTip:='我的托盘程序'; if not Shell_NotifyIcon(NIM_delete,@tray1) then begin ShowMessage('no'); end;end;procedure TForm1.N1Click(Sender: TObject); begin showmessage('you click open'); end;procedure TForm1.N2Click(Sender: TObject); begin showmessage('you click save'); end;procedure TForm1.N3Click(Sender: TObject); begin showmessage('you click saveas'); end;procedure TForm1.FormCreate(Sender: TObject); begin tags:=true; ShowWindow(Application.Handle,SW_HIDE); ico1:=ticon.Create; ico2:=ticon.create; imagelist1.GetIcon(0,ico1); imagelist1.geticon(1,ico2); tray1.cbSize:=sizeof(tray1); tray1.Wnd:=form1.Handle; tray1.uID:=0; tray1.uFlags:=NIF_ICON or NIF_TIP or NIF_MESSAGE; tray1.uCallbackMessage:=ghy_tray; tray1.hIcon:=ico1.Handle; tray1.szTip:='我的托盘程序'; if not Shell_NotifyIcon(NIM_ADD,@tray1) then begin ShowMessage('no'); end;end;end.原作者 高红岩
在设计任务栏中的托盘程序时主要用到了一个WIN API函数Shell_NotifyIcon,大部分功能的实现都是在此函数基础上来实现的,该函数的原型如下:
WINSHELLAPI BOOL WINAPI Shell_NotifyIcon(
DWORD dwMessage, // message identifier
PNOTIFYICONDATA pnid // pointer to structure
);
通过看到参数我们知道要传递一个dwMessage消息参数的标识类型和一个指向具体修改信息的结构pnid,第一个参数的具体取值如下:
dwMessage
Identifier of the message to send. This parameter can be one of these values:
NIM_ADD Adds an icon to the status area.{添加图标}
NIM_DELETE Deletes an icon from the status area.{删除图标}
NIM_MODIFY Modifies an icon in the status area. {修改图标}
即为添加一个图标,删除一个图标和修改一个图标在任务栏的右部区域中。可以通过第一个参数的内容来定制对任务栏状态区的操作,第二个参数的具体取值如下:
pnid
Pointer to a NOTIFYICONDATA structure. The content of the structure depends on the value of dwMessage.
此参数为一个指向NOTIFYICONDATA结构的指针,通过这个结构来对设计者想要的操作进行定义,结构成员定义如下:
typedef struct _NOTIFYICONDATA { // nid
DWORD cbSize; {结构的大小}
HWND hWnd; {关联状态区图标的窗口句柄,用来处理回调函数}
UINT uID; {应用程序定义的状态区图标的标识符}
UINT uFlags; {此成员表明NOTIFYICONDATA记录中的成员uCallbackMessage、hIcon和szTip这三者的哪些项的值有效}
UINT uCallbackMessage; {程序定义的消息标识符,例如当鼠标在状态区图标上移动或者左右点击所发生的事情时,操作系统将向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 hIcon; {指定一个应用程序定义的图标的句柄}
char szTip[64];{在图标上显示的提示信息}
} NOTIFYICONDATA, *PNOTIFYICONDATA;
通过前面对Shell_NotifyIcon函数的基本认识,我们知道了具体的操作有添加,删除和修改图标,下面我们以一个实例来具体的去实现托盘程序的效果。
新建一个工程,然后放入ApplicationEvents1控件,在additional控件面板中,本例程带有弹出菜单功能。
代码如下:
unit Unit1;
interfaceuses
Windows,shellapi, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,AppEvnts, ImgList, Menus;
{一定要uses shellapi单元}
const
ghy_tray=wm_user+2;
type
TForm1 = class(TForm)
ImageList1: TImageList;
ApplicationEvents1: TApplicationEvents;
PopupMenu1: TPopupMenu;
N1: TMenuItem;
N2: TMenuItem;
N3: TMenuItem;
procedure ApplicationEvents1Minimize(Sender: TObject);
procedure ApplicationEvents1Restore(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure N1Click(Sender: TObject);
procedure N2Click(Sender: TObject);
procedure N3Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
procedure WMSysCommand(var msg: TMessage);message wm_syscommand;
{ Private declarations }
public
procedure mytray(var Msg: TMessage); message ghy_tray;
{ Public declarations }
end;var
Form1: TForm1;
tray1,tray2:TNotifyIconData;
ico1,ico2:ticon;
tags:boolean;
implementation{$R *.DFM}
procedure Tform1.WMSysCommand(var msg: TMessage);
begin
if msg.WParam = SC_MINIMIZE then
begin
showwindow(application.handle,sw_hide);
inherited;
end
else
inherited;
end;procedure tform1.mytray(var Msg: TMessage);
var
pt:tpoint;
begin
GetCursorPos(pt);case msg.lParam of
WM_LBUTTONDOWN:
begin
//鼠标左键被按下
if tags=true then
begin
application.Minimize;
form1.Hide;
end
else
begin
application.Restore;
end;
end;WM_LBUTTONUP:
begin
//释放鼠标左键
end;
wm_rbuttondown:
begin
//鼠标右键被按下
SetForegroundWindow(Form1.Handle);
form1.PopupMenu1.Popup(pt.x,pt.y);
end
else//调用父类的WndProc方法处理其它消息
inherited;
end;
end;procedure TForm1.ApplicationEvents1Minimize(Sender: TObject);
begin
tags:=false;
ShowWindow(Application.Handle,SW_HIDE);
tray2.cbSize:=sizeof(tray2);
tray2.Wnd:=form1.Handle;
tray2.uID:=0;
tray2.uFlags:=NIF_ICON or NIF_TIP or NIF_MESSAGE;
tray2.uCallbackMessage:=ghy_tray;
tray2.hIcon:=ico2.Handle;
tray2.szTip:='我的托盘程序';
if not Shell_NotifyIcon(NIM_modify,@tray2) then
begin
ShowMessage('no');
end;
end;procedure TForm1.ApplicationEvents1Restore(Sender: TObject);
begin
tags:=true;
form1.show;ico1:=ticon.Create;
ico2:=ticon.create;
imagelist1.GetIcon(0,ico1);
imagelist1.geticon(1,ico2);
tray1.cbSize:=sizeof(tray1);
tray1.Wnd:=form1.Handle;
tray1.uID:=0;
tray1.uFlags:=NIF_ICON or NIF_TIP or NIF_MESSAGE;
tray1.uCallbackMessage:=ghy_tray;
tray1.hIcon:=ico1.Handle;
tray1.szTip:='我的托盘程序';
if not Shell_NotifyIcon(NIM_modify,@tray1) then
begin
ShowMessage('no');
end;
end;procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
ico1:=ticon.Create;
ico2:=ticon.create;
imagelist1.GetIcon(0,ico1);
imagelist1.geticon(1,ico2);
tray1.cbSize:=sizeof(tray1);
tray1.Wnd:=form1.Handle;
tray1.uID:=0;
tray1.uFlags:=NIF_ICON or NIF_TIP or NIF_MESSAGE;
tray1.uCallbackMessage:=ghy_tray;
tray1.hIcon:=ico1.Handle;
tray1.szTip:='我的托盘程序';
if not Shell_NotifyIcon(NIM_delete,@tray1) then
begin
ShowMessage('no');
end;end;procedure TForm1.N1Click(Sender: TObject);
begin
showmessage('you click open');
end;procedure TForm1.N2Click(Sender: TObject);
begin
showmessage('you click save');
end;procedure TForm1.N3Click(Sender: TObject);
begin
showmessage('you click saveas');
end;procedure TForm1.FormCreate(Sender: TObject);
begin
tags:=true;
ShowWindow(Application.Handle,SW_HIDE);
ico1:=ticon.Create;
ico2:=ticon.create;
imagelist1.GetIcon(0,ico1);
imagelist1.geticon(1,ico2);
tray1.cbSize:=sizeof(tray1);
tray1.Wnd:=form1.Handle;
tray1.uID:=0;
tray1.uFlags:=NIF_ICON or NIF_TIP or NIF_MESSAGE;
tray1.uCallbackMessage:=ghy_tray;
tray1.hIcon:=ico1.Handle;
tray1.szTip:='我的托盘程序';
if not Shell_NotifyIcon(NIM_ADD,@tray1) then
begin
ShowMessage('no');
end;end;end.原作者 高红岩