线程中是不可以调用父窗口的UpdateData,原因如下:
当创建窗口的线程和UpdateData调用所在的线程不是同一线程的时候MFC就会出错。为MFC把部分信息储存在线程的TLS中,这些信息对于MFC的执行非常重要,因此MFC会在很多代码里面检查线程状态是否正确。当在线程中调用父窗口的UpdateData时,相对于UpdateData的线程环境已经改变了,所以就会出错了。
可以使用如下方案:
1,在线程中使用 pDLG->GetDlgItem(ID)->SetWindowText(str)
2,线程向父对话框发送自定义消息,消息响应函数里调用UpDateData,该方案详见:
- 在randomDlg.h
- //定义用户消息,不可与系统消息冲突,所以就这样定义
- //WM+USER表示用户消息,加100还是加其他值并没多大区别的
- #define WM_MYUPDATEDATA WM_USER+100
- 在线程内
- //向主程序框架MainFrm发送消息
- //SendMessage第二第三参数可以为其他更多的类型,不局限于此
- DWORD RondomLeftThread(CRandomDlg *p)
- {
- p->SendMessage(WM_MYUPDATEDATA,FALSE);
- }
- //调用线程的地方
- hThread_1=CreateThread(NULL,
- 0,
- (LPTHREAD_START_ROUTINE)RondomLeftThread,
- this,
- 0,
- (unsigned long *)&ThreadID);
- 在randomDlg.cpp内
- //关联自定义消息
- BEGIN_MESSAGE_MAP(CRandomDlg, CDialog)
- //{{AFX_MSG_MAP(CRandomDlg)
- ON_WM_PAINT()
- ON_WM_QUERYDRAGICON()
- ON_MESSAGE(WM_MYUPDATEDATA,OnUpdateMyData)
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
- 定义OnUpdateMyData
- class CRandomDlg : public CDialog
- {
- // Construction
- public:
- CRandomDlg(CWnd* pParent = NULL); // standard constructor
- // Dialog Data
- //{{AFX_DATA(CRandomDlg)
- enum { IDD = IDD_RANDOM_DIALOG };
- HANDLE hThread_1;
- HANDLE hThread_2;
- //}}AFX_DATA
- // ClassWizard generated virtual function overrides
- //{{AFX_VIRTUAL(CRandomDlg)
- protected:
- virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
- //}}AFX_VIRTUAL
- // Implementation
- protected:
- HICON m_hIcon;
- // Generated message map functions
- //{{AFX_MSG(CRandomDlg)
- virtual BOOL OnInitDialog();
- afx_msg void OnPaint();
- afx_msg HCURSOR OnQueryDragIcon();
- LRESULT OnUpdateMyData(WPARAM wParam, LPARAM lParam);
- //}}AFX_MSG
- DECLARE_MESSAGE_MAP()
- public:
- void EnableDisplay(int,BOOL);
- };
- 实现OnUpdateMyData
- LRESULT CRandomDlg::OnUpdateMyData(WPARAM wParam, LPARAM lParam)
- {
- UpdateData(wParam);
- return 1;
- }
评论