利用VisualC++实现系统托盘程序.docx

上传人:b****2 文档编号:23093594 上传时间:2023-04-30 格式:DOCX 页数:17 大小:21.38KB
下载 相关 举报
利用VisualC++实现系统托盘程序.docx_第1页
第1页 / 共17页
利用VisualC++实现系统托盘程序.docx_第2页
第2页 / 共17页
利用VisualC++实现系统托盘程序.docx_第3页
第3页 / 共17页
利用VisualC++实现系统托盘程序.docx_第4页
第4页 / 共17页
利用VisualC++实现系统托盘程序.docx_第5页
第5页 / 共17页
点击查看更多>>
下载资源
资源描述

利用VisualC++实现系统托盘程序.docx

《利用VisualC++实现系统托盘程序.docx》由会员分享,可在线阅读,更多相关《利用VisualC++实现系统托盘程序.docx(17页珍藏版)》请在冰豆网上搜索。

利用VisualC++实现系统托盘程序.docx

利用VisualC++实现系统托盘程序

利用VisualC++实现系统托盘程序

转自:

利用VisualC++实现系统托盘程序

自从微软公司推出Windows95操作系统以来,系统托盘应用作为一种极具吸引力的用户界面设计深受广大用户的喜爱。

使用系统托盘作为用户界面的Windows应用程序数不胜数,比如"金山词霸"、"Winamp"、"RealPlayer"等等。

这些程序运行时不显示运行窗口,只在任务栏上显示一个图标,表示程序正在运行,用户可以通过鼠标与应用程序交互,程序开发人员有时也需要编制一些仅在后台运行的类似程序,为了不干扰前台程序的运行界面和不显示不必要的窗口,应使程序运行时的主窗口不可见。

同时将一个图标显示在任务栏右端静态通告区中并响应用户的鼠标动作。

本实例就介绍VisualC++开发这类程序的设计方法,该程序编译运行后,如果双击托盘图标,程序会弹出一个消息列表窗口,只要鼠标在托盘图标上移动或点击(无论是左右键的单击或双击),产生的消息都会显示在这个窗口里;当鼠标光标移到托盘图标上时,在图标附近会显示提示信息;单击右键时弹出上下文菜单,这个菜单中应包含打开属性页的命令或者打开与图标相关的其它窗口的命令,另外,该程序还可以动态的改变托盘的图标。

参照这个例子,相信读者能轻松自如地在自己的程序中应用系统托盘。

一、实现方法

为了实现拖盘程序,首先要使程序的主窗口不可见,这点实现起来十分容易,只要调用ShowWindow(SW_HIDE)就可以了,本实例采用的就是这种方法,还有一种思路是通过分别设置主边框窗口的风格和扩展风格来隐藏主框架:

BOOLCMainFrame:

:

PreCreateWindow(CREATESTRUCT&cs)

{

cs.style=WS_POPUP;//使主窗口不可见;

cs.dwExStyle=WS_EX_TOOLWINDOW;//不显示任务按钮;

returnCFrameWnd:

:

PreCreateWindow(cs);

}

在任务条上显示图标是利用系统API函数Shell_NotifyIcon()来将一个图标显示在任务栏的通告区中。

该函数的原型为:

BOOLShell_NotifyIcon(DWORDdwMessage,PNOTIFYICONDATApnid);

该函数的第一个参数dwMessage类型为DWORD,表示要进行的动作,它可以是下面的值之一:

NIM_ADD:

添加一个图标到任务栏。

NIM_MODIFY:

修改状态栏区域的图标。

NIM_DELETE:

删除状态栏区域的图标。

NIM_SETFOCUS:

将焦点返回到任务栏通知区域。

当完成用户界面操作时,任务栏图标必须用此消息。

例如,如果任务栏图标正显示上下文菜单,但用户按下"ESCAPE"键取消操作,这时就必须用此消息将焦点返回到任务栏通知区域。

NIM_SETVERSION:

指示任务栏按照相应的动态库版本工作。

第二个参数pnid是NOTIFYICONDATA结构的地址,其内容视dwMessage的值而定。

这个结构在SHELLAPI.H文件中定义如下:

typedefstruct_NOTIFYICONDATA{

DWORDcbSize;//结构大小(sizeofstruct),必须设置

HWNDhWnd;//发送通知消息的窗口句柄

UINTuID;//图标ID(由回调函数的WPARAM指定)

UINTuFlags;

UINTuCallbackMessage;//消息被发送到此窗口过程

HICONhIcon;//任务栏图标句柄

CHARszTip[64];//提示文本

}NOTIFYICONDATA;

