MFC程序最小化到系统托盘及其响应函数

预备知识:

Windows API函数:

WINSHELLAPI BOOL WINAPI Shell_NotifyIcon(
    DWORD dwMessage, 
    PNOTIFYICONDATA pnid
);

该函数的两个参数:

第一个参数dwMessage可以取以下值:

NIM_ADD          向托盘中加入一个图标;
NIM_MODIFY      修改托盘中的图标
NIM_DELETE       从托盘中删除一个图标

第二个参数pnid是NOTIFYICONDATA结构的一个引用。该结构的原型如下:

typedef struct _NOTIFYICONDATA { 
    DWORD cbSize;               // 结构的大小,必须在程序中给出
    HWND hWnd;                  // 程序中将要接收托盘消息的窗口句柄 
    UINT uID;                   // 应用程序中定义的托盘图标ID,此参数用作标识
    UINT uFlags;                //设置属性 标记下边3个参数是否有效
    UINT uCallbackMessage;      // 自定义的消息ID值
    HICON hIcon;                //显示在系统托盘上的Icon的句柄
    char szTip[64];             // 用于图标显示的提示字符串
} NOTIFYICONDATA, *PNOTIFYICONDATA; 
 

具体步骤:

1.在CxxxDlg.h中增加一个私有的NOTIFYICONDAT对象和消息处理函数;

private:
    NOTIFYICONDATA m_notify; 
    afx_msg LRESULT OnTrayMsg(WPARAM wparan, LPARAM lparam); //托盘处理函数
    afx_msg void OnSysCommand(UINT nID, LPARAM lParam);//最小化按键响应
    afx_msg void OnDestroy();//程序退出时删除托盘图标
    afx_msg void setTray();//设置托盘图标

 

2.WM_USER_NOTIFYICON是自定义的消息 在文件CxxxDlg.cpp文件开头中进行声明;

#define WM_USER_NOTIFYICON WM_USER+1

 

3.添加映射:

BEGIN_MESSAGE_MAP(CxxxDlg, CDialog)
   ON_WM_SYSCOMMAND() ON_MESSAGE(WM_USER_NOTIFYICON,
&CxxxDlg::OnTrayMsg) //}}AFX_MSG_MAP END_MESSAGE_MAP()

 

4.实现自定义的消息处理函数,在消息处理函数中对自定义的消息进行处理;

LRESULT CxxxDlg::OnTrayMsg(WPARAM wparam, LPARAM lparam);
LRESULT CxxxDlg::OnTrayMsg(WPARAM wparam, LPARAM lparam)
{
    if(wparam!=IDR_MAINFRAME)   
        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,"关闭");     
            //确定弹出式菜单的位置   
            menu.TrackPopupMenu(TPM_LEFTALIGN,lpoint->x,lpoint->y,this);   
            //资源回收   
            HMENU hmenu=menu.Detach();   
            menu.DestroyMenu();   
            delete lpoint;   
        }   
        break;   
    case WM_LBUTTONDBLCLK://双击左键的处理   
        {   
            this->ShowWindow(SW_SHOWNORMAL);//显示主窗口
        this->SetWindowPos(&wndTopMost,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);//使窗口总是在最前面
            this->SetWindowPos(&wndNoTopMost,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);//使窗口可以被其他窗口覆盖        
        }   
        break;   
    }    
    return 0;
}
 

void CxxxDlg::OnDestroy();

void CxxxDlg::OnDestroy()
{
    CDialog::OnDestroy();
    
    Shell_NotifyIcon(NIM_DELETE, &m_notify);//退出程序后删除图标
}

void CxxxDlg::setTray();

void CxxxDlg::setTray()
{
    m_notify.cbSize = (DWORD)sizeof(NOTIFYICONDATA); 
    m_notify.hWnd = this->m_hWnd; 
    m_notify.uID = IDR_MAINFRAME; 
    m_notify.uFlags = NIF_ICON|NIF_MESSAGE|NIF_TIP; 
    m_notify.uCallbackMessage = WM_USER_NOTIFYICON;//自定义的消息名称 
    m_notify.hIcon = LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDR_MAINFRAME)); 
    strcpy(m_notify.szTip,"托盘程序"); //信息提示条 
    Shell_NotifyIcon(NIM_ADD,&m_notify); //在托盘区添加图标 
    ShowWindow(SW_HIDE); //隐藏主窗
}

void CxxxDlg::OnSysCommand(UINT nID, LPARAM lParam);

void CxxxDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
   CDialog::OnSysCommand(nID, lParam);
if(nID==SC_MINIMIZE) { setTray();//最小化到托盘 } }

 

 

完成。

参考资料:

 
posted @ 2018-07-24 16:36  余生以学  阅读(950)  评论(0编辑  收藏  举报