您的位置:首页 > 编程语言 > Delphi

任务栏通知区域小图标的编程实践(DELPHI版)

2008-01-22 23:23 525 查看
Windows操作系统任务栏右下角的通知区域主要用来放置系统的通知图标,并对鼠标输入进行响应。同时,用户程序也可以通过系统外壳函数进行操作,放置自己的图标,并根据鼠标操作进行响应。那么,怎样进行此区域的编程哪?

其实很简单,只需要一个函数:
function Shell_NotifyIcon(dwMessage: DWORD; lpData: PNotifyIconDataA): BOOL; stdcall;

此函数在ShellApi单元中申明,你只需要在你的文件中uses ShellApi就可以使用此函数。那么,怎样使用它进行通知区域的编程哪?总结起来如下:

1.准备lpData结构,标明要显示的图标(lpData^.hIcon),标明要接受消息的窗口(lpData^.hWnd),标明消息ID(lpData^.uCallMessage),标明当鼠标进入时要显示的标题文字(lpData^.szTip[64])等。
2.调用Shell_NotifyIcon(dwMessage: DWORD; lpData: PNotifyIconData): BOOL函数,并把dwMessage参数设为NIM_ADD,这样就在通知区域放置了图标。
3.在接受消息窗口编写消息ID的处理函数,以响应鼠标消息。
4.最后再调用Shell_NotifyIcon(dwMessage: DWORD; lpData: PNotifyIconData): BOOL函数,并把dwMessage参数设为NIM_DELETE,用来删除图标。

从上面可以看出,通知区域图标的编程主要由Shell_NotifyIcon,我先对此函数的两个参数进行介绍,然后进入实践。

第一个参数dwMessage: DWORD
此参数控制了图标的添加和修改,见下表
NIM_ADD 添加图标
NIM_MODIFY 修改图标
NIM_DELETE 删除图标

第二个参数lpData: PnotifyIconData :
PNotifyIconData = ^TnotifyIconData;
TnotifyIconData = _NOTIFYICONDATA;
_NOTIFYICONDATA = record
cbSize: DWORD; //次结构的大小,使用SIZEOF()
Wnd: HWND; //接受消息的窗口HANDLE
uID: UINT; //图标使用的ID
uFlags: UINT;
//说明此结构的有效信息(NIF_MESSAGE,NIF_ICON,NIF_TIP
uCallbackMessage: UINT; //定义消息ID
hIcon: HICON; //图标HANDLE
szTip: array [0..63] of AnsiChar; //显示标题
end;

下面为实践的实际代码:
//添加图标
procedure Tfrm.AddNotifyIcon;
var
NotifyData : TNotifyIconData;
begin
NotifyData.cbSize := sizeof(TNotifyIconData);
notifyData.Wnd := self.handle;
NotifyData.uID := FC_BACKUP_ICONID;
NotifyData.uFlags := NIF_MESSAGE OR NIF_ICON OR NIF_TIP;
NotiFydata.uCallbackMessage := MSG_FCBACKUP_ICON;
NotifyData.hIcon := LoadIcon(hInstance,'Notify');

Shell_NotifyIcon(NIM_ADD,@NotifyData);
end;

//处理图标消息
procedure Tfrm.MSGFCBACKUPICON(var msg: Tmessage);
var
pt : Tpoint;
iCommand : integer;
hmm,hPopup : hMenu;
rt : Trect;
begin
case msg.LParam of
WM_LBUTTONUP : begin
ShowWindow(application.Handle,SW_SHOWNORMAL );
SetForegroundWindow(application.Handle);
end;
WM_RBUTTONUP : begin
//显示菜单
GetCursorPos(pt);

hmm := loadMenu(hInstance,'Notifymenu');
hpopup := GetSubmenu(hMM,0);

iCommand := integer(TrackPopupMenu(hPopup,TPM_BOTTOMALIGN or TPM_LEFTBUTTON OR TPM_RETURNCMD, PT.X,GetSystemMetrics(SM_CYSCREEN)-10,0,self.Handle,nil));
//处理菜单ID
case icommand of
AB_NOTIFY_OPEN : begin
ShowWindow(application.Handle,SW_SHOWNORMAL );
SetForegroundWindow(application.Handle);

end;
AB_NOTIFY_RUN : actRunExecute(SELF);
AB_NOTIFY_STOP : actStopExecute(self);
AB_NOTIFY_FILECOPY : actRunFileCopyExecute(self);
AB_NOTIFY_EXIT : CLOSE;
end;
destroyMenu(hmm);
end;
end;
end;

//删除图标
procedure Tfrm.DelNotifyIcon;
var
NotifyData : TNotifyIconData;
begin
NotifyData.cbSize := sizeof(TNotifyIconData);
notifyData.Wnd := self.handle;
NotifyData.uID := FC_BACKUP_ICONID; //必须与添加使用的ID相同
NotifyData.uFlags := NIF_MESSAGE OR NIF_ICON OR NIF_TIP;
NotiFydata.uCallbackMessage := MSG_FCBACKUP_ICON;
NotifyData.hIcon := LoadIcon(hInstance,'Notify');
//NotifyData.hIcon := LoadIcon(nil,Pointer(integer(IDI_APPLICATION)));
notifyData.szTip := '';

Shell_NotifyIcon(NIM_DELETE,@NotifyData);
end;

最后的技巧,当在通知区域放置图标后,我们就希望程序不在任务栏出现,同时当用户单击关闭按钮时,希望程序在后台运行,这时候我们需要改写WM_SysCommand消息的响应,具体使用如下代码:
procedure TfrmAutoBack.WMSysCommand(var Message: TWMSysCommand);
begin
//当用户单击关闭是最小化程序
if (Message.CmdType and $FFF0 = SC_CLOSE) then begin
message.cmdType := message.cmdType xor SC_CLOSE;
message.CmdType := message.CmdType or SC_MINIMIZE;
end;
//最小化程序后,隐藏任务栏
inherited;
if (Message.CmdType and $FFF0 = SC_MINIMIZE) then
ShowWindow(application.handle,SW_HIDE);

end;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: