大悟还俗

邮箱 key_ok@qq.com 我的收集 http://pan.baidu.com/share/home?uk=1177427271
posts - 236, comments - 8, trackbacks - 0, articles - 0
  新随笔  :: 联系 :: 订阅 订阅  :: 管理

Windows消息【一】 消息队列

Posted on 2013-10-09 12:25 大悟还俗 阅读(...) 评论(...) 编辑 收藏

看了MSDN后,以下是我个人的理解!

消息能够被分为「队列化消息」和「非队列化消息」。

队列化消息是指当程序发生某事件时,由Windows主动捕获并把消息放入系统消息队列中,而程序在运行时会初始化一个消息泵,该消息泵用于抽取系统消息队列中的与之相关的消息,并把之分发到相应窗口函数上!

非队列化消息不走消息泵,而是直接分发到相应的窗口函数上!

 

 队列化消息基本上是使用者输入的结果,以击键(如WM_KEYDOWN和WM_KEYUP消息)、击键产生的字符(WM_CHAR)、鼠标移动(WM_MOUSEMOVE)和鼠标按钮(WM_LBUTTONDOWN)的形式给出。队列化消息还包含时钟消息(WM_TIMER)、更新消息(WM_PAINT)和退出消息(WM_QUIT)。(使用PostMessage来发送队列消息)

 

非队列化消息则是其它消息。在许多情况下,非队列化消息来自呼叫特定的Windows函数(使用SendMessage来发送非队列化消息)

 

咱们看看消息泵长什么样:

 

function TApplication.ProcessMessage(var Msg: TMsg): Boolean;
var
  Handled: Boolean;
begin
  Result := False;
  if PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then
  begin
    Result := True;
    if Msg.Message <> WM_QUIT then
    begin
      Handled := False;
      if Assigned(FOnMessage) then FOnMessage(Msg, Handled);//只有队列消息才会处理OnMessage函数
      if not IsHintMsg(Msg) and not Handled and not IsMDIMsg(Msg) and//处理完毕要加标识,handled:=True;
        not IsKeyMsg(Msg) and not IsDlgMsg(Msg) then
      begin
        TranslateMessage(Msg);
        DispatchMessage(Msg);//分发到各个窗口函数中
      end;
    end
    else
      FTerminate := True;
  end;
end;
View Code

由此理论依据我们可以得出结论:

使用Application.OnMessage事件是获取不到非队列化消息的!