VC 将程序最小化到托盘

这篇文章内容比较基础,最近看到觉得有用,顺便翻译一下
有空可以写一个自己的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();


现在可以运行程序,并且尝试最小化按钮的使用(他会最小化导系统托盘)。
现在尽情发挥,完善这些步骤,完成自己的系统托盘图标吧!

 

你可能感兴趣的:(VC 将程序最小化到托盘)