MFC对象不能供多个线程使用,有可能出错,在那个线程开的变量,就应该只在那个线程内用。你应该这样,将dialog的m_hWnd传过来(通过函数参数,或用个全局量),然后用
((C??Dlg*)(CWnd::FromHandle(g_hWnd)))->UpdateData(FALSE)

解决方案 »

  1.   

    to voidman():
    用 ((C??Dlg*)(CWnd::FromHandle(g_hWnd)))->UpdateData(FALSE)
    就出现“0xxxxxx内存不能read”的错误
      

  2.   

    另外,线程函数还调用了DLL函数,这应该没关系吧
      

  3.   

    我把pdlg->UpdateData(FALSE)注释掉就没错,
    但是我要在对话框上显示,怎么办?
      

  4.   

    将UpdateData(...)干掉,改用直接操作(SetWindowText......),相信会有新的结果。试试看吧。
      

  5.   

    to neomeng(大胖) :
    “在线程里建立一个对话框的指针,在线程启动前把对话框的指针传递给线程里的指针对象。”
    ----不行
    “建立一个全局的对话框指针对象,在线程里调用也行。 ”
    ----也不行到底是什么原因不行呢?
      

  6.   

    to FrostyNeptune():
    那样就得先取得对话框中编辑框的句柄,有没有更好的方法?看来我得加分了
      

  7.   

    我也碰到过这个问题,哪怕你在主程序中加一个函数来UPDATEDATA,然后在子线程中调用此函数,也是不可行的,我是用消息发送来处理的.
      

  8.   

    想主线程发自定义消息
    主线程收到后进行updatedata操作,就这么easy
      

  9.   

    1。如果要在线程中使用MFC,则要用AfxBeginThread创建线程才行;2。在线程中用如下方法获得你的对话框指针:
    CMyDlg* pDlg = (CMyDlg *)AfxGetApp()->m_pMainWnd;
    pDlg->GetDlgItem(IDC_Edit1)->SetWindowText("OK");
      

  10.   

    alpha_segment()是对的!不过,是用AfxBeginThread还是用CreateThread创建线程没有什么区别!
    关键是在线程中获得主窗口指针只有通过AfxGetApp()->m_pMainWnd方式!调用UpdateData肯定死菜,不过你可以通过GetDlgItem方法获得控件指针来操作,
    一样达到要求!
      

  11.   

    看来我是来对了!
    这与用什么方式创建线程没有关系!
    不过不主张 使用 CreateThread()
    UpdateData()是CWnd 的一个保护成员函数,在外面是不可以调用的,自己在程序写一个消息处理函数,在处理函数中调用 UpdateData()就可以了。
      

  12.   

    那就不能用Updatedata函数把。你直接用Getdlgitem-》SetDlgItemText()方法吧,我就是这样用的。没问题。
      

  13.   

    这个错误其实是MFC在DEBUG模式下的保护性代码报错(有兴趣可以去读读代码),如果用Release模式编译和运行,以你的情况应该不会有错,只不过在逻辑上存在危险。
    我觉得更通用的方法应该是线程里面向主进程发自定义的消息来处理在wincore.cpp的886行有解释说明
    // Note: if either of the above asserts fire and you are
    // writing a multithreaded application, it is likely that
    // you have passed a C++ object from one thread to another
    // and have used that object in a way that was not intended.
    // (only simple inline wrapper functions should be used)
    //
    // In general, CWnd objects should be passed by HWND from
    // one thread to another.  The receiving thread can wrap
    // the HWND with a CWnd object by using CWnd::FromHandle.
    //
    // It is dangerous to pass C++ objects from one thread to
    // another, unless the objects are designed to be used in
    // such a manner.
      

  14.   

    to WhiteWaterBlueSky:
    为什么???
      

  15.   

    不是主线程里用AfxGetApp()->m_pMainWnd是不安全的,用GetDlgItem也不一定能取到想取的窗口,调试就看得见,取出来的窗口的一些类成员都没有赋值。多个线程操纵同一个窗口,MSDN上的建议是传递 handle ,可以用CWnd::FromHandle创建一个临时的对象,或者用CWnd::Attach产生一个永久的对象,或者是避免多个线程同时操纵同一窗口,要操作的时候向别的线程的窗口发消息。
      

  16.   


    欢迎到“VC专家答疑”提问:
    http://bros4.top263.net
      

  17.   

    to voidman():
    CWnd::FromHandle()不行啊
    我传CMyDlg *pdlg给线程,然后pdlg->SetDlgItemText()行。
    这样有什么不安全吗?
      

  18.   

    你传个HWND过去不就行了,this->m_hWnd;
    然后用CWnd::FromHandle(),就可以生成一个临时变量了
    再用SetDlgItemText()
      

  19.   

    WINAPI Func(LPVOID lpArg)
    {
    .................
    CWnd *pWnd=CWnd::FromHandle((HWND)lpArg))
    }AfxBeginThread((AFX_THREADPROC)Func,(LPVOID)this->m_hWnd);
      

  20.   

    CreateThread()的进程函数里执行fopen()不成功,是不是要用_beginthreadex()
      

  21.   

    用 ((C??Dlg::FromHandle(g_hWnd)))->UpdateData(FALSE)
      

  22.   

    xj_h():
    用你的啥都没有,没显示,也没出错我传CMyDlg *pdlg给线程,然后pdlg->SetDlgItemText(),已经搞定了。
    现在的问题是:
    线程函数调用了另外一个DLL函数,
    DLL函数读不了文件,用fopen()和CreateFile()都不能读取一个保证正确的文件
    为什么?
      

  23.   

    which DLL are u trying to use?? because some C-runtime dll's are not thread save, let us know which DLL you are trying to use..some source code would help as well...
      

  24.   

    hmm.. fopen is a C function...
      

  25.   

    If you want to do file access in win32, try the use these functionsCreateFile()
    ReadFile()
    WriteFile()you can look up MSDN on how to use these functions...
      

  26.   

    分数该给谁呢?
    提到SetDlgItemText()都得吧
      

  27.   

    我也遇到过这个问题,下面是我从一本书看到的一段话,希望对大家用点用处:
    在线程之间传递窗口、GDI对象和其他对象时应该通过句柄来代替指向MFC对象的指针进行传递。通常情况下,如果用传递句柄来代替传递指针,并且然后使用FromHandle()来在当前线程的临时句柄映射表中“重建”对象,则问题就会少一些。但是这样做并不意味着任何函数都能工作。例如:在线程中调用CMainFrame::GetActiveDocument()时,就会由于ASSERT_VALID(this)引起断言错误。ASSERT_VALID调用CWnd::AssertValid(),它通过确保相关联的HWND出现在永久或临时句柄映射表中来执行安全性检查,框架用这个映射表把HWND转换成CWnd。由一个CWnd转换成一个HWND是容易的,因为HWND是该类的一个数据成员,但是把一个HWND转换成一个CWnd,则只能通过映射表。并且这里有一个问题:句柄映射表对每个线程是局部的,并且对其他线程是不可见的。如果其地址被传给ASSERT_VALID的CWnd是另一个线程创建的,那么相应的HWND将不会出现在当前线程的永久或临时句柄映射表中,并且MFC将引发断言。许多MFC的非内联函数调用ASSERT_VALID,但内联函数不调用它。
      

  28.   

    其实很好办,你在线程的传入结构中,添加一个需要更新显示的控件的指针,如CEdit* edit,然后将该控件的地址传给这个指针,如value->edit = &m_Edit ;
    在线程里面,就可以直接用value->edit->SetWindowText()来更新显示了。有多个控件就用多个变量吧。挺好用的。