📄 利用任务栏上的图标与用户交.htm
字号:
<html><head><meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=gb_2312-80"><meta NAME="GENERATOR" CONTENT="Microsoft FrontPage 3.0"><title>利用任务栏上的图标与用户交互</title></head><body LINK="#0000ff" VLINK="#800080"><!-- FC HP BN1 START --><!-- Please do not remove the line above or the code within this section --><!-- Doing so may cause damage to your pages or insertion of multiple banners--><center><p><table border="0" cellspacing="0" cellpadding="0"><tr><td colspan="11"><img src="http://www.fortunecity.com/console2/newnav/top.gif" height="7" width="555"></td></tr><tr><td><img src="http://www.fortunecity.com/console2/newnav/left.gif" alt="FC Navigation Console" height="60" width="72" border="0" usemap="#fcleft"><map name="fcleft"><area shape="rect" coords="10,43,64,60" href="http://www2.fortunecity.com/cgi-bin/homepage/estate.pl?referer=navbar" target="_top"><area shape="rect" coords="9,21,61,36" href="http://www2.fortunecity.com/cgi-bin/showarea.pl?area=skyscraper&referer=navbar" target="_top"><area shape="rect" coords="8,0,62,15" href="http://www.fortunecity.com" target="_top"><area shape="rect" href="http://www.fortunecity.com" target="_top" coords="0,0,49,49"></map></td><td colspan="9"><A HREF="http://ad.doubleclick.net/jump/fc.us468/member/tech;s1=m;s3=tech;pos=1;tag=g;sz=468x60;mtile=1;num=78088?"><IMG SRC="http://ad.doubleclick.net/ad/fc.us468/member/tech;s1=m;s3=tech;pos=1;tag=g;sz=468x60;mtile=1;num=78088?" border=0 height="60" width="468"></A></td><td><img src="http://www.fortunecity.com/console2/newnav/right.gif" width="15" height="60"></td></tr><tr><td><img src="http://www.fortunecity.com/console2/newnav/left2.gif" height="31" width="72" target="_top"></td><td><img src="http://www.fortunecity.com/console2/newnav/gap1.gif" width="17" height="31"></td><td><a href="http://adex3.flycast.com/server/socket/127.0.0.1:2800/click/FortuneCitycom/NavBar1/78088" target="_top"><img src="http://adex3.flycast.com/server/socket/127.0.0.1:2800/ad/FortuneCitycom/NavBar1/78088" border="0" width="88" height="31"></a></td><td><img src="http://www.fortunecity.com/console2/newnav/gap2.gif" width="24" height="31"></td><td><a href="http://adex3.flycast.com/server/socket/127.0.0.1:2800/click/FortuneCitycom/NavBar2/78088" target="_top"><img src="http://adex3.flycast.com/server/socket/127.0.0.1:2800/ad/FortuneCitycom/NavBar2/78088" border="0" width="88" height="31"></a></td><td><img src="http://www.fortunecity.com/console2/newnav/gap3.gif" width="24" height="31"></td><td><a href="http://adex3.flycast.com/server/socket/127.0.0.1:2800/click/FortuneCitycom/NavBar3/78088" target="_top"><img src="http://adex3.flycast.com/server/socket/127.0.0.1:2800/ad/FortuneCitycom/NavBar3/78088" border="0" width="88" height="31"></a></td><td><img src="http://www.fortunecity.com/console2/newnav/gap4.gif" width="19" height="31"></td><td><a href="http://www2.fortunecity.com/cgi-bin/homepage/navbarforward.cgi?from=nav4&referer=navbare" target="_top"><img src="http://www.fortunecity.com/console2/newnav/button4.gif" border="0" width="88" height="31"></a></td><td><img src="http://www.fortunecity.com/console2/newnav/gap5.gif" width="32" height="31"></td><td><img src="http://www.fortunecity.com/console2/newnav/right2.gif" width="15" height="31"></td></tr></table></p></center><!-- WARNING: under no circumstances remove the line below. Doing so may damage your page.--><!-- FC HP BN1 END --><font FACE="黑体" LANG="ZH-CN" size="4"><p ALIGN="CENTER"></font><font FACE="黑体" LANG="ZH-CN" size="5">利用任务栏上的图标与用户交互</p></font><p ALIGN="CENTER"><small><font lang="ZH-CN" face="宋体" size="5"><small>作者:李奔</small></font></small></p><p ALIGN="CENTER"><font FACE="黑体" LANG="ZH-CN" size="5"><small><small>回到<ahref="../chinese.htm">中文教材</a></small></small></font></p><font FACE="楷体_GB2312" LANG="ZH-CN" SIZE="5"><p ALIGN="JUSTIFY"></font><font FACE="楷体_GB2312" LANG="ZH-CN" size="4">我们有时需要编制一些仅在后台监控的程序,为了不干扰前台程序的运行界面和不显示不必要的窗口,应使其运行时的主窗口不可见。同时,应该让用户知道该程序正在运行,并且达到与用户进行交互的目的。将一个图标显示在任务栏右端静态通告区中并响应用户的鼠标动作是当前非常流行的方法,它体现了</font><fontSIZE="4">Windows 95<font FACE="楷体_GB2312" LANG="ZH-CN">友好的界面风格。下面以一个</font>SDI<fontFACE="楷体_GB2312" LANG="ZH-CN">(单文档界面)程序为例,讲述采用</font>Microsoft Visual C++ 5.0<font FACE="楷体_GB2312" LANG="ZH-CN">开发这类程序的主要步骤。</p><p ALIGN="JUSTIFY">首先,要使程序的主窗口不可见,并且不在任务栏上出现任务按钮,要做到这两点,需分别设置主边框窗口的风格和扩展风格:</p></font></font><font size="3"><p ALIGN="JUSTIFY">BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)</p><p ALIGN="JUSTIFY">{</p><p ALIGN="JUSTIFY">cs.style =WS_POPUP;//<font FACE="楷体_GB2312" LANG="ZH-CN">使主窗口不可见</p><p ALIGN="JUSTIFY"></font>cs.dwExStyle |=WS_EX_TOOLWINDOW;//<font FACE="楷体_GB2312"LANG="ZH-CN">不显示任务按钮</p></font><p ALIGN="JUSTIFY">return CFrameWnd::PreCreateWindow(cs);</p></font><font FACE="楷体_GB2312" LANG="ZH-CN" size="3"><p ALIGN="JUSTIFY">}</p></font><font size="4" FACE="楷体_GB2312" LANG="ZH-CN"><p ALIGN="JUSTIFY">其次,利用系统函数</font><font SIZE="4">Shell_NotifyIcon<fontFACE="楷体_GB2312" LANG="ZH-CN">将一个图标显示在任务栏的通告区中。该函数的原型为:</p></font></font><font size="3"><p ALIGN="JUSTIFY">WINSHELLAPI BOOL WINAPI Shell_NotifyIcon(</p><dir> <dir> <p ALIGN="JUSTIFY">DWORD dwMessage, </p> <p ALIGN="JUSTIFY">PNOTIFYICONDATA pnid </p> </dir></dir><p ALIGN="JUSTIFY">); </p></font><font SIZE="4"><p ALIGN="JUSTIFY"><font FACE="楷体_GB2312" LANG="ZH-CN">下例中被显示的是主边框窗口的图标,实际上可以显示任何图标:</p></font></font><font size="3"><p ALIGN="JUSTIFY">int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)</p><font FACE="楷体_GB2312" LANG="ZH-CN"><p ALIGN="JUSTIFY">{</p><p ALIGN="JUSTIFY"></font>…</p><font FACE="楷体_GB2312" LANG="ZH-CN"><p ALIGN="JUSTIFY"></font>NOTIFYICONDATA tnd;</p><p ALIGN="JUSTIFY">tnd.cbSize=sizeof(NOTIFYICONDATA);</p><p ALIGN="JUSTIFY">tnd.hWnd=this->m_hWnd;</p><p ALIGN="JUSTIFY">tnd.uID=IDR_MAINFRAME;</p><p ALIGN="JUSTIFY">tnd.uFlags=NIF_MESSAGE|NIF_ICON|NIF_TIP;</p><p ALIGN="JUSTIFY">tnd.uCallbackMessage=WM_LIBEN;</p><p ALIGN="JUSTIFY">tnd.hIcon=LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDR_MAINFRAME));</p><p ALIGN="JUSTIFY">strcpy(tnd.szTip,"<font FACE="楷体_GB2312" LANG="ZH-CN">提示信息</font>");</p><p ALIGN="JUSTIFY">Shell_NotifyIcon(NIM_ADD,&tnd);</p><font FACE="楷体_GB2312" LANG="ZH-CN"><p ALIGN="JUSTIFY"></font>…</p></font><font FACE="楷体_GB2312" LANG="ZH-CN" size="3"><p ALIGN="JUSTIFY">}</p></font><font size="4" FACE="楷体_GB2312" LANG="ZH-CN"><p ALIGN="JUSTIFY">在调用该函数之前,需要确定其参数的取值,其中之一为一个具有</font><fontSIZE="4">NOTIFYICONDATA<font FACE="楷体_GB2312" LANG="ZH-CN">类型的结构。其原型为:</p></font></font><font size="3"><p ALIGN="JUSTIFY">typedef struct _NOTIFYICONDATA { // nid</p><p ALIGN="JUSTIFY">DWORD cbSize;</p><p ALIGN="JUSTIFY">HWND hWnd;</p><p ALIGN="JUSTIFY">UINT uID;</p><p ALIGN="JUSTIFY">UINT uFlags;</p><p ALIGN="JUSTIFY">UINT uCallbackMessage;</p><p ALIGN="JUSTIFY">HICON hIcon; </p><p ALIGN="JUSTIFY">charszTip[64]; }</p><p ALIGN="JUSTIFY">NOTIFYICONDATA, *PNOTIFYICONDATA; </p></font><font size="4" FACE="楷体_GB2312" LANG="ZH-CN"><p ALIGN="JUSTIFY">在该结构的成员中,</font><font SIZE="4">cbSize<fontFACE="楷体_GB2312" LANG="ZH-CN">为该结构所占的字节数,</font>hWnd<fontFACE="楷体_GB2312" LANG="ZH-CN">为接受该图标所发出的消息的窗口的句柄,</font>uID<fontFACE="楷体_GB2312" LANG="ZH-CN">为被显示图标的</font>ID<font FACE="楷体_GB2312"LANG="ZH-CN">,</font>uFlags<font FACE="楷体_GB2312" LANG="ZH-CN">指明其余的几个成员(</font>hIcon<fontFACE="楷体_GB2312" LANG="ZH-CN">、</font>uCallBackMessage<font FACE="楷体_GB2312"LANG="ZH-CN">和</font>szTip<font FACE="楷体_GB2312" LANG="ZH-CN">)的值是否有效,</font>uCallbackMessage<fontFACE="楷体_GB2312" LANG="ZH-CN">为一个自定义的消息,当用户在该图标上作用一些鼠标动作时,将向</font>hWnd<fontFACE="楷体_GB2312" LANG="ZH-CN">成员中指定的窗口发出该消息,可以定义该消息为</font>WM_USER+100<fontFACE="楷体_GB2312" LANG="ZH-CN">。</font>hIcon<font FACE="楷体_GB2312" LANG="ZH-CN">为被显示图标的句柄,</font>szTip<fontFACE="楷体_GB2312" LANG="ZH-CN">为一字符数组,当鼠标停留在该图标上时,将其内容显示在浮动的提示信息框中。</font>Shell_NotifyIcon<fontFACE="楷体_GB2312" LANG="ZH-CN">函数的另一个参数是一个预定义的消息,可以取如下值之一:</font>NIM_ADD<fontFACE="楷体_GB2312" LANG="ZH-CN">、</font>NIM_DELETE<font FACE="楷体_GB2312"LANG="ZH-CN">或</font>NIM_MODIFY<font FACE="楷体_GB2312" LANG="ZH-CN">,分别表示添加图标、删除图标或修改图标。</p><p ALIGN="JUSTIFY">最后,要与用户进行交互,也就是当用户在该图标上单击或双击鼠标左键或右键时要执行相应的操作,至少也要响应用户终止该程序的意愿。上面已经提到,当用户在图标上进行鼠标动作时,将向</font>hWnd<fontFACE="楷体_GB2312" LANG="ZH-CN">成员中指定的窗口发出自定义的消息,该消息由</font>uCallbackMessage<fontFACE="楷体_GB2312" LANG="ZH-CN">成员指定(在上例中为</font>WM_LIBEN<fontFACE="楷体_GB2312" LANG="ZH-CN">,取值为</font>WM_USER+100<font FACE="楷体_GB2312"LANG="ZH-CN">)。因此,我们的任务就是在</font>hWnd<font FACE="楷体_GB2312"LANG="ZH-CN">窗口中响应该自定义消息:</p></font></font><font size="3"><p ALIGN="JUSTIFY">void CMainFrame::OnLiben(WPARAM wParam,LPARAM lParam)</p><p ALIGN="JUSTIFY">{</p><p ALIGN="JUSTIFY">UINT uID;//<font FACE="楷体_GB2312" LANG="ZH-CN">发出该消息的图标的</font>ID</p><font FACE="楷体_GB2312" LANG="ZH-CN"><p ALIGN="JUSTIFY"></font>UINT uMouseMsg;//<font FACE="楷体_GB2312" LANG="ZH-CN">鼠标动作</p><p ALIGN="JUSTIFY"></font>POINT pt;</p><p ALIGN="JUSTIFY">uID=(UINT) wParam;</p><p ALIGN="JUSTIFY">uMouseMsg=(UINT) lParam;</p><p ALIGN="JUSTIFY">if(uMouseMsg==WM_RBUTTONDOWN)//<font FACE="楷体_GB2312" LANG="ZH-CN">如果是单击右键</p><p ALIGN="JUSTIFY">{</p><p ALIGN="JUSTIFY"></font>switch(uID)</p><p ALIGN="JUSTIFY">{</p><p ALIGN="JUSTIFY">case IDR_MAINFRAME://<font FACE="楷体_GB2312" LANG="ZH-CN">如果是我们的图标</p><p ALIGN="JUSTIFY"></font>GetCursorPos(&pt);//<font FACE="楷体_GB2312" LANG="ZH-CN">取得鼠标位置</p><p ALIGN="JUSTIFY"></font>…//<font FACE="楷体_GB2312" LANG="ZH-CN">执行相应操作</p><p ALIGN="JUSTIFY"></font>break;</p><font FACE="楷体_GB2312" LANG="ZH-CN"><p ALIGN="JUSTIFY"></font>…</p><font FACE="楷体_GB2312" LANG="ZH-CN"><p ALIGN="JUSTIFY"></font>default:</p><p ALIGN="JUSTIFY">…</p><font FACE="楷体_GB2312" LANG="ZH-CN"><p ALIGN="JUSTIFY">}</p><p ALIGN="JUSTIFY">}</p><p ALIGN="JUSTIFY"></font>return; </p><p ALIGN="JUSTIFY">}</p></font><font size="4" FACE="楷体_GB2312" LANG="ZH-CN"><p ALIGN="JUSTIFY">需要注意的是,首先要在该窗口类的头文件中给出该消息映射函数的原型说明: </p></font><font size="3"><p ALIGN="JUSTIFY">afx_msg void OnLiben(WPARAM wParam,LPARAM lParam);</p></font><font size="4" FACE="楷体_GB2312" LANG="ZH-CN"><p ALIGN="JUSTIFY">并且要在</font><font SIZE="4">CPP<font FACE="楷体_GB2312"LANG="ZH-CN">文件中的消息映射中加入相应的条目,注意一定要加在</font>//{{AFX_MSG_MAP(CMainFrame)</font><fontFACE="楷体_GB2312" LANG="ZH-CN" size="3">和</font><font SIZE="4">//}}AFX_MSG_MAP</font><fontFACE="楷体_GB2312" LANG="ZH-CN" size="3">之外:</p></font><font size="3"><p ALIGN="JUSTIFY">BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)</p><p ALIGN="JUSTIFY">//{{AFX_MSG_MAP(CMainFrame)</p><p ALIGN="JUSTIFY">ON_WM_CREATE()</p><p ALIGN="JUSTIFY">ON_COMMAND(ID_APP_EXIT, OnAppExit)</p><p ALIGN="JUSTIFY">//}}AFX_MSG_MAP</p><p ALIGN="JUSTIFY">ON_MESSAGE(WM_LIBEN,OnLiben)</p><p ALIGN="JUSTIFY">END_MESSAGE_MAP()</p></font><font FACE="楷体_GB2312" LANG="ZH-CN" size="4"><p ALIGN="JUSTIFY">当程序结束时,需要删去通告区中的图标,这时同样应该调用</font><fontSIZE="4">Shell_NotifyIcon<font FACE="楷体_GB2312" LANG="ZH-CN">函数,只不过第一个参数是表示删除图标的</font>NIM_DELETE<fontFACE="楷体_GB2312" LANG="ZH-CN">了:</p></font></font><font size="3"><p ALIGN="JUSTIFY">void CMainFrame::OnAppExit() </p><p ALIGN="JUSTIFY">{</p><p ALIGN="JUSTIFY">// TODO: Add your command handler code here</p><p ALIGN="JUSTIFY">NOTIFYICONDATA tnid;</p><p ALIGN="JUSTIFY">tnid.cbSize=sizeof(NOTIFYICONDATA);</p><p ALIGN="JUSTIFY">tnid.hWnd=this->m_hWnd;</p><p ALIGN="JUSTIFY">tnid.uID=IDR_MAINFRAME;//<font FACE="楷体_GB2312" LANG="ZH-CN">保证删除的是我们的图标</p><p ALIGN="JUSTIFY"></font>Shell_NotifyIcon(NIM_DELETE,&tnid);</p><p ALIGN="JUSTIFY">AfxPostQuitMessage(0);</p><p ALIGN="JUSTIFY">}</p></font><font FACE="楷体_GB2312" LANG="ZH-CN" size="4"><p ALIGN="JUSTIFY">通过类似的步骤,读者可以响应其他的消息,完成更加高级的交互功能,这里不再赘述。上文所述是笔者经验所得,肯定有不到之处,欢迎指正。</p></font><p ALIGN="CENTER"><font face="黑体" lang="ZH-CN" size="5"><small><small>回到<ahref="../chinese.htm">中文教材</a></small></small></font></p></body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -