• 隐藏基于Dialog的MFC的主窗体


      最近需要做一个主窗体常态隐藏的程序,类似360卫士那样,只有托盘图标常显示。本以为隐藏主窗体很简单,但遇到了意想不到的情况。

    无效的做法

      最初的想法是设置主对话框资源的 Visiable 属性为 false, 并在OnInitDialog函数里调用 ShowWindow(SW_HIDE) ,发现这些操作根本没有作用,对话框还是好好的显示在那里。开始还以为是改错了项目,或者当前启动项目设置错了,检查了一遍,确认没错,只好开始百度。

      最初发现的解决方法是在OnInitDialog函数中执行以下代码:

    SetWindowPos(&wndNoTopMost,0,0,0,0,SWP_HIDEWINDOW); 
    ModifyStyleEx(WS_EX_APPWINDOW,WS_EX_TOOLWINDOW);//移除任务栏图标显示
    ShowWindow(SW_HIDE);

      结果是窗体的大部分隐藏了,还剩了点没隐藏,就是下图这个要死不活的样子

      

      既然还剩了一部分,那我就把对话框资源的 Caption 属性为空,SystemMenu属性设置为false,结果文字和关闭按钮确实都不见了,但还是剩下了一些东西,就是下图中的小长条

      只能继续研究。

    有效的做法

      1 将界面像素置为0,移动界面至屏幕角落

        int nFullWidth = GetSystemMetrics(SM_CXSCREEN);
        int nFullHeight = GetSystemMetrics(SM_CYSCREEN);
        SetWindowPos(NULL, nFullWidth, nFullHeight, 0, 0, SWP_NOZORDER);  //设置0像素,移到最角落  或者:MoveWindow(0,0,0,0);
        ShowWindow(SW_HIDE);
        ModifyStyleEx(WS_EX_APPWINDOW, WS_EX_TOOLWINDOW);  //移除任务栏图标显示

      这种做法只是将上述的小长条移到了不易看到的地方,用户一旦操作界面的任一部位,窗口都会因为失活而不再显示,达到了隐藏界面的目的。但是这种做法明显属于凑合,而且一旦需要显示主界面,还需要将对话框的类型改回来,不能为工具窗口,否则任务栏不显示。

      2 采用定时器,在窗口初始化完成后马上隐藏

      在OnInitDialog中创建一个定时器SetTimer(1,1,NULL);

      然后在OnTimer函数中调用ShowWindow(SW_HIDE)

      这种做法的缺点就是窗口会闪烁一次,而且这种手法太野路子,不优雅。

      

      3 响应WM_NCPAINT消息

       在第一次处理WM_NCPAINT消息是,调用ShowWindow(SW_HIDE)方法,之所以只调用一次,是为了之后可以将主窗口再显示出来。

       这种方法比较优雅,推荐采用

    void CMFCApplication1Dlg::OnNcPaint()
    {
        // TODO: 在此处添加消息处理程序代码
        static bool bNotPaint = true;
        if (bNotPaint)
        {
            ShowWindow(SW_HIDE);
            bNotPaint = false;
        }
        else
        {
            CDialogEx::OnNcPaint();
        }
    }

        

      4 改变主窗体的创建方式

        将 C***App::InitInstance() 函数中的代码

    CMFCApplication1Dlg dlg;
    m_pMainWnd = &dlg;
    INT_PTR nResponse = dlg.DoModal();

      替换为

    CMFCApplication1Dlg dlg;
    m_pMainWnd = &dlg;
    //INT_PTR nResponse = dlg.DoModal();
    INT_PTR nResponse = dlg.Create(CMFCApplication1Dlg::IDD);
    dlg.ShowWindow(SW_HIDE);
    dlg.RunModalLoop();  

      同样比较优雅,推荐使用

      综上所述,由于CDialog的创建隐藏了太多细节,只有弄清楚基于Dialog的窗体的创建方式、绘制时机、消息循环方式才能够优雅的实现功能,当然,我还没有弄明白。

  • 相关阅读:
    bootstrap之Click大事
    BZOJ 2878([Noi2012]-失落的游乐园树DP+出站年轮加+后市展望DP+vector的erase)
    cocos2d 消除类游戏简单的算法 (一)
    【BZOJ3627】【JLOI2014】路径规划 分层图
    Windows台cocos2d-x 3.2下载一个新的项目,创造的过程
    无插件,直接加参数,chrome它可以模拟手机浏览器
    unix您不能使用crontab设置运营计划
    LeetCode36:Valid Sudoku
    HDInsight HBase概观
    最受欢迎telnet
  • 原文地址:https://www.cnblogs.com/canger/p/6647281.html
Copyright © 2020-2023  润新知