首页 > 技术文章 > 基于对话框的程序隐藏于托盘(二)

small-lazybee 2018-10-19 17:31 原文

接下来创建托盘。

要使用托盘就要用到NOTIFYICONDATA类。步骤如下:

1. 添加成员变量

class CxxxxxDlg : public CDialog
{
...... Private:
//tray NOTIFYICONDATA m_nid; WINDOWPLACEMENT m_wp;
...... }

 

2. 定义用来响应托盘鼠标操作的消息

#define WM_SHOWTASK WM_USER+100

3.添加消息响应函数的声明

class CxxxtDlg : public CDialog
{
  ......
  LRESULT OnShowTask(WPARAM wParam, LPARAM lParam);
  ......
};

 

4.在BEGIN_MESSAGE_MAP 和 END_MESSAGE_MAP 之间添加消息处理映射:

    ON_MESSAGE(WM_SHOWTASK, OnShowTask)

5.添加消息处理函数的实现:

HRESULT CxxxxDlg::OnShowTask(WPARAM wParam, LPARAM lParam)
{
    if(wParam !=IDI_ICON1 )//
        return 1;
    switch(lParam)
    {
    case WM_RBUTTONUP:                                        // 右键起来时弹出菜单
        {

            LPPOINT lpoint = new tagPOINT;
            ::GetCursorPos(lpoint);                    // 得到鼠标位置
            CMenu menu;
            menu.CreatePopupMenu();                    // 声明一个弹出式菜单
            //增加菜单项“关闭”,点击则发送消息WM_DESTROY给主窗口(已 
            //隐藏),将程序结束。
            menu.AppendMenu(MF_STRING, WM_DESTROY, _T("关闭"));
            //确定弹出式菜单的位置 
            menu.TrackPopupMenu(TPM_LEFTALIGN, lpoint->x ,lpoint->y, this);
            //资源回收 
            HMENU hmenu = menu.Detach();
            menu.DestroyMenu();
            delete lpoint;
        }
        break;
    case WM_LBUTTONDBLCLK:                                 // 双击左键的处理
        {   // ModifyStyleEx(WS_EX_TOOLWINDOW, WS_EX_APPWINDOW);
            this->ShowWindow(SW_SHOWNORMAL);         // 显示主窗口
            SetWindowPlacement(&m_wp); 
            //CenterWindow();
        }
        break;
    }
    return 0;
}

6. 在OnInitDialog()函数中添加:

BOOL CxxxxxxDlg::OnInitDialog()
{
    ......
    //show tray  
    m_nid.cbSize  = (DWORD)sizeof(NOTIFYICONDATA);  
    m_nid.hWnd    = this->m_hWnd;  
    m_nid.uID     = IDI_ICON1; // IDR_MAINFRAME
    m_nid.uFlags  = NIF_ICON | NIF_MESSAGE | NIF_TIP ;  
    m_nid.uCallbackMessage = WM_SHOWTASK;             // 自定义的消息名称  
    m_nid.hIcon   = LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDI_ICON1)); //IDR_MAINFRAME 
    wcscpy_s(m_nid.szTip, _T("串口通信"));                // 信息提示条为"串口通信",VS2008 UNICODE编码用wcscpy_s()函数  
    Shell_NotifyIcon(NIM_ADD, &m_nid);   // 在托盘区添加图标  


    //-----------------------------------------
   // 记录窗口初始位置,托盘恢复成窗口的时候使用
   CenterWindow();
   m_wp.length = sizeof(WINDOWPLACEMENT); 
   GetWindowPlacement(&m_wp);  //恢复时用 

   ModifyStyleEx(WS_EX_APPWINDOW, 0);//从任务栏中去掉图标
   // 隐藏窗口
   SetWindowPos(&wndTop,0,0,0,0,NULL);

return TRUE; }

7. 点击最小化按钮隐藏话框程序

void CXXXXXXDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
    if ((nID & 0xFFF0) == IDM_ABOUTBOX)
    {
        CAboutDlg dlgAbout;
        dlgAbout.DoModal();
    }
    else if (nID == SC_MINIMIZE)// when click minimize, hide the window
    {
        ShowWindow(SW_HIDE);
    }
    else
    {
        CDialog::OnSysCommand(nID, lParam);
    }
}

8.在 OnDestroy 函数中销毁托盘

void CxxxxDlg::OnDestroy()
{
    CDialog::OnDestroy();

    //删除托盘图标
    ::Shell_NotifyIcon(NIM_DELETE, &m_nid); 
}

OK,搞定!

 

参考文章:

https://www.cnblogs.com/micq/p/6196734.html

https://www.cnblogs.com/JczmDeveloper/p/3510294.html

https://blog.csdn.net/starytx/article/details/69236378?locationNum=13&fps=1

https://www.cnblogs.com/likebeta/archive/2012/09/15/2687105.html

 

 

 

 

 

 

 

推荐阅读