据书上说,CWnd,CDC,CMenu,CGdiObject及其派生类只能由生成该对象的线程来访问,在线程间传递的时候应该传递句柄,然后用FromHandle来生成自己的对象。 
我自己编了个程序(vc6)试了一下,很奇怪并不是这样,清高手指教。 我得程序是基于对话框的普通mfc程序,实现对话框的类是CTestThreadDlg, 
对话框上我安了两个控件   ,一个编辑框(IDC_EDIT1),一个button(IDC_BUTTON1), 
同时在对话框类(CTestThreadDlg)中添加了一个public访问的成员变量m_var, 代码如下: 
//   TestThreadDlg.cpp 
  ... 
  UINT   ThreadFunc(LPVOID   p)   //   线程函数,p将要接受CTestThreadDlg对象得指针 
  { 
                  ASSERT(p   !=   NULL); 
                  //   ((CEdit   *)p)-> SetWindowText( "lala "); 
                  (CTestThreadDlg*)p)-> SetDlgItemText(IDC_EDIT1,   "HAHA ");   //   ---(1) 
                  ((CTestThreadDlg*)p)-> m_var   =   8;   //   --------------------------(2) 
                  return   0; 
  } 
  void   CTestThreadDlg::OnButton1()   //   单击button(IDC_BUTTON1)的响应函数 
  { 
                  //   TODO:   Add   your   control   notification   handler   code   here 
                  AfxBeginThread(ThreadFunc,   this); 
                  Sleep(100); 
                  int   ret   =   m_var; 
  } 
  让我奇怪的是单击button后,编辑框(IDC_EDIT1)马上显示了“HAHA”,同时通过调试也发现了CTestThreadDlg::m_var值变成了8,也就是说,语句(1)、(2)有效,太奇怪了!(本来觉得(1)、(2)不会有效,因为在线程间传递的时候应该传递句柄)不知什么原因? 
--------------------------------
书上说,不要在线程间传递MFC对象。1:
但是我试了无数遍的,在主线程中传递this指针(主对话框指针),到工作线程中,
然后 
pDlg=(CMainDlg *)this;
pDlg->m_number++;
用pDlg访问对话框内的自定义的成员变量,根本不出错。2:
当然updateData()是不能访问的。请问各位在商业软件开发中,你们这样用过吗(如1),1中这样是安全的吧?
我觉得同一个进程内的,不同线程之间传递this指针(主对话框指针),然后访问对话框的成员变量(类型非MFC),是不会出错的

解决方案 »

  1.   

    SetWindowText causes a WM_SETTEXT message to be sent to the specified window or control。
    你的工作线程并没有直接操作gdi,而是发消息,UI线程处理的。1,pDlg->m_number++;
    这个访问根本就和 gdi 没关系了,和普通对象一样。
    不过跟楼主说下,m_number++;并不是原子操作,多线程要同步的,不然可能少加
      

  2.   

    线程中不要直接操作UI界面上的控件,改用发送自定义消息到UI线程,在UI线程的自定义消息响应函数中去更新控件的信息~
      

  3.   

    理论上将,“CWnd,CDC,CMenu,CGdiObject及其派生类只能由生成该对象的线程来访问”是不准确的。线程间是共享同一个地址空间的,所以要跨线程访问这类对象,是“能”的。但是,这些类在设计的时候并没有考虑线程安全问题,所以在多个线程中并发访问的时候,很可能出问题,所以不建议这么用。一定要用的话,自己加一层同步机制来做访问冲突保护,也未尝不可,只是舍近求远而已。而像你这样弄一个简单的例子来跑,很可能因为并没有发生真正的访问冲突,所以貌似没有问题。但这并不能说明这种编程方式是正确的。
    ————————————————————————————————
    基于CSDN论坛提供的插件扩展功能,自己做了个签名档工具,分享给大家,欢迎技术交流 :)
      

  4.   

    传句柄是线程安全的,通过句柄发送窗口消息或线程消息。不要传MFC对象指针,MSDN明确说,对象指针不是线程安全的