hcnak.blog

posted at 2016-10-30 11:50:27 +0000

MFC自定义消息传递,实现子线程更新主窗口数据

最近在写贴吧分布式爬虫项目的客户端,采用了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



© kanchzl AT kanchz DOT com

last updated on 2022-07-27 01:57:54 +0000