posted at 2016-10-30 11:50:27 +0000
最近在写贴吧分布式爬虫项目的客户端,采用了MFC来写。
其中需要后台连接服务器更新在线爬虫列表。这里使用多线程是肯定的,但是如何实现在工作线程里操作主对话框里的数据。
当时想的是在开辟新线程的时候,将主对话框的this指针传递给子线程。
但事实证明,在VS 2015环境下,这种方法并不行,会引发运行时错误(Assertion Failed)。
后面在网上查了一翻关于MFC子线程如何操作主对话框数据的资料,了解到,可以通过在子线程里面传递消息来实现。但是原文里面的方法,在消息映射那里并不行。
后来在MSDN上查了下,终于正确实现子线程传递消息到主对话框,然后,调用相应的函数更新数据。
首先,我们要自定义一个我们要传递的消息,在对话框类的头文件中声明:
#define WM_MY_MESSAGE WM_USER+100
//根据MSDN
//函数原型必须如下(对于ON_MESSAGE来说):
afx_msg LRESULT OnMyMessage(WPARAM, LPARAM) {
//在这里添加处理方法
}
紧接着,我们需要在相应源文件中的消息映射里面添加对应的消息映射,把我们刚刚自定义的消息映射到那个函数去:
BEGIN_MESSAGE_MAP(CLmsTestDlg, CDialog)
ON_MESSAGE(WM_MY_MESSAGE,OnMyMessage) //这是我们添加的消息映射
//消息映射一定要添加到BEGIN_MESSAGE_MAP和END_MESSAGE_MAP之间
END_MESSAGE_MAP()
然后,我们在线程函数里面调用PostMessage方法传递消息即可:
//线程函数
UINT myThreadProc(LPRARM lPram) {
WHAND whand = (WHAND)lPram; //由于PostMessage第一个参数为窗口句柄,所以我们要得到主窗口句柄
::PostMessage(whand,WM_MY_MESSAGE,NULL,NULL); //传递消息
}
在线程函数里面,我们需要传递一个主窗口句柄给PostMessage
函数,所以,在调用AfxBeginThread
的时候,我们需要传递主窗口的句柄给它。可以通过以下方法获取主窗口句柄:
//在任何位置都可以通过这个方法来取得主窗口句柄
AfxGetMainWnd()->m_hWnd;
参考:
MSDN:https://msdn.microsoft.com/zh-cn/library/k35k2bfs.aspx
CSDN BLOG:http://blog.csdn.net/npu_wy/article/details/28625085
© kanch
→ zl AT kanchz DOT com
last updated on 2022-07-27 01:57:54 +0000