MFC的来龙去脉-----热身开胃汤

现在是2013年12月份。对MFC这个老人来讲,这个年代早已是年轻人的天下。但我还是要看看你走过的路,体会你曾经的光荣。

  在剖析MFC之前,一定要先搞懂几个问题:

1.消息机制

  windows系统的soul,无需多言,也没能力多言...

2.消息及消息队列

  首先要清楚消息分两种,一种是要进入消息循环的的队列消息;一种是不进消息循环的非队列消息;在讨论消息循环时,一定是针对队列消息的

  对于windows系统,它维护着属于windows的唯一的消息队列。当有消息循环的线程执行时,它将分配该线程一个(或称为一组)属于该线程独有的消息队列。

  对于一个线程,消息队列可分别SendMessage 队列、PostedMessage 队列、Visualized Input队列、ReplyMessage队列等等,其本质是按照不同的处理方式、来源,给消息分类排队,并定义了不同的处理优先级,使得线程能够对不同消息做出不同的处理。

  关于消息队列的详细介绍,可见:

     http://my.oschina.net/myspaceNUAA/blog/64682 或

     http://blog.youkuaiyun.com/FreeWave/article/details/2056469或<windows 核心编程> 第四章。

3.消息从何而来

  -来自系统设备的响应,如硬件设备驱动如键盘、鼠标、音频、串口等;

  -来自应用程序本身,有一些是自动运行的,一些需要程序中实现,如改变窗口大小,重绘窗口、控件内容变化;另如定时器;

  -来自应用程序中用户自定义的WM_USER+XX的消息;该类消息采用Send/PostMessage发送;

4.windows对象、句柄及MFC对象的关系

  句柄用来标识windows对象。MFC使用C++对象,为了能与windows对象打交道,它封装了句柄,因此三者才能建立联系,形如【CWnd<->m_hWnd<->windows对象】

  以下文中有详细解释:http://blog.youkuaiyun.com/banward/article/details/4418367 和http://blog.sina.com.cn/s/blog_493309600100cqhw.html

  以下文中描述他们转换的方法:http://blog.163.com/fengxuedong_fxd/blog/static/719263062011920102930356/

  他们的关系,以句柄映射Map的形式保存在创建线程的UI线程状态信息中。显然每个UI线程拥有自己掌控的独有的句柄列表,也即CWnd对象,这样可以限制多个线程同时访问同一个对象,从而引起错误。当一个线程使用某个MFC对象指针P时,ASSERT_VALID(P)将验证当前线程的当前模块是否有Windows句柄和P对应,即是否创建了P所指的Windows对象,验证失败导致ASSERT断言中断程序的执行。如果一个线程要使用其他线程的Windows对象,则必须传递Windows对象句柄,不能传递MFC对象指针。

  由此应该知道,跨线程(这里指UI线程)的去更新一个CWnd对象时,不能直接用指针操作,因为发起者线程中(线程状态结构体中)并没有接收对象的句柄。有一种途径可以实现:

  ①在CWnd对象中自定义好消息,然后在另外线程中Send/PostMessage发送该消息给窗口;

  句柄绑定对象的方法是先建立对象实例Cxx,Attach;解绑Detach;

  

5.MFC线程与消息循环的关系

  线程分为Work Thread和UI Thread,前者不带消息循环,后者带消息循环。

  UI线程对象启动执行后,windows为它维护一个消息队列,UI线程将执行自己的消息循环,即自动执行run,若不改写,即CWinThread::Run;

6.PeekMessage与GetMessage区别

  都是获得消息。

  Peek有偷窥之意,它抓一下消息队列中的消息,不管抓不抓到,都立即返回;

  Get是强盗,一定要得到,进入阻塞,不获得消息绝不返回;

7.SendMeesage与Postmessage区别

   都是把消息发送。

  Send是直接发送。对于本线程的接收者,绕过消息循环,直接督促内核user32模块调用WinProc(最后即消息处理),并在发送期间阻塞,直至处理结束;对于跨线程的Send,则发送到接收者线程消息队列的Send队列中,此队列优先级别略高,可能最后仍然是由user32模块直接WinProc;

  Post有寄送之意,轻巧地把消息放入接收者线程的消息队列,由消息循环去寻找去向,找到去向,再调用消息处理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值