在任务栏通知区域加上自己的图标
在任务栏通知区域加上自己的图标 在任务栏通知区域加上自己的图标2001拄
在任务栏通知区域加上自己的图标
LayoutYourOwnIconintheNoticeAreaofTaskbar 郑加齐黄聃
(北方交通大学北京100024)(北京未材防腐厂北京100024) 【摘要】详细讨论了Windows下在任务栏通知区放置图标为运作机理,解析了与图标相关的几个参数,给出
了几种常见的运用目标(单个图标,动画图标,多国标)的编码并附有明晰的解释. 【关键词】围标,通知区,编码,动态显示
ABSTRACTThepaperdiscussestherunmngmechanismoficonlayoutinthenotmeareaofta
skbarunderWindows,Bo【veseveral
parametersrelativewithicon,andgivescodesofcommonlyusedicons(singleicon,animatio
nicon,multi—icon)andcleardescrip—
tioni
KEYW0RDSicon,noticearea,coding,dynamicdisplay
位于屏幕任务栏右边凹下的区域通常叫做通知
区,平常显示系统时间和音量控制开关,但我们也经常
看到许多的专业程序(解霸,sQIServer等)在此设置
图标与用户交互,当用户击鼠标左键时.激活一个窗
弹出一个菜单.本文将讨论它的实现方 口,击右键时,
法,希望能为你的程序增光添彩.
1运行机制
应用程序在任务栏通知区域放置一个图标的同时
就定义一条回调消息.不管什幺时候,只要用户单击那
个图标,应用程序就会接受到定制消息,并且判断用户
对那个图标实行了什么操作,从这个时候开始,应用程
序就会继续它的常规执行流程.在程序退出之前,图标 将从通知区域删除,并且恢复通知区域以前的状态. 要理解整个过程,关键是要理解下面这个函数及 它的参数:
#include<sheltapi.h>
BOOLWINAPIShetl—
Notifylcon(DWORDdwMessage,
PNOTIFYICONDATApnid/I 该函数通过其两个参数的不同组合来完成该图标 的建立,改变和消亡.两个参数的内容是: dwMessage有三个值:
NIM—ADD在任务栏通知区域插入一个图标 NIM—MODIFY对任务栏通知区域图标进行修改 NIM—
DELETE从任务栏通知区域删除一个图标 typedefstruct—
NOTIFYICONDATA
{
DWoRDebSize
HWNDhWnd:
UINTUId;
UINTuFlags;
UINTuCallbaekMessage HIcoNhlcon'
wcHARszTip[64];
结构的尺寸;
代码所在的窗口句柄
图标的唯一标识;
标志;
用户定义的回调消息;
图标资源-
鼠标位于图标上时,显示
的内容;
}NOTIFYICONDATAt*PNOTIFYICONDATA}
hWnd所指窗口的进程是放置处理代码的位置, 它是整个过程的核心.
Uid的值将随用户定义的消息一起传到窗口,是 实现处理多个图标的关键.
UFlags指示该结构中:uCallbackMessage,
hlcon,WCHARszTip~64]的信息是否有效. szTip[64]预示着我们设置的提示信息不能超过 64位.
归纳建立通知区域图标的步骤如下:
第一步:定义用户消息和图标的唯一ID. 第二步:预备NOTIFYICONDATA结构:tnd 第三步:调用Shell—Notifylcon(NIM—
ADD,
8~tnd),建立图标;
第四步:在窗口进程处理用户消息,必要时可利用 Shell—
Notifyleon(NIM—MODIFY,&tnd)改变图标 的样子和图标的TIP文字.
第五步:调用Shell—Notifylcon(NIM DELETE,&tnd),删除该图标.
*2001一Ol一02收到
**郏加齐,勇,1970年出生,硕士.1992年毕业于西南交通大学,研究方向:系统
与系统集成,遗传算法等.
第14卷第6期电脑开发与应用(总287)?25? 2实现单个图标显示
在主进程中加入:
#defineWM—
TRAYNOTIFYWM—
USER+100
利用资源编辑器加入唯一ID
#defineTRAY—
ICON110
在窗口进程中加入:
switch(message)
caseWMCREATE:
hlcon=Load[con((HINSTAN(E)GetWindowLong
(hWnd,GWLHINSTANCE),MAKEINTRESOURCE(IDI
IC0N));
//此处加载图标资源{
N0TIFYICoNDATAmd; tnd.cbSize—sizeof(NOTIFYM:0NDATA);
tnd.hWnd=hWnd'
tnd.uID=TRAYICONl tnd.uFIags=NIF—
MESSAGEINIF—
ICONINIF—
TIP;
md.uCallbaekMessage=WM—
TRAYNOTIFY;
tnd.hIcon=hlcon' //定义结构NoTIFYlc0DATA中的参数 strcpy(md.szTip.THiSisaICOil)
Shell—
Notifylcon(NIM—
ADD,&1nd)}
//图标的初始建立;
caseWMCOMMANDF
//单击右键时.将弹出一十菜单,处理该菜单命令. wmldLOWORDfwParflm)1 wmEvent—HIWORD(wParam); switch(wmld)
caseIDIC0N:
MessageBoxEx(hWnd单击了图标!-"消息. MB—
OK,MAKELANGID(LANG—
NEUTRAL,SUBLANG
NEUTRAL))l
breakI
caseID—EXITI
break{
defau】t:
returnDefWindowProe(hWrtd,message,
wParam,IParam)l
break;
caseWM—
TRAYNoTIFY:
//用户自定义消息的处理.后面可看到,如果我们加上 wVaram的判断,将可以处理多图标
sw~tch(IParam)
{
caWM—
RBUT110ND0WNF
p0INTpt
intiCmdl
Getcur?rP0s(&)l
SetWocus(hWnd)'
SetActlveWindow(hWnd); HMENUhmenu'
hrnenu=LoadMenu(fHINSTANCE)GetWi
dowLong(hWnd,GWL—
HINSTANCE),MAKEINTRE- S0URCE(IDRP0PUPTRAY)); hmenu=GetSubMenu(bmenu.O)' iCmd—TrackPopupMenu(hmenu,TPM—
BoTTOMALIGNITPMLEFTALIGNITPMRE— TURNCMD-pt,X.pt.Y,O,hWnd,NULL);
//加载上下文莱单
if(iCmd)
SendMessage(hWnd,WM—
CoMMAND,
MAKEWPARAM【1Cmd.O),0); break{
CaseWM—LBUTTOND0WN:
setForegroundWindow(hwod); setFoCus(Hwnd);
setActiveWindOw(hwnd); break{
break
caseWMDESTROY:
tnd.hWnd=hWnd;
md.u[D=TRAY—ICON;
md.uFlags~NIF—
ICON;
md.hlcon=hlcon[1~: *md.szTip=,0:
//上面的代码如不加入,程序可正常结束, 但通知区图标不会马上消失,踪非该区得到嗣新的机会,
shet[一
Notifylcort(NIM—
DELETE,nd);
//消灭任务栏图标;
postQuitMessage(0); break;
default:
returnDefWindowProc(hWnd-message,
wParam,IParam);
re[urn0;
}
3实现动态图标显示
同上也定义消息和图标ID,在窗口进程中加入下 列代码(省略处同上):
switch(message)
caseWM—
CREATE:
h[con[O]
Loadlcon((HINSTANCE)GetWmdowLong(hWnd.GWL
HINSTANCE),MAKEINTRESOURCE(IDI— HAPPy)){
hlcon[:1]
Loadlcon((HINSTANCE)GetWindowLong(hWnd.GWL
HINSTANCE),E(?)lSAD))
?26?(总288)在任务栏通知区域加上自己的图标2001妊
//可加八两个或两个以上代码,
SetTimer(hWnd.1,500.NULL)F
Bs,WM—
COMMAND://单击右键时.将弹出一个 菜单.此处处理该菜单命令.
wmld—L0W0RD(wParam){ w~nEvent—HIWORD(wParam): switch(wmld)
caseIDHAPPYj
K.1】Timer(hWnd.1); CountNumber一0'
SendMessage(bWnd,WM breakf
caseIDSAD:
K|】1Timer(hWnd.1); CountNumber一1:
SendMessage(hWnd,WM break;
caseIDANIMATED;
TIMER,0.Oj
TIMER.0,0)
SetTimer(hWnd,1.500,NULL);
break;
default:
returnDefWindowProcfhWnd.message
wParam.1Param)F
break;
caseWM—
TIMER:
++CountNumber; if(CountNumber2) md.ulD—TRAY—
ICON;
tnd.uFlags=NIF—
ICONIN1F—
TIPF
tnd.hlcon—hlcon[0]; strcpy(rod.szTip,THisishappyface.")F
1
else
{
tnd.uID=TRAY—
IcoN;
tnd.uFlags=NIF—
ICONINIF—
TIP;
md.hleon—hlcon~1]; strcpy(tnd.szTip,"THisissadface.);
}
Shell—
Notifylcon(NIM—
MODIFY.nd): //利用定时器实现动态显示.同时展现修改图标
的调用形式.
break;
caseWM—
TRAYNOTIFY:
caseWM—
DEsTROY:
default;
return1)e~WindowProc(hWnd.message,
wParam,1Param) 4在通知区加入多个图标
同上建立两个图标,加入两个上下文菜单,定义两
个图标ID.
switch(message) caseWMCREATE: NoTIFYK:oNDATAmd,md1}
Shell—
Notify1con(NIM—ADD,趴nd)f shIINotifyleon(NIM—
ADD,Band1);//建
立两个图标
caseWMCOMMAND: //所有菜单命令的处理中心
caseWM—
TRAYNOTIFY:
//根据wParam中放置的值,判断出选择的是哪
个图标
if(wParam=TRAY—
ICON)
switch(IParam) {…
}
}
Lf(wParam一=TRAY—
ICON1)
switch(IParam)
{…}
break;
caseWMDESTRoY
Shell—
Notifylcon(NIM—
DELETE,&』nd);
Shell—
Noti~lcon(NIM—DELETE,~,.tnd1/; PostQuitMessage(0){ break;
defauh:
returnDefWindowProc(hWnd—message? Wparam.IParam);
}
return0;
}
另外我们也可通过定义两个回调消息来实现多个 图标,还可以实现多个动态图标.
以上列举了图标的三种方式,在此基础上,读者可 根据自己的想象,在抓住运用图通知区图标的机制上, 创造出更灵活,更生动的图标.