该结构中uFlags的值分别为:

#defineNIF_MESSAGE0x1//表示uCallbackMessage有效

#defineNIF_ICON0x2//表示hIcon有效

#defineNIF_TIP0x4//表示szTip有效

在该结构的成员中,cbSize为该结构所占的字节数,hWnd为接受该图标所发出的消息的窗口的句柄(鼠标在任务栏上程序图标上动作时图标将发出消息,这个消息用户要自己定义),uID为被显示图标的ID,uFlags指明其余的几个成员(hIcon、uCallBackMessage和szTip)的值是否有效,uCallbackMessage为一个用户自定义的消息,当用户在该图标上作用一些鼠标动作时,图标将向应用程序的主框架窗口(hWnd成员中指定的窗口)发出该消息,为了使程序的主框架得到该通知消息,需要设置NOTIFYICONDATA结构的flag成员的值为NIF_MESSAGE。

hIcon为将在任务栏上显示的图标句柄,szTip鼠标停留在该图标上时显示的提示字符串。

尽管Shell_NotifyIcon函数简单实用,但它毕竟是个Win32API,为此本实例将它封装在了一个C++类中,这个类叫做CTrayIcon,有了它,托盘编程会更加轻松自如,因为它隐藏了NOTIFYICONDATA、消息代码、标志以及一些繁琐的细节。

二、编程步骤

  1、启动VisualC++6.0,生成一个单文档的应用程序TrayTest,取消文档视图支持;

  2、在CMainFrame类中添加自定义消息#defineWM_MY_TRAY_NOTIFICATIONWM_USER+0,并在该类中为此自定义消息手动添加消息映射ON_MESSAGE(WM_MY_TRAY_NOTIFICATION,OnTrayNotification)和消息响应函数afx_msgLRESULTOnTrayNotification(WPARAMwp,LPARAMlp);

  3、设计二个图标添加到项目中,其ID标志分别为"IDI_MYICON"、"IDI_MYICON2",作为托盘显示时的图标;

  4、在CMainFrame类中添加下述变量:

CTrayIconm_trayIcon(用来操作图标的类对象)、CEditm_wndEdit(编辑框用来显示所跟踪到的鼠标消息)、intm_iWhichIcon(决定当前托盘使用哪个图标)、BOOLm_bShutdown(是否关闭当前拖盘程序标志)、BOOLm_bShowTrayNotifications(是否显示托盘消息标志);

  5、为程序的IDR_MAINFRAME添加处理菜单项和托盘的上下文菜单IDI_TRAYICON(具体的菜单项的标题和ID标志符参见代码部分),然后使用ClassWizard为各个菜单项添加处理函数;

  6、添加代码,编译运行程序。

////////////////////////////////////////////////CTrayIcon类的头文件;

#ifndef_TRAYICON_H

#define_TRAYICON_H

classCTrayIcon:

publicCCmdTarget{

 protected:

  DECLARE_DYNAMIC(CTrayIcon)

  NOTIFYICONDATAm_nid;//structforShell_NotifyIconargs

 public:

  CTrayIcon(UINTuID);

  ~CTrayIcon();

  //Callthistoreceivetraynotifications

  voidSetNotificationWnd(CWnd*pNotifyWnd,UINTuCbMsg);

  BOOLSetIcon(UINTuID);//mainvariantyouwanttouse

  BOOLSetIcon(HICONhicon,LPCSTRlpTip);

  BOOLSetIcon(LPCTSTRlpResName,LPCSTRlpTip)

  {returnSetIcon(lpResName?

   AfxGetApp()->LoadIcon(lpResName):

NULL,lpTip);}

  BOOLSetStandardIcon(LPCTSTRlpszIconName,LPCSTRlpTip)

  {returnSetIcon(:

:

LoadIcon(NULL,lpszIconName),lpTip);}

  virtualLRESULTOnTrayNotification(WPARAMuID,LPARAMlEvent);

};

#endif

///////////////////////////////////////////////////CTrayIcon类的.CPP文件

#include"stdafx.h"

#include"trayicon.h"

#include//forAfxLoadString

IMPLEMENT_DYNAMIC(CTrayIcon,CCmdTarget)

CTrayIcon:

:

CTrayIcon(UINTuID)

{

 memset(&m_nid,0,sizeof(m_nid));//InitializeNOTIFYICONDATA

 m_nid.cbSize=sizeof(m_nid);

 m_nid.uID=uID;//neverchangesafterconstruction

 AfxLoadString(uID,m_nid.szTip,sizeof(m_nid.szTip));

 //Useresourcestringastipifthereisone

}

CTrayIcon:

:

~CTrayIcon()

{

 SetIcon(0);//removeiconfromsystemtray

}

voidCTrayIcon:

:

SetNotificationWnd(CWnd*pNotifyWnd,UINTuCbMsg)

{

 //Setnotificationwindow.Itmustcreatedalready.

 ASSERT(pNotifyWnd==NULL  :

:

IsWindow(pNotifyWnd->GetSafeHwnd()));

 m_nid.hWnd=pNotifyWnd->GetSafeHwnd();

 ASSERT(uCbMsg==0  uCbMsg>=WM_USER);

 m_nid.uCallbackMessage=uCbMsg;

}

BOOLCTrayIcon:

:

SetIcon(UINTuID)

{

 //SetsboththeiconandtooltipfromresourceID,Toremovetheicon,callSetIcon(0)

 HICONhicon=NULL;

 if(uID){

  AfxLoadString(uID,m_nid.szTip,sizeof(m_nid.szTip));

  hicon=AfxGetApp()->LoadIcon(uID);

 }

 returnSetIcon(hicon,NULL);

}

BOOLCTrayIcon:

:

SetIcon(HICONhicon,LPCSTRlpTip)

{

 //CommonSetIconforalloverloads.

 UINTmsg;

 m_nid.uFlags=0;

 if(hicon){

  //Settheicon

  msg=m_nid.hIcon?

NIM_MODIFY:

NIM_ADD;

  m_nid.hIcon=hicon;//Addorreplaceiconinsystemtray

  m_nid.uFlags =NIF_ICON;

 }else{

  if(m_nid.hIcon==NULL)//removeiconfromtray

   returnTRUE;//alreadydeleted

  msg=NIM_DELETE;

 }

 if(lpTip)//Usethetip,ifany

  strncpy(m_nid.szTip,lpTip,sizeof(m_nid.szTip));

 if(m_nid.szTip[0])

  m_nid.uFlags =NIF_TIP;

 if(m_nid.uCallbackMessage&&m_nid.hWnd)//Usecallbackifany

  m_nid.uFlags =NIF_MESSAGE;

  BOOLbRet=Shell_NotifyIcon(msg,&m_nid);//Doit

 if(msg==NIM_DELETE  !

bRet)

  m_nid.hIcon=NULL;//failed

 returnbRet;

}

LRESULTCTrayIcon:

:

OnTrayNotification(WPARAMwID,LPARAMlEvent)

{

 if(wID!

=m_nid.uID  (lEvent!

=WM_RBUTTONUP&&lEvent!

=WM_LBUTTONDBLCLK))

  return0;

 CMenumenu;//装载上下文菜单;

 if(!

menu.LoadMenu(m_nid.uID))

  return0;

 CMenu*pSubMenu=menu.GetSubMenu(0);

 if(!

pSubMenu)

  return0;

 if(lEvent==WM_RBUTTONUP){//设置第一个菜单项为默认菜单项目

  :

:

SetMenuDefaultItem(pSubMenu->m_hMenu,0,TRUE);

  //将当前菜单作为上下文菜单;

  CPointmouse;

  GetCursorPos(&mouse);

  :

:

SetForegroundWindow(m_nid.hWnd);

  :

:

TrackPopupMenu(pSubMenu->m_hMenu,0,mouse.x,mouse.y,0,m_nid.hWnd,NULL);

 }else//doubleclick:

executefirstmenuitem

  :

:

SendMessage(m_nid.hWnd,WM_COMMAND,pSubMenu->GetMenuItemID(0),0);

 return1;

}

/////////////////////////////////MainFrm.h:

interfaceoftheCMainFrameclass

#if!

defined(AFX_MAINFRM_H__9ED70A69_C975_4F20_9D4E_B2877E3575D0__INCLUDED_)

#defineAFX_MAINFRM_H__9ED70A69_C975_4F20_9D4E_B2877E3575D0__INCLUDED_

#if_MSC_VER>1000

#pragmaonce

#endif//_MSC_VER>1000

#include"trayicon.h"

classCMainFrame:

