由于非模态对话框的自己没有消息循环,创建后无法进行消息处理。需要和父窗口共用消息循环。如果单独在子窗口进行控件由于自己没有单独的消息循环,更新是无法进行的。

如果在父窗口更新控件会造成程序假死。如以下代码在主窗口更新子窗口消息,界面进入假死状态。因为主界面对主进程进行了sleep(100),如下代码所示

  1. void CModelessDlg::OnBnClickedOk()
  2. {
  3. DLGModeLess *pDlg = new DLGModeLess();
  4. pDlg->Create(IDD_DG_MODLESS, NULL);
  5. pDlg->ShowWindow(SW_SHOW);
  6. pDlg->m_Progress1.SetRange(, );
  7. pDlg->m_Progress1.SetStep();
  8. for (int i = ; i<; i++)
  9. {
  10. pDlg->m_Progress1.StepIt();
  11. Sleep();
  12. }
  13. // TODO: 在此添加控件通知处理程序代码
  14. //CDialogEx::OnOK();
  15. }

在主窗口尝试开一个线程来更新控件

  1. void CModelessDlg::OnBnClickedOk()
  2. {
  3. AfxBeginThread((AFX_THREADPROC)MyThreadExample, , THREAD_PRIORITY_IDLE);
  4. // TODO: 在此添加控件通知处理程序代码
  5. //CDialogEx::OnOK();
  6. }
  1. UINT MyThreadExample(LPVOID *pParam)
  2. {
  3. DLGModeLess *pDlg = new DLGModeLess();
  4. pDlg->Create(IDD_DG_MODLESS, NULL);
  5. pDlg->ShowWindow(SW_SHOW);
  6. pDlg->m_Progress1.SetRange(, );
  7. pDlg->m_Progress1.SetStep();
  8. for (int i = ; i<; i++)
  9. {
  10. pDlg->m_Progress1.StepIt();
  11. Sleep();
  12. }
  13. return ;
  14. }

发现这样开线程后,子窗口直接假死都不可以移动了!

我发现在子线程直接开窗口这样做似乎有点愚蠢,这似乎是让整个程序一直跑在子窗口里面,同时还SLEEP(100)和上面在主程序更新一样,同样造成了程序假死。而且是停留在子窗口的假死。

为了不这么愚蠢,我把程序更改如下。创建了一个全局模态窗口的指针,同时在构造函数里面创建了该窗口,然后在按钮事件处响应。在线程处隐藏。这样就可以避免多次创建子窗口。

  1. DLGModeLess *pDlg = new DLGModeLess();//全局新建非模态窗口指针。
  2.  
  3. // CModelessDlg 对话框
  4. UINT MyThreadExample(LPVOID *pParam)
  5. {
  6. pDlg->m_Progress1.SetRange(, );
  7. pDlg->m_Progress1.SetStep();
  8. for (int i = ; i<; i++)
  9. {
  10. pDlg->m_Progress1.StepIt();
  11. Sleep();
  12. }
  13. pDlg->ShowWindow(false);
  14. return ;
  15. }
  16.  
  17. CModelessDlg::CModelessDlg(CWnd* pParent /*=nullptr*/)
  18. : CDialogEx(IDD_MODELESS_DIALOG, pParent)
  19. {
  20. m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  21. pDlg->Create(IDD_DG_MODLESS, NULL); //构造函数里面创造程序,按钮响应,避免多次创建
  22. }
  1. void CModelessDlg::OnBnClickedOk() //按键响应事件
  2. {
  3. //if (pDlg->GetDlgItem(IDD_DG_MODLESS));
  4. CWnd* pWnd = GetDlgItem(IDD_DG_MODLESS);
  5.  
  6. pDlg->ShowWindow(SW_SHOW);
  7. AfxBeginThread((AFX_THREADPROC)MyThreadExample, , THREAD_PRIORITY_IDLE);
  8. // TODO: 在此添加控件通知处理程序代码
  9. //CDialogEx::OnOK();
  10. }

经过这样的处理之后,我就可以很自在的在非模态窗口中更新进程控件。

跟新的同时可以随便移动子窗口。

更新完成后,由pDlg->ShowWindow(false);线程函数隐藏。

MFC非模态添加进程控件方法一(线程方法)的更多相关文章

  1. MFC非模态添加进程控件方法二(自定义消息方法)

    以下内容有大部分转载自CSDN,经过自己整理完成. 该文主要的方法为在非模态对话框中自定义一组消息函数,然后在主窗口中开辟一个线程通过线程把消息传递给子窗口进行更新. 在子窗口类中定义消息如下: /* ...

  2. mfc非模态对话框

    按照我们的之前的做法,先新建工程. 把基本的内容都添加上. 形成这样一个样子: 并且进行试运行,让程序能够完成加法运算. 值的注意的是,静态文本那里要改一下名字,否则无法将成员变量进行添加. 前期准备 ...

  3. MFC非模态对话框中屏蔽ESC键

    个人的编程经验认为:对于非模态对话框,按下ESC键和点击红叉都会响应OnCancel()函数,而不会去响应OnClose()函数. 我们都知道,如果想屏蔽Enter键,只须重写OnOK()函数即可(重 ...

  4. MFC非模态对话框销毁

    非模态对话框需要重载OnCanel方法, 并调用DestroyWindow, 且不能调用基类的OnCanel重载PostNcDestroy, 需要delete掉this指针 // Overrides  ...

  5. VS2010 MFC中 单独添加ODBC数据库记录集类(CRecordset)方法

    基于VS2010 MFC的项目是之前建好的,后来需要添加数据库. 方法分享于此. 1.  打开自己的项目,项目->添加类. 2. 选MFC ODBC使用者,点右下角的添加. 3. 点数据源. / ...

  6. objectarx MFC 非模态对话框为当前焦点

    dialog.h afx_msg LRESULT OnAcadKeepFocus(WPARAM, LPARAM); dialog.cpp BEGIN_MESSAGE_MAP(CTextDialog, ...

  7. 十三、$.ajax、模态/非模态框、window.open()、href属性、submit()等提交请求优劣及问题解决方法

    1. $.ajax提交请求进行数据更新,并通过回调进行有效提示 function updateAudit(dispacher, control) { var currentpage = documen ...

  8. 控制非模态弹出框(showModelessDialog)唯一且随父页面关闭

    网站开发中,常常会遇到需要弹出窗体的情况,一般弹出框有模态和非模态两种,如下: 模态:window.showModalDialog() 非模态:window.showModelessDialog() ...

  9. 添加RichEdit控件后导致MFC对话框程序无法运行的解决方法

    新建一个基于对话框的MFC程序,对话框上添加了RichEdit控件,编译成功后无法运行起来,Debug版本与Release版本均不行! Windbg分析结果: WARNING: Stack unwin ...

随机推荐

  1. 【Leetcode】【Medium】Word Break

    Given a string s and a dictionary of words dict, determine if s can be segmented into a space-separa ...

  2. jbd2/dm-2-8 io太高

    用iotop查看发现[jbd2/dm-2-8]几乎占用了99%的io使用率,但是却没有输入输出 后来上网查找,网上有人说是个内核bug,需要升级内核,或者降低jdb2的提交次数,即重新挂载磁盘 添加c ...

  3. 删除datatable的行后,出现“不能通过已删除的行访问该行的信息”的错误,即DeletedRowInaccessibleException

    删除datatable的行后,出现“不能通过已删除的行访问该行的信息”的错误 =========================================================== 采 ...

  4. CentOS 6 网络yum源配置

    # CentOS-Base.repo## The mirror system uses the connecting IP address of the client and the# update ...

  5. 使用c++11写个最简跨平台线程池

    为什么需要多线程? 最简单的多线程长啥样? 为什么需要线程池,有什么问题? 实现的主要原理是什么? 带着这几个问题,我们依次展开. 1.为什么需要多线程? 大部分程序毕竟都不是计算密集型的,简单的说, ...

  6. UVa 580 - Critical Mass(递推)

    链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  7. vim命令set nu

    set nu:为vim设置行号 set nonu:取消vim中的行号

  8. Spring(十九)之异常处理

    异常处理,对于项目开发至关重要,总不能用户点击一个页面出错了,直接报500,那样用户体验多不好啊! 所以这里讲的是SpringMVC对异常的处理,希望能给大家带来一定的 帮助和启发. 一.编写实体 p ...

  9. Page Object设计模式(项目整体结构)

    1. 什么是框架 1.1 定义: 框架(Framework)是整个或部分系统的可重用设计,表现为一组抽象构件(类)及构件(类)实例间交互的方法. 1.2 为什么要搭建自动化测试框架 自动化测试的开发, ...

  10. C#一键显示及杀死占用端口号进程

    private void t_btn_kill_Click(object sender, EventArgs e) { int port; bool b = int.TryParse(t_txt_gu ...