MFC非模态添加进程控件方法一(线程方法)

Posted luxingsh

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MFC非模态添加进程控件方法一(线程方法)相关的知识,希望对你有一定的参考价值。

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

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

技术分享图片
void CModelessDlg::OnBnClickedOk()
{
    DLGModeLess *pDlg = new DLGModeLess();
    pDlg->Create(IDD_DG_MODLESS, NULL);
    pDlg->ShowWindow(SW_SHOW);
    pDlg->m_Progress1.SetRange(1, 100);
    pDlg->m_Progress1.SetStep(1);
    for (int i = 0; i<100; i++)
    {
        pDlg->m_Progress1.StepIt();
        Sleep(100);
    }
    // TODO: 在此添加控件通知处理程序代码
    //CDialogEx::OnOK();
}
View Code

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

void CModelessDlg::OnBnClickedOk()
{
    AfxBeginThread((AFX_THREADPROC)MyThreadExample, 0, THREAD_PRIORITY_IDLE);
    // TODO: 在此添加控件通知处理程序代码
    //CDialogEx::OnOK();
}

 

UINT MyThreadExample(LPVOID *pParam)
{
    DLGModeLess *pDlg = new DLGModeLess();
    pDlg->Create(IDD_DG_MODLESS, NULL);
    pDlg->ShowWindow(SW_SHOW);
    pDlg->m_Progress1.SetRange(1, 100);
    pDlg->m_Progress1.SetStep(1);
    for (int i = 0; i<100; i++)
    {
        pDlg->m_Progress1.StepIt();
        Sleep(100);
    }
    return 0;
}

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

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

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

DLGModeLess *pDlg = new DLGModeLess();//全局新建非模态窗口指针。

// CModelessDlg 对话框
UINT MyThreadExample(LPVOID *pParam)
{
    pDlg->m_Progress1.SetRange(1, 100);
    pDlg->m_Progress1.SetStep(1);
    for (int i = 0; i<100; i++)
    {
        pDlg->m_Progress1.StepIt();
        Sleep(100);
    }
    pDlg->ShowWindow(false);
    return 1;
}


CModelessDlg::CModelessDlg(CWnd* pParent /*=nullptr*/)
    : CDialogEx(IDD_MODELESS_DIALOG, pParent)
{
    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
    pDlg->Create(IDD_DG_MODLESS, NULL); //构造函数里面创造程序,按钮响应,避免多次创建
}
void CModelessDlg::OnBnClickedOk() //按键响应事件
{
    //if (pDlg->GetDlgItem(IDD_DG_MODLESS));
    CWnd* pWnd = GetDlgItem(IDD_DG_MODLESS);
    
    pDlg->ShowWindow(SW_SHOW);
    AfxBeginThread((AFX_THREADPROC)MyThreadExample, 0, THREAD_PRIORITY_IDLE);
    // TODO: 在此添加控件通知处理程序代码
    //CDialogEx::OnOK();
}

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

技术分享图片

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

技术分享图片

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

技术分享图片

 

以上是关于MFC非模态添加进程控件方法一(线程方法)的主要内容,如果未能解决你的问题,请参考以下文章

《深入浅出MFC》第十四章 多线程程序设计

mfc非模态对话框

MFC入门

MFC编程 | 非模态对话框的定义

VS2017 MFC应用中添加模态对话框时为其添加类弹出如下错误

MFC如何选中combo box的一个内容,将这个内容显示在edit中?请高手指点?