任务栏通知区域小图标的编程实践(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;
其实很简单,只需要一个函数:
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;
相关文章推荐
- 28、Windows API Shell任务栏通知区域(Tray)图标
- Delphi笔记-在任务栏通知区中加图标
- 任务栏的通知区域的图标模糊的问题之一
- Delphi之Windows Taskbar API 编程,包括任务栏进度条,图标覆盖,任务栏缩略图,跳转列表
- win7笔记本任务栏通知区域里电源图标不见或呈灰色的解决方法
- Win7删除桌面右下角任务栏通知区域带红叉的小白旗图标的方法
- 删除Windows7任务栏通知区域的大量无效旧图标
- Win7任务栏通知区域图标设置
- 处理win7任务栏通知区域图标异常问题
- 最小化以图标显示在任务栏的通知区域中
- Delphi对Windows通知栏图标编程示例
- Windows8任务栏通知区域输入法图标消失不见的解决方法
- windows7下MSN如何最小化到任务栏系统通知区域
- 本地网络连接——已选“连接后在通知区域显示图标”却不显示
- Vista 快速清理通知区域的图标
- Delphi XE4 主窗体隐藏之后任务栏没有图标显示。
- 只需两步轻松除无效图标还Win7任务栏通知区洁净
- Win10任务栏通知区域时间不显示无法看到当前时间的解决方法
- 删除Win7通知区域的无效图标
- 如何设置Windows7任务栏通知区图标的三种方法介绍