您的位置:首页 > 其它

MFC程序最小化到系统托盘

2016-05-17 10:29 309 查看
转载自:http://blog.csdn.net/csf111/article/details/6980508

 为了使MFC程序(SDI,MDI,DLG)均能最小化到系统托盘,这里运用消息机制来实现系统托盘效果。

          那么什么是托盘呢?所谓的“托盘”,在Windows系统界面中,指的就是下面任务条右侧,有系统时间等等的标志的那一部分。在程序最小化或挂起时,但有不希望占据任务栏的时候,就可以把程序放到托盘区。

          怎么实现呢?这里需要运用到的Windows API函数:
BOOL Shell_NotifyIcon(
DWORD dwMessage,
PNOTIFYICONDATA lpdata
);

          函数了里面的参数对于实现不同的效果尤其重要,包括托盘图标、托盘菜单等等。那么我们来了解一下两个参数吧:

dwMessage可以取以下值:

NIM_ADD 向托盘中加入一个图标

NIM_MODIFY 修改托盘中的图标

NIM_DELETE 从托盘中删除一个图标

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

[cpp] view
plain copy

 print?

typedef struct _NOTIFYICONDATA {   

    DWORD cbSize; // 结构的大小,必须在程序中给出  

    HWND hWnd;    // 程序中将要接收托盘消息的窗口句柄  

    UINT uID;     // 应用程序中定义的托盘图标ID,此参数用作标识  

    UINT uFlags;  //设置属性 标记下边3个参数是否有效  

    UINT uCallbackMessage;// 自定义的消息ID值  

    HICON hIcon;//显示在系统托盘上的Icon的句柄  

    #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;   

           具体步骤如下:

1.在程序中增加一个私有的NOTIFYICONDAT对象

[cpp] view
plain copy

 print?

private:  

        NOTIFYICONDATA m_tnid;  

2.在初始化窗口时对NOTIFYICONDAT对象初始化 用Shell_NotifyIcon函数进行注册

[cpp] view
plain copy

 print?

m_notify.cbSize=sizeof NOTIFYICONDATA;  

m_notify.hWnd=this->m_hWnd;    

m_notify.uID=IDR_MAINFRAME;  

m_notify.hIcon=LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDR_MAINFRAME));  

strcpy(m_notify.szTip,"Michael_Chen is a good man");  

m_notify.uCallbackMessage=WM_USER_NOTIFYICON;  

m_notify.uFlags=NIF_ICON|NIF_MESSAGE|NIF_TIP; //OK,下面就是托盘产生了.   

Shell_NotifyIcon(NIM_ADD,&m_notify);  

3.增加自定义的消息处理函数或者重载WindowProc函数,在消息处理函数或WindowProc函数中对自定义的消息进行处理

1)运用自定义消息

i,WM_USER_NOTIFYICON是自定义的消息 在头文件中进行声明;

[cpp] view
plain copy

 print?

#define WM_USER_NOTIFYICON WM_USER+1  

ii,在.h文件中声明消息函数原型

[cpp] view
plain copy

 print?

afx_msg LRESULT OnNotifyMsg(WPARAM wparam,LPARAM lparam);  

iii,在.cpp文件中进行消息映射

[cpp] view
plain copy

 print?

BEGIN_MESSAGE_MAP(CNotifyiconDlg, CDialog)  

    //{{AFX_MSG_MAP(CNotifyiconDlg)  

                 ...  

    ON_MESSAGE(WM_USER_NOTIFYICON,OnNotifyMsg)  

    //}}AFX_MSG_MAP  

END_MESSAGE_MAP()  

iiii,在.cpp文件中添加自定义的消息响应代码,左键双击弹出应用程序主窗口,右键单击弹出菜单。

[cpp] view
plain copy

 print?

LRESULT  CNotifyiconDlg::OnNotifyMsg(WPARAM wparam,LPARAM lparam)  

//wParam接收的是图标的ID,而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_SHOW);//简单的显示主窗口完事儿     

        }     

        break;     

    }      

    return 0;  

}  

2)重载WindowProc函数

i,重载WindowProc函数(方法略)

ii,在WindowProc中增加的消息相应代码

[cpp] view
plain copy

 print?

//WindowProc中增加的代码  

LRESULT CNotifyiconDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)   

{  

    // TODO: Add your specialized code here and/or call the base class  

    switch(message) //判断消息类型  

    {   

    case WM_USER_NOTIFYICON:   

        //如果是用户定义的消息   

        if(lParam==WM_LBUTTONDBLCLK)  

              

        {   

            //鼠标双击时主窗口出现   

            if(AfxGetApp()->m_pMainWnd->IsWindowVisible()) //判断窗口当前状态  

            {  

                AfxGetApp()->m_pMainWnd->ShowWindow(SW_HIDE); //隐藏窗口  

            }  

            else  

            {  

                AfxGetApp()->m_pMainWnd->ShowWindow(SW_SHOW); //显示窗口  

            }  

              

        }   

        else if(lParam==WM_RBUTTONDOWN)  

        { //鼠标右键单击弹出选单   

            CMenu menu;   

            menu.LoadMenu(IDR_MENU1); //载入事先定义的选单   

            CMenu *pMenu=menu.GetSubMenu(0);   

            CPoint pos;   

            GetCursorPos(&pos);   

            pMenu->TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON,pos.x,pos.y,AfxGetMainWnd());   

        }   

        break;   

    case WM_SYSCOMMAND:   

        //如果是系统消息   

        if(wParam==SC_MINIMIZE)  

        {   

            //接收到最小化消息时主窗口隐藏   

            AfxGetApp()->m_pMainWnd->ShowWindow(SW_HIDE);   

            return 0;   

        }   

        if(wParam==SC_CLOSE)  

        {  

            ::Shell_NotifyIcon(NIM_DELETE,&m_notify); //关闭时删除系统托盘图标  

        }  

        break;  

    }  

    return CDialog::WindowProc(message, wParam, lParam);  

}  

        经过以上的步骤,就编写出了一个简单的可以最小化到托盘的程序。该程序在一启动时,在托盘创立应用程序的图标,最小化程序时隐藏主窗口,双击托盘区的图标时,显示主窗口,右键点击托盘区窗口时,弹出菜单。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: