• MFC实现窗口关闭为最小化托盘


    新建一个 MinTray 的MFC工程(基于Dialog),
    在 MinTrayDlg.h 头文件中,自定义消息 WM_SHOWTASK

    ////////////////// MinTrayDlg.h   ///////////////
    #pragma once
    #define WM_SHOWTASK (WM_USER +1) //自定义消息WM_SHOWTASK
    
    //添加成员函数
    class CMinTrayDlg : public CDialogEx
    {
       //....
        afx_msg LRESULT OnShowTask(WPARAM wParam, LPARAM lParam);//wParam接收的是图标的ID,而lParam接收的是鼠标的行为
        //1、最小化的原理:首先要将窗口隐藏,然后在右下角绘制图标。
        //2、恢复的原理:将窗口显示,再将托盘中的图片删除。
        void ToTray();//最小化窗口到托盘
        void DeleteTray();////删除托盘图标函数   
    }

    在 MinTrayDlg.cpp 中

    // MinTrayDlg.cpp : 实现文件
    
    BEGIN_MESSAGE_MAP(CMinTrayDlg, CDialogEx)
        ON_WM_SYSCOMMAND()
        ON_WM_PAINT()
        ON_WM_QUERYDRAGICON()
        ON_MESSAGE(WM_SHOWTASK, OnShowTask) //其中WM_SHOWTASK是消息名,OnShowTask是自己定义的消息响应函数
    
    END_MESSAGE_MAP()
    
    
    
    void CMinTrayDlg::OnSysCommand(UINT nID, LPARAM lParam)
    {
        if ((nID & 0xFFF0) == IDM_ABOUTBOX)
        {
            CAboutDlg dlgAbout;
            dlgAbout.DoModal();
        }
        else if (nID == SC_CLOSE)//右上角的关闭和标题栏的关闭WM_CLOSE
        {
            ToTray();//最小化到托盘
        }
        else
        {
            CDialogEx::OnSysCommand(nID, lParam);
        }
    }
    
    LRESULT CMinTrayDlg::OnShowTask(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();//声明一个弹出式菜单
            menu.AppendMenu(MF_STRING, WM_DESTROY, L"关闭"); //增加菜单项“关闭”,点击则发送消息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);//简单的显示主窗口完事儿
            DeleteTray();
        } break;
        default: break;
        }
        return 0;
    }
    
    //最小化窗口到托盘
    void CMinTrayDlg::ToTray()
    {
        NOTIFYICONDATA nid;
        nid.cbSize = (DWORD)sizeof(NOTIFYICONDATA);
        nid.hWnd = this->m_hWnd;
        nid.uID = IDR_MAINFRAME;
        nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
        nid.uCallbackMessage = WM_SHOWTASK;//自定义的消息名称
        nid.hIcon = LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MAINFRAME));
        wcscpy(nid.szTip, L"程序名称"); //信息提示条
        Shell_NotifyIcon(NIM_ADD, &nid); //在托盘区添加图标
        ShowWindow(SW_HIDE); //隐藏主窗口
    }
    
    //删除托盘图标函数
    void CMinTrayDlg::DeleteTray()
    {
        NOTIFYICONDATA nid;
        nid.cbSize = (DWORD)sizeof(NOTIFYICONDATA);
        nid.hWnd = this->m_hWnd;
        nid.uID = IDR_MAINFRAME;
        nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
        nid.uCallbackMessage = WM_SHOWTASK; //自定义的消息名称
        nid.hIcon = LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MAINFRAME));
        wcscpy(nid.szTip, L"程序名称"); //信息提示条为“计划任务提醒”
        Shell_NotifyIcon(NIM_DELETE, &nid); //在托盘区删除图标
    }

    另外:MFC中屏蔽 Esc 和 Enter 关闭窗口(由于Esc直接调用 OnCancel(),Enter 直接调用 OnOk())

    方法一:

    在头文件中

    protected:
         virtual BOOL PreTranslateMessage(MSG* pMsg);  // PreTranslateMessage是消息在送给TranslateMessage函数之前被调用的
    public:
         virtual void OnOK();

    在cpp文件中

    BOOL CxxxDlg::PreTranslateMessage(MSG* pMsg)
    {
        //屏蔽ESC关闭窗体/
        if(pMsg->message==WM_KEYDOWN && pMsg->wParam==VK_ESCAPE ) return TRUE;
        //屏蔽回车关闭窗体,但会导致回车在窗体上失效.
        //if(pMsg->message==WM_KEYDOWN && pMsg->wParam==VK_RETURN && pMsg->wParam) return TRUE;
        else
            return CDialog::PreTranslateMessage(pMsg);
    }
    void CxxxDlg::OnOK()
    {
        //CDialogEx::OnOK();
    }

    方法二:

    //////////////////  头文件  /////////
    
    public:
        virtual void OnOK();
        virtual void OnCancel();
        afx_msg void OnClose(); //响应关闭事件!
    
    
    /////////////// cpp文件  /////////////////
    void CxxxDlg::OnOK()
    {
        return;
    }
    void CxxxDlg::OnCancel()
    {
        return;
    }
    void CxxxDlg::OnClose()
    {
        // TODO:  在此添加消息处理程序代码和/或调用默认值
        
        CDialogEx::OnCancel();
        //CDialogEx::OnClose();
    }

    常记溪亭日暮,沉醉不知归路。兴尽晚回舟,误入藕花深处。争渡,争渡,惊起一滩鸥鹭。

    昨夜雨疏风骤,浓睡不消残酒。试问卷帘人,却道海棠依旧。知否?知否?应是绿肥红瘦。
  • 相关阅读:
    2018 ACM-ICPC World Finals Problem D. Gem Island(递推)
    2016-2017 ACM-ICPC Northeastern European Regional Contest Problem C. Cactus Construction(仙人掌+构造)
    JZOJ 6997. 2021.03.06【2021省赛模拟】排列(最小树形图)
    JZOJ 6653. 【2020.05.27省选模拟】树(权值线段树)
    JZOJ 6652. 【2020.05.27省选模拟】序列(贪心+序列翻转)
    JZOJ 6979. 【2021.02.03冬令营模拟】天各一方(DP)
    MyBatisPlus使用Version注解(乐观锁)
    并行库parallelStream设置并行数量
    PHPUnit漏洞复现
    使用云函数隐藏C2服务器
  • 原文地址:https://www.cnblogs.com/htj10/p/11688347.html
Copyright © 2020-2023  润新知