利用Visual C++实现系统托盘程序.docx_第1页
利用Visual C++实现系统托盘程序.docx_第2页
利用Visual C++实现系统托盘程序.docx_第3页
利用Visual C++实现系统托盘程序.docx_第4页
利用Visual C++实现系统托盘程序.docx_第5页
已阅读5页,还剩12页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

利用Visual C+实现系统托盘程序这些程序运行时不显示运行窗口,只在任务栏上显示一个图标,表示程序正在运行,用户可以通过鼠标与应用程序交互,程序开发人员有时也需要编制一些仅在后台运行的类似程序,为了不干扰前台程序的运行界面和不显示不必要的窗口,应使程序运行时的主窗口不可见。同时将一个图标显示在任务栏右端静态通告区中并响应用户的鼠标动作。本实例就介绍Visual C+开发这类程序的设计方法,该程序编译运行后,如果双击托盘图标,程序会弹出一个消息列表窗口,只要鼠标在托盘图标上移动或点击(无论是左右键的单击或双击),产生的消息都会显示在这个窗口里;当鼠标光标移到托盘图标上时,在图标附近会显示提示信息;单击右键时弹出上下文菜单,这个菜单中应包含打开属性页的命令或者打开与图标相关的其它窗口的命令,另外,该程序还可以动态的改变托盘的图标。参照这个例子,相信读者能轻松自如地在自己的程序中应用系统托盘。 一、实现方法为了实现拖盘程序,首先要使程序的主窗口不可见,这点实现起来十分容易,只要调用ShowWindow(SW_HIDE)就可以了,本实例采用的就是这种方法,还有一种思路是通过分别设置主边框窗口的风格和扩展风格来隐藏主框架: BOOL CMainFrame:PreCreateWindow(CREATESTRUCT& cs) cs.style =WS_POPUP;/使主窗口不可见; cs.dwExStyle =WS_EX_TOOLWINDOW;/不显示任务按钮; return CFrameWnd:PreCreateWindow(cs); 在任务条上显示图标是利用系统API函数Shell_NotifyIcon()来将一个图标显示在任务栏的通告区中。该函数的原型为: BOOL Shell_NotifyIcon(DWORD dwMessage, PNOTIFYICONDATA pnid); 该函数的第一个参数dwMessage类型为DWORD,表示要进行的动作,它可以是下面的值之一: NIM_ADD: 添加一个图标到任务栏。 NIM_MODIFY: 修改状态栏区域的图标。 NIM_DELETE: 删除状态栏区域的图标。 NIM_SETFOCUS: 将焦点返回到任务栏通知区域。当完成用户界面操作时,任务栏图标必须用此消息。例如,如果任务栏图标正显示上下文菜单,但用户按下ESCAPE键取消操作,这时就必须用此消息将焦点返回到任务栏通知区域。 NIM_SETVERSION:指示任务栏按照相应的动态库版本工作。 第二个参数pnid是NOTIFYICONDATA结构的地址,其内容视dwMessage的值而定。这个结构在SHELLAPI.H文件中定义如下: typedef struct _NOTIFYICONDATA DWORD cbSize; / 结构大小(sizeof struct),必须设置 HWND hWnd; / 发送通知消息的窗口句柄 UINT uID; / 图标ID ( 由回调函数的WPARAM 指定) UINT uFlags; UINT uCallbackMessage; / 消息被发送到此窗口过程 HICON hIcon; / 任务栏图标句柄 CHAR szTip64; / 提示文本 NOTIFYICONDATA; 该结构中uFlags的值分别为: #define NIF_MESSAGE 0x1 / 表示uCallbackMessage 有效 #define NIF_ICON 0x2 / 表示hIcon 有效 #define NIF_TIP 0x4 / 表示szTip 有效 在该结构的成员中,cbSize为该结构所占的字节数,hWnd为接受该图标所发出的消息的窗口的句柄(鼠标在任务栏上程序图标上动作时图标将发出消息,这个消息用户要自己定义),uID为被显示图标的ID,uFlags指明其余的几个成员(hIcon、uCallBackMessage和szTip)的值是否有效,uCallbackMessage为一个用户自定义的消息,当用户在该图标上作用一些鼠标动作时,图标将向应用程序的主框架窗口(hWnd成员中指定的窗口)发出该消息,为了使程序的主框架得到该通知消息,需要设置NOTIFYICONDATA 结构的flag成员的值为NIF_MESSAGE。hIcon为将在任务栏上显示的图标句柄,szTip鼠标停留在该图标上时显示的提示字符串。 尽管Shell_NotifyIcon函数简单实用,但它毕竟是个Win32 API,为此本实例将它封装在了一个C+类中,这个类叫做CTrayIcon,有了它,托盘编程会更加轻松自如,因为它隐藏了NOTIFYICONDATA、消息代码、标志以及一些繁琐的细节。二、编程步骤 1、 启动Visual C+6.0,生成一个单文档的应用程序TrayTest,取消文档视图支持; 2、 在CMainFrame类中添加自定义消息#define WM_MY_TRAY_NOTIFICATION WM_USER+0,并在该类中为此自定义消息手动添加消息映射ON_MESSAGE(WM_MY_TRAY_NOTIFICATION, OnTrayNotification)和消息响应函数afx_msg LRESULT OnTrayNotification(WPARAM wp, LPARAM lp); 3、 设计二个图标添加到项目中,其ID标志分别为IDI_MYICON、IDI_MYICON2,作为托盘显示时的图标; 4、 在CMainFrame类中添加下述变量: CTrayIcon m_trayIcon(用来操作图标的类对象)、CEdit m_wndEdit(编辑框用来显示所跟踪到的鼠标消息)、int m_iWhichIcon(决定当前托盘使用哪个图标)、BOOL m_bShutdown(是否关闭当前拖盘程序标志)、BOOL m_bShowTrayNotifications(是否显示托盘消息标志); 5、 为程序的IDR_MAINFRAME添加处理菜单项和托盘的上下文菜单IDI_TRAYICON(具体的菜单项的标题和ID标志符参见代码部分),然后使用Class Wizard为各个菜单项添加处理函数; 6、 添加代码,编译运行程序。 /CTrayIcon类的头文件; #ifndef _TRAYICON_H #define _TRAYICON_H class CTrayIcon : public CCmdTarget protected: DECLARE_DYNAMIC(CTrayIcon) NOTIFYICONDATA m_nid; / struct for Shell_NotifyIcon args public: CTrayIcon(UINT uID); CTrayIcon(); / Call this to receive tray notifications void SetNotificationWnd(CWnd* pNotifyWnd, UINT uCbMsg); BOOL SetIcon(UINT uID); / main variant you want to use BOOL SetIcon(HICON hicon, LPCSTR lpTip); BOOL SetIcon(LPCTSTR lpResName, LPCSTR lpTip) return SetIcon(lpResName ? AfxGetApp()-LoadIcon(lpResName) : NULL, lpTip); BOOL SetStandardIcon(LPCTSTR lpszIconName, LPCSTR lpTip) return SetIcon(:LoadIcon(NULL, lpszIconName), lpTip); virtual LRESULT OnTrayNotification(WPARAM uID, LPARAM lEvent); ; #endif /CTrayIcon类的.CPP文件 #include stdafx.h #include trayicon.h #include / for AfxLoadString IMPLEMENT_DYNAMIC(CTrayIcon, CCmdTarget) CTrayIcon:CTrayIcon(UINT uID) memset(&m_nid, 0 , sizeof(m_nid); / Initialize NOTIFYICONDATA m_nid.cbSize = sizeof(m_nid); m_nid.uID = uID; / never changes after construction AfxLoadString(uID, m_nid.szTip, sizeof(m_nid.szTip); / Use resource string as tip if there is one CTrayIcon:CTrayIcon() SetIcon(0); / remove icon from system tray void CTrayIcon:SetNotificationWnd(CWnd* pNotifyWnd, UINT uCbMsg) / Set notification window. It must created already. ASSERT(pNotifyWnd=NULL :IsWindow(pNotifyWnd-GetSafeHwnd(); m_nid.hWnd = pNotifyWnd-GetSafeHwnd(); ASSERT(uCbMsg=0 uCbMsg=WM_USER); m_nid.uCallbackMessage = uCbMsg; BOOL CTrayIcon:SetIcon(UINT uID) / Sets both the icon and tooltip from resource ID ,To remove the icon, call SetIcon(0) HICON hicon=NULL; if (uID) AfxLoadString(uID, m_nid.szTip, sizeof(m_nid.szTip); hicon = AfxGetApp()-LoadIcon(uID); return SetIcon(hicon, NULL); BOOL CTrayIcon:SetIcon(HICON hicon, LPCSTR lpTip) / Common SetIcon for all overloads. UINT msg; m_nid.uFlags = 0; if (hicon) / Set the icon msg = m_nid.hIcon ? NIM_MODIFY : NIM_ADD; m_nid.hIcon = hicon; / Add or replace icon in system tray m_nid.uFlags = NIF_ICON; else if (m_nid.hIcon=NULL) / remove icon from tray return TRUE; / already deleted msg = NIM_DELETE; if (lpTip) / Use the tip, if any strncpy(m_nid.szTip, lpTip, sizeof(m_nid.szTip); if (m_nid.szTip0) m_nid.uFlags = NIF_TIP; if (m_nid.uCallbackMessage & m_nid.hWnd) / Use callback if any m_nid.uFlags = NIF_MESSAGE; BOOL bRet = Shell_NotifyIcon(msg, &m_nid); / Do it if (msg=NIM_DELETE !bRet) m_nid.hIcon = NULL; / failed return bRet; LRESULT CTrayIcon:OnTrayNotification(WPARAM wID, LPARAM lEvent) if (wID!=m_nid.uID (lEvent!=WM_RBUTTONUP & lEvent!=WM_LBUTTONDBLCLK) return 0; CMenu menu;/装载上下文菜单; if (!menu.LoadMenu(m_nid.uID) return 0; CMenu* pSubMenu = menu.GetSubMenu(0); if (!pSubMenu) return 0; if (lEvent=WM_RBUTTONUP) /设置第一个菜单项为默认菜单项目 :SetMenuDefaultItem(pSubMenu-m_hMenu, 0, TRUE); /将当前菜单作为上下文菜单; CPoint mouse; GetCursorPos(&mouse); :SetForegroundWindow(m_nid.hWnd); :TrackPopupMenu(pSubMenu-m_hMenu, 0, mouse.x, mouse.y, 0,m_nid.hWnd, NULL); else / double click: execute first menu item :SendMessage(m_nid.hWnd, WM_COMMAND, pSubMenu-GetMenuItemID(0), 0); return 1; / MainFrm.h : interface of the CMainFrame class #if !defined(AFX_MAINFRM_H_9ED70A69_C975_4F20_9D4E_B2877E3575D0_INCLUDED_) #define AFX_MAINFRM_H_9ED70A69_C975_4F20_9D4E_B2877E3575D0_INCLUDED_ #if _MSC_VER 1000 #pragma once #endif / _MSC_VER 1000 #include trayicon.h class CMainFrame : public CFrameWnd public: CMainFrame(); protected: DECLARE_DYNAMIC(CMainFrame) / Attributes public: / Overrides / ClassWizard generated virtual function overrides /AFX_VIRTUAL(CMainFrame) /AFX_VIRTUAL / Implementation public: virtual CMainFrame(); #ifdef _DEBUG virtual void AssertValid() const; virtual void Dump(CDumpContext& dc) const; #endif protected: / control bar embedded members CStatusBar m_wndStatusBar; CTrayIcon m_trayIcon; / my tray icon CEdit m_wndEdit; / to display tray notifications int m_iWhichIcon; / which HICON to use BOOL m_bShutdown; / OK to terminate TRAYTEST BOOL m_bShowTrayNotifications; / display info in main window / Generated message map functions protected: /AFX_MSG(CMainFrame) afx_msg LRESULT OnTrayNotification(WPARAM wp, LPARAM lp); afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); afx_msg void OnToggleIcon(); afx_msg void OnViewClear(); afx_msg void OnViewNotifications(); afx_msg void OnUpdateViewClear(CCmdUI* pCmdUI); afx_msg void OnUpdateViewNotifications(CCmdUI* pCmdUI); afx_msg void OnClose(); afx_msg void OnAppOpen(); afx_msg void OnAppSuspend(); / NOTE - the ClassWizard will add and remove member functions here. / DO NOT EDIT what you see in these blocks of generated code! /AFX_MSG DECLARE_MESSAGE_MAP() ; /CMainFrm.cpp #include stdafx.h #include TrayTest.h #include MainFrm.h #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE = _FILE_; #endifLRESULT CTrayIcon:OnTrayNotification(WPARAM wID, LPARAM lEvent) if (wID!=m_nid.uID (lEvent!=WM_RBUTTONUP & lEvent!=WM_LBUTTONDBLCLK) return 0; CMenu menu;/装载上下文菜单; if (!menu.LoadMenu(m_nid.uID) return 0; CMenu* pSubMenu = menu.GetSubMenu(0); if (!pSubMenu) return 0; if (lEvent=WM_RBUTTONUP) /设置第一个菜单项为默认菜单项目 :SetMenuDefaultItem(pSubMenu-m_hMenu, 0, TRUE); /将当前菜单作为上下文菜单; CPoint mouse; GetCursorPos(&mouse); :SetForegroundWindow(m_nid.hWnd); :TrackPopupMenu(pSubMenu-m_hMenu, 0, mouse.x, mouse.y, 0,m_nid.hWnd, NULL); else / double click: execute first menu item :SendMessage(m_nid.hWnd, WM_COMMAND, pSubMenu-GetMenuItemID(0), 0); return 1; / MainFrm.h : interface of the CMainFrame class #if !defined(AFX_MAINFRM_H_9ED70A69_C975_4F20_9D4E_B2877E3575D0_INCLUDED_) #define AFX_MAINFRM_H_9ED70A69_C975_4F20_9D4E_B2877E3575D0_INCLUDED_ #if _MSC_VER 1000 #pragma once #endif / _MSC_VER 1000 #include trayicon.h class CMainFrame : public CFrameWnd public: CMainFrame(); protected: DECLARE_DYNAMIC(CMainFrame) / Attributes public: / Overrides / ClassWizard generated virtual function overrides /AFX_VIRTUAL(CMainFrame) /AFX_VIRTUAL / Implementation public: virtual CMainFrame(); #ifdef _DEBUG virtual void AssertValid() const; virtual void Dump(CDumpContext& dc) const; #endif protected: / control bar embedded members CStatusBar m_wndStatusBar; CTrayIcon m_trayIcon; / my tray icon CEdit m_wndEdit; / to display tray notifications int m_iWhichIcon; / which HICON to use BOOL m_bShutdown; / OK to terminate TRAYTEST BOOL m_bShowTrayNotifications; / display info in main window / Generated message map functions protected: /AFX_MSG(CMainFrame) afx_msg LRESULT OnTrayNotification(WPARAM wp, LPARAM lp); afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); afx_msg void OnToggleIcon(); afx_msg void OnViewClear(); afx_msg void OnViewNotifications(); afx_msg void OnUpdateViewClear(CCmdUI* pCmdUI); afx_msg void OnUpdateViewNotifications(CCmdUI* pCmdUI); afx_msg void OnClose(); afx_msg void OnAppOpen(); afx_msg void OnAppSuspend(); / NOTE - the ClassWizard will add and remove member functions here. / DO NOT EDIT what you see in these blocks of generated code! /AFX_MSG DECLARE_MESSAGE_MAP() ; /CMainFrm.cpp #include stdafx.h #include TrayTest.h #include MainFrm.h #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE = _FILE_; #endif / / CMainFrame diagnostics #ifdef _DEBUG void CMainFrame:AssertValid() const CFrameWnd:AssertValid(); void CMainFrame:Dump(CDumpContext& dc) const CFrameWnd:Dump(dc); #endif /_DEBUG / BOOL CMyApp:InitInstance() /在应用程序初始化函数中将程序的主框架隐藏起来; #ifdef _AFXDLL Enable3dControls(); / Call this when using MFC in a shared DLL #else Enable3dControlsStatic(); / Call this when linking to MFC statically #endif SetRegistryKey(_T(Local AppWizard-Generated Applications); CMainFrame* pFrame = new CMainFrame; m_pMainWnd = pFrame; pFrame-LoadFrame(IDR_MAI

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论