窗口和线程漫谈之工作线程如何将数据的处理结果显示到窗口

原创 2015年07月08日 15:54:26

前言

原本这篇博客的标题叫《窗口和线程漫谈》,但想来想去确实不太合适,因为我确实没有写关于窗口和线程的任何理论知识,而只是探讨了工作线程如何将数据的处理结果显示到窗口这个问题,因此重新修改标题。

另外,关于窗口和线程的相关理论知识,感觉一两句话确实说不清楚,而且《Windows 核心编程》这本书上介绍的也挺好的,有机会再写吧。特别是感觉现在好多人都直接在学 MFC,用 MFC,甚至连窗口过程,消息循环都不太明白,如果能有这样一篇博客也是很有价值的。

为什么要讨论这个问题

讨论这个依然是跟之前的项目经历有关。这里暂且称该项目为 A 项目。A 项目包括一个客户端和服务端,客户端有一个核心的网络模块,该网络模块基于完成端口开发,有多个工作线程,网络模块负责接收来自服务端的数据,对这些数据进行处理,并将最终的处理结果显示在窗口上。那么问题来了,工作线程如何将数据的最终处理结果显示在窗口上?可以说这个问题不仅仅是 A 项目中遇到的问题,绝大多数网络应用程序都会遇到这个问题。当时 A 项目中采用的方案是在工作线程中利用窗口句柄直接调用相应函数(如 SendMessage)对窗口进行操作。虽然这种做法当时并没有出现问题?但它真的没问题吗?如果有问题,我们该采用什么方式将最终的处理结果显示在窗口上呢?

窗口和线程的关系

理论知识是我们回答上述问题的基础。这方面我找到的唯一资料就是 《Windows 核心编程》 第 26 章 窗口消息。对这块不太明白的兄弟,可以先看下。这里我们就不详述了。

在工作线程中利用窗口句柄直接调用相应函数对窗口进行操作这种做法有没有问题

绝大多数情况下,确实不会出现问题。但只是绝大多数情况下,下面是出现问题的两种情况。

  1. 这种情况是我在项目 A 中亲身经历的。当时我在工作线程中调用了 SetFocus 这个函数,结果这个函数并没有成功返回,为什么?下面是 SetFocus 文档中的描述。

    Sets the keyboard focus to the specified window. The window must be attached to the calling thread’s message queue.

    原因很明显,传递给 SetFocus 函数的窗口句柄代表的窗口必须是属于调用 SetFocus 函数的这个线程的,但工作线程并没拥有该窗口,也没有拥有任何窗口。那为什么调用 SetFoucs 函数要有这个需求呢?这个只能说我也不太清楚,但结合 《Windows 核心编程》 第 26 章 中的相关描述,每一个线程都拥有自己的键盘焦点,应该在一定程度上回答了这个问题。

  2. 这种情况是《多线程编程中的主界面安全处理》这篇文章中提到的,大致情况就是拥有窗口的线程正在等待工作线程退出,而工作线程正阻塞于对窗口的 SendMessage 调用中。应该说,这种情况不是没有可能发生。

说了这么多,说到底我是不建议在工作线程中利用窗口句柄直接调用相关函数对窗口进程操作这种做法的,虽然这种做法绝大多数情况下不会出错,但一旦出现问题,排查起来就比较困难。但我也不完全否认这种做法,前提是,程序员自身一定要对程序本身的逻辑认识清楚,比如在工作线程中会不会调用类似 SetFocus 的这类函数,会不会出现上面提到的第二种情况。

工作线程如何将最终的处理结果显示到窗口

既然,在工作线程中通过窗口句柄直接调用相关函数对窗口进行操作的这种做法不太好,那采用什么方法将最终的处理结果显示到窗口上呢?我的方法是调用 PostMessage,通过自定义消息将数据交给窗口的窗口过程处理,也就是拥有窗口的线程处理,这种情况下工作线程中唯一和窗口相关的操作就是通过窗口句柄调用 PostMessage。目前,我并想不到这种做法有什么有问题的地方,如果有人觉得有问题,大家可以一起讨论下。

另外,如果有兄弟知道更好的做法,大家也可以讨论下。

感受和思考

在查找线程和窗口的相关资料过程中,发现很多人都在问关于线程和窗口的一些问题,在讨论关于窗口和线程的一些概念,而且搞出来一些很玄乎的东西。但其实搞清楚一些基础知识,自己独立思考一下,这些问题并不难回答。也许 MFC 相对传统的 Win32 API 确实方便些,但窗口过程,消息循环等一些基本概念还是要理解的。

版权声明:本文为博主原创文章,未经博主允许不得转载。

如何得到线程执行完之后返回的结果

在实际开发过程中,很多时候要将子线程执行完后返回的结果给到主线程里。具体怎么实现呢?这里给出3个实现方法!1、根据反射原理实现很多人都习惯在调用线程的时候,通过构造方法给线程传递参数,这里我们在构造方...

基于Qt与OpenCV的图片读取、保存,并利用Canny进行简单的边缘处理结果显示

本次采用Qt5.7(安装包名称为qt-opensource-windows-x86-mingw530-5.7.1.exe)与OpenCV3.1版本。两者环境的配置就不多说了。 最终实现了图片的读取,边...

在独立线程中显示WPF窗口

  • 2012年04月30日 23:09
  • 48KB
  • 下载

如何在工作线程中创建窗口?

 在前面我们研究了使用AFX_MANAGE_STATE(AfxGetStaticModuleState())进行DLL间的资源切换,以及工作线程中创建Windows消息循环的原理,以为就可以搞定...

工作线程中弹出带Doc/View的窗口

 关键词:MFC 多线程,弹出窗口,Doc/View,自定义消息   一、问题提出   不是弹出对话框,是那种带框架(Frame...

如何在工作线程中创建窗口?

在前面我们研究了使用AFX_MANAGE_STATE(AfxGetStaticModuleState())进行DLL间的资源切换,以及工作线程中创建Windows消息循环的原理,以为就可以搞定一切类似...

Windows消息队列,UI线程,窗口以及消息处理方式总结

1.窗口    Windows程序是由一系列的窗口构成的,每个窗口都有自己的窗口过程,窗口过程就是一个拥有有固定 Signature 的 C函数,具体格式如下:    LRESULT CALL...
  • weiqubo
  • weiqubo
  • 2012年02月15日 23:33
  • 3114
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:窗口和线程漫谈之工作线程如何将数据的处理结果显示到窗口
举报原因:
原因补充:

(最多只允许输入30个字)