[一篇VC小文章]VC++制作一个最小化最小托盘的8步骤(Minimize your app to systray in 8 easy steps)翻译完
By Yasar Arslan. From codeproject
这篇文章内容比较基础,最近看到觉得有用,顺便翻译一下
有空可以写一个自己的TrayIcon类,化简这些原始的操作。
Introduction
这篇文章解析了 Shell_NotifyIcon
这个函数用法--用来建立你自己的应用程序的系统托盘图标.
这篇文章给了基本的缩小到托盘的操作过程并让你从中了解.
这篇文章提供8个简单的步骤让你成功的实现在你的程序中建立系统托盘图标.
源代码提供了一个基于对话框的演示程序.
Tray Icons
为了用托盘图标你需要用一个shell函数 :)
BOOL Shell_NotifyIcon( DWORD dwMessage, PNOTIFYICONDATA pnid );
The dwMessage
可选的参数包括 the NIM_ADD,NIM_DELETE and NIM_MODIFY
功能分别是添加删除以及修改图标于系统图标.
PNOTIFYICONDATA
结构包括这些系统需要处理的任务图标状态区域消息等信息.
typedef struct _NOTIFYICONDATA {
DWORD cbSize;
HWND hWnd;
UINT uID;
UINT uFlags;
UINT uCallbackMessage;
HICON hIcon;
#if (_WIN32_IE < 0x0500)
TCHAR szTip[64];
#else
TCHAR szTip[128];
#endif #if (_WIN32_IE >= 0x0500)
DWORD dwState;
DWORD dwStateMask;
TCHAR szInfo[256];
union {
UINT uTimeout;
UINT uVersion;
} DUMMYUNIONNAME;
TCHAR szInfoTitle[64];
DWORD dwInfoFlags;
#endif #if (_WIN32_IE >= 0x600)
GUID guidItem;
#endif
} NOTIFYICONDATA, *PNOTIFYICONDATA;
*Note: 更完全的信息可以去参考MSDN
Creating the Application
Create a new VC++ dialog based project and call it TrayMin.
创建一个名叫TrayMin的基于对话框的VC++工程
Step: 1
自定义消息于 TrayMinDlg.h 头文件.
#define WM_TRAY_MESSAGE (WM_USER + 1)
The WM_USER
常量用来帮助用户定义自己的消息被用来建立个人的窗口类, 定义时通常用这种格式 WM_USER+X
, 这里 X 是一个整形变量.
*更详细的看MSDN
Step: 2
现在在Now add the DECLARE_MESSAGE_MAP() 之前添加下面的用户函数吧( TrayMinDlg.h file) afx_msg void OnTrayNotify(WPARAM wParam, LPARAM lParam);
当添加一个图标到托盘时这有一个图标的回调消息,注意到 NOTIFYICONDATA
结构中有uCallbackMessage成员是回调消息识别的关键,它会被传给NIM_ADD(我们之后将会见到更详细的)。当添加托盘图标这个事件发生时,系统发送一个回调函数到由hWnd成员对象指定的窗口过程(winproc),wParam 参数可以用来被识别究竟发生了什么操作。lParam参数存放发生事件相关的鼠标或者键盘消息。举个例子,当一个鼠标指针指向一个托盘图标,lParam将包括WM_MOUSEMOVE
Step: 3
现在添加下面的这行在消息宏中(MessageMap)在TrayMinDlg.cpp
ON_MESSAGE(WM_TRAY_MESSAGE,OnTrayNotify)
现在应该是这样的.
BEGIN_MESSAGE_MAP(CTrayMinDlg, CDialog) //{{AFX_MSG_MAP(CTrayMinDlg) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_MESSAGE(WM_TRAY_MESSAGE ,OnTrayNotify) //}}AFX_MSG_MAP END_MESSAGE_MAP()
Step: 4
现在在TrayMinDlg.cpp 定义OnTrayNotify函数,不要忘记在函数头部添加afx_msg。
afx_msg void CTrayMinDlg::OnTrayNotify(WPARAM wParam, LPARAM lParam) { UINT uID; UINT uMsg; uID = (UINT) wParam; uMsg = (UINT) lParam; if (uID != 1) return; CPoint pt; switch (uMsg ) { case WM_LBUTTONDOWN: GetCursorPos(&pt); ClientToScreen(&pt); OnTrayLButtonDown(pt); break; case WM_RBUTTONDOWN: case WM_CONTEXTMENU: GetCursorPos(&pt); OnTrayRButtonDown(pt); break; } return; }
Step: 5
现在在TrayMinDlg类添加两个成员函数来相应鼠标事件。
实现鼠标左键单击的相应
-
函数类型:void
-
函数声明:
OnTrayLButtonDown(CPoint pt)
实现鼠标右键单击的相应
- 函数类型:
void
- 函数声明:
OnTrayRButtonDown(CPoint pt)
OnTrayLButtonDown(CPoint pt)的定义如下
.
void CTrayMinDlg::OnTrayLButtonDown(CPoint pt) { MessageBox("You have clicked Left mouse Button "); }
The Declaration of OnTrayRButtonDown(CPoint pt)
is as following.
void CTrayMinDlg::OnTrayRButtonDown(CPoint pt) { //m_menu is the member of CTrayMinDlg as CMenu m_menu; m_menu.GetSubMenu(0)->TrackPopupMenu(TPM_BOTTOMALIGN| TPM_LEFTBUTTON|TPM_RIGHTBUTTON,pt.x,pt.y,this); }
Step: 6
Add two member variable to the CTrayMinDlg
.
为CTrayMinDlg添加两个成员变量
- Variable Type:
NOTIFYICONDATA
- Variable Name:
m_TrayData
; - Variable Type:
CMenu
- Variable Name:
m_menu
;
现在添加菜单资源
Step: 7
现在画一个最小化的按钮在对话框设计中
并且添加这个按钮的执行函数
void CShellDlg::OnMinimize() { m_TrayData.cbSize = sizeof(NOTIFYICONDATA); //Size of this structure, in bytes. m_TrayData.hWnd = this->m_hWnd; //Handle to the window that receives notification //messages associated with an icon in the taskbar //status area. The Shell uses hWnd and uID to //identify which icon to operate on when //Shell_NotifyIcon is invoked. m_TrayData.uID = 1; //Application-defined identifier of the taskbar icon.//The Shell uses hWnd and uID to identify which icon //to operate on when Shell_NotifyIcon is invoked. You// can have multiple icons associated with a single //hWnd by assigning each a different uID. m_TrayData.uCallbackMessage = WM_TRAY_MESSAGE; //Application-defined message identifier. The system //uses this identifier to send notifications to the //window identified in hWnd. These notifications are //sent when a mouse event occurs in the bounding //rectangle of the icon, or when the icon is selected //or activated with the keyboard. The wParam parameter //of the message contains the identifier of the taskbar //icon in which the event occurred. The lParam parameter //holds the mouse or keyboard message associated with the// event. For example, when the pointer moves over a //taskbar icon, lParam is set to WM_MOUSEMOVE. m_TrayData.hIcon = this->m_hIcon; //Handle to the icon to be added, modified, or deleted strcpy(m_TrayData.szTip,"My Icon"); //Pointer to a null-terminated string with the text //for a standard ToolTip. It can have a maximum of 64 //characters including the terminating NULL. m_TrayData.uFlags = NIF_ICON|NIF_MESSAGE; //Flags that indicate which of the other members contain valid data. BOOL bSuccess = FALSE; BOOL BSus = FALSE; BSus = m_menu.LoadMenu(IDR_MENU1); if(!(BSus)) MessageBox("Unabled to Loa menu"); bSuccess = Shell_NotifyIcon(NIM_ADD,&m_TrayData); if(!(bSuccess)) MessageBox("Unable to Set Tary Icon"); else { this->ShowWindow(SW_MINIMIZE); this->ShowWindow(SW_HIDE); } }
Step: 8
在退出菜单的执行函数写下如下
Shell_NotifyIcon(NIM_DELETE,&m_TrayData);
DestroyWindow();
现在可以运行程序,并且尝试最小化按钮的使用(他会最小化导系统托盘)。
现在尽情发挥,完善这些步骤,完成自己的系统托盘图标吧!