zoukankan      html  css  js  c++  java
  • 线程调用UpdateData函数出错

    在尝试线程更新界面时,在线程中调用UpdateData(FALSE)后出现如下错误:

    原因:

      MFC对象不支持多线程操作,不能供多个线程进程使用。子线程调用pDlg-> UpdateData(FALSE)时主线程(界面线程)会阻塞,更新必须由它完成,这样就形成死锁。UpdateData()函数属于CDialog类的保护成员函数,在工作线程中不能使用UpdateData来更新主线程中的数据。更改界面的操作最好用主线程(界面线程),要想在子线程(工作线程)里执行界面线程的操作,可以通过向主线程发送消息来解决。

    解决办法:

    1. 创建线程时使用AfxBeginThread创建CWinThread继承类,参数传递时最好传递窗口句柄(主线程向子线程传递对象不安全),使用PostMessage或SendMessage消息传递函数向主窗口发送自定义消息,在主窗口中对自定义消息进行处理并更新。

    创建线程:

    void CEditTestDlg::OnBnClickedButton4()
    {
        CWinThread* pThread;
        pThread = AfxBeginThread(SendMsgThread,this);
    }

    发送消息(推荐使用SendMessageTimeout):

    static UINT SendMsgThread(LPVOID lpParam)
    {
        CEditTestDlg *dlg = (CEditTestDlg*) lpParam;
        int i = 0;
        while (i < 100)
        {
            Sleep(20);
            i += 1;
            dlg->m_value2.Format(_T("%d"), i);
            //PostMessage(dlg->m_hWnd,WM_UPDATEDATA,FALSE,NULL);
            //SendMessage(dlg->m_hWnd,WM_UPDATEDATA,FALSE,NULL);
            SendMessageTimeout(dlg->m_hWnd, WM_UPDATEDATA, FALSE, NULL, SMTO_BLOCK, 1000, NULL);
        }
        return 0;
    }

    消息处理:

    LRESULT CEditTestDlg::OnUpdateData(WPARAM wParam, LPARAM lParam)
    {
        UpdateData(wParam);
        return 0;
    }

    2. 使用control变量或直接获取控件指针进行更新:

    dlg->m_editCtl.SetWindowText(dlg->m_value2);
    dlg->GetDlgItem(IDC_EDIT2)->SetWindowText(dlg->m_value2);

    3. 最简单的办法,将Debug改为Release正常运行。

     

     相关内容请查看:MFC添加自定义消息

     

  • 相关阅读:
    Maximum sum
    走出迷宫
    取石子游戏
    全排列
    BZOJ3456 城市规划
    【SHOI2016】黑暗前的幻想乡
    【AHOI2012】信号塔
    HDU5730 Shell Necklace
    线性常系数齐次递推关系学习笔记
    矩阵树定理学习笔记
  • 原文地址:https://www.cnblogs.com/skywatcher/p/3506045.html
Copyright © 2011-2022 走看看