publicCFrameWnd

{

 public:

  CMainFrame();

 protected:

  DECLARE_DYNAMIC(CMainFrame)

  //Attributes

 public:

  //Overrides

  //ClassWizardgeneratedvirtualfunctionoverrides

  //{{AFX_VIRTUAL(CMainFrame)

  //}}AFX_VIRTUAL

  //Implementation

 public:

  virtual~CMainFrame();

  #ifdef_DEBUG

   virtualvoidAssertValid()const;

   virtualvoidDump(CDumpContext&dc)const;

  #endif

 protected:

//controlbarembeddedmembers

  CStatusBarm_wndStatusBar;

  CTrayIconm_trayIcon;//mytrayicon

  CEditm_wndEdit;//todisplaytraynotifications

  intm_iWhichIcon;//whichHICONtouse

  BOOLm_bShutdown;//OKtoterminateTRAYTEST

  BOOLm_bShowTrayNotifications;//displayinfoinmainwindow

  //Generatedmessagemapfunctions

 protected:

  //{{AFX_MSG(CMainFrame)

   afx_msgLRESULTOnTrayNotification(WPARAMwp,LPARAMlp);

   afx_msgintOnCreate(LPCREATESTRUCTlpCreateStruct);

   afx_msgvoidOnToggleIcon();

   afx_msgvoidOnViewClear();

   afx_msgvoidOnViewNotifications();

   afx_msgvoidOnUpdateViewClear(CCmdUI*pCmdUI);

   afx_msgvoidOnUpdateViewNotifications(CCmdUI*pCmdUI);

   afx_msgvoidOnClose();

   afx_msgvoidOnAppOpen();

   afx_msgvoidOnAppSuspend();

   //NOTE-theClassWizardwilladdandremovememberfunctionshere.

   //DONOTEDITwhatyouseeintheseblocksofgeneratedcode!

  //}}AFX_MSG

 DECLARE_MESSAGE_MAP()

};

///////////////////////////////////////////////CMainFrm.cpp

#include"stdafx.h"

#include"TrayTest.h"

#include"MainFrm.h"

#ifdef_DEBUG

#definenewDEBUG_NEW

#undefTHIS_FILE

staticcharTHIS_FILE[]=__FILE__;

#endif

LRESULTCTrayIcon:

:

OnTrayNotification(WPARAMwID,LPARAMlEvent)

{

 if(wID!

=m_nid.uID  (lEvent!

=WM_RBUTTONUP&&lEvent!

=WM_LBUTTONDBLCLK))

  return0;

 CMenumenu;//装载上下文菜单;

 if(!

menu.LoadMenu(m_nid.uID))

  return0;

 CMenu*pSubMenu=menu.GetSubMenu(0);

 if(!

pSubMenu)

  return0;

 if(lEvent==WM_RBUTTONUP){//设置第一个菜单项为默认菜单项目

  :

:

SetMenuDefaultItem(pSubMenu->m_hMenu,0,TRUE);

  //将当前菜单作为上下文菜单;

  CPointmouse;

  GetCursorPos(&mouse);

  :

:

SetForegroundWindow(m_nid.hWnd);

  :

:

TrackPopupMenu(pSubMenu->m_hMenu,0,mouse.x,mouse.y,0,m_nid.hWnd,NULL);

 }else//doubleclick:

executefirstmenuitem

  :

:

SendMessage(m_nid.hWnd,WM_COMMAND,pSubMenu->GetMenuItemID(0),0);

 return1;

}

/////////////////////////////////MainFrm.h:

interfaceoftheCMainFrameclass

#if!

defined(AFX_MAINFRM_H__9ED70A69_C975_4F20_9D4E_B2877E3575D0__INCLUDED_)

#defineAFX_MAINFRM_H__9ED70A69_C975_4F20_9D4E_B2877E3575D0__INCLUDED_

#if_MSC_VER>1000

#pragmaonce

#endif//_MSC_VER>1000

#include"trayicon.h"

classCMainFrame:

publicCFrameWnd

{

 public:

  CMainFrame();

 protected:

  DECLARE_DYNAMIC(CMainFrame)

  //Attributes

 public:

  //Overrides

  //ClassWizardgeneratedvirtualfunctionoverrides

  //{{AFX_VIRTUAL(CMainFrame)

  //}}AFX_VIRTUAL

  //Implementation

 public:

  virtual~CMainFrame();

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 幼儿教育

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1