zoukankan      html  css  js  c++  java
  • 学习win32API消息处理

    消息队列与消息循环(摘自win32API参考)

    delphi通过TApplication对象自动对消息进行处理,每一个线程都有自己的消息队列,通过TApplication.ProcessMessages方法实现程序的消息循环:

    {Forms}
    procedure TApplication.ProcessMessages;
    var
      Msg: TMsg;
    begin
      while ProcessMessage(Msg) do {loop};
    end;

    程序通过简单地建立一个循环来实现自己的消息循环,通过调用下边四个函数实现.以下参考delphi帮助,自己翻译的,理解也许有错误,不过这正是我需要的,等回头看时,会收获好多.

    BOOL GetMessage(      

    LPMSG lpMsg,{指向消息结构的指针,从线程消息队列里边获取消息} HWND hWnd,{取得消息窗口句柄,当值为NULL时,为属于调用线程的窗口检索消息,通过PostThreadMessage发送给调用线程} UINT wMsgFilterMin,{被检索的最小消息} UINT wMsgFilterMax{被检索的最大消息} );
    BOOL PeekMessage(      

    LPMSG lpMsg,{接收消息的结构指针} HWND hWnd,{被检查消息的窗口句柄} UINT wMsgFilterMin,{被检索的最小消息} UINT wMsgFilterMax,{被检索的最大消息} UINT wRemoveMsg{决定消息处理方式,缺省处理所有消息} );

    BOOL TranslateMessage(
    const MSG *lpMsg );{指向有消息的结构指针,包含上面两个函数从消息队列里取得的消息}

    如果消息被转换返回0.

    LRESULT DispatchMessage(
    const MSG *lpmsg );{指向有消息的结构指针}

    分发消息给窗口程序,一般从GetMessage获得.

    delphi通过ProcessMessage函数来处理

    function TApplication.ProcessMessage(var Msg: TMsg): Boolean;
    var
      Unicode: Boolean;//老版本的delphi好像没有这个,可能是为了处理宽字符串吧
      Handled: Boolean;
      MsgExists: Boolean;
    begin
      Result := False;
      if PeekMessage(Msg, 0, 0, 0, PM_NOREMOVE) then //消息处理后,在队列中保留
      begin
        Unicode := (Msg.hwnd <> 0) and IsWindowUnicode(Msg.hwnd);
        if Unicode then
          MsgExists := PeekMessageW(Msg, 0, 0, 0, PM_REMOVE)//处理后移出消息队列
        else
          MsgExists := PeekMessage(Msg, 0, 0, 0, PM_REMOVE);
        if not MsgExists then Exit;
        Result := True;
        if Msg.Message <> WM_QUIT then
        begin
          Handled := False;
          if Assigned(FOnMessage) then FOnMessage(Msg, Handled);
          if not IsPreProcessMessage(Msg) and not IsHintMsg(Msg) and
            not Handled and not IsMDIMsg(Msg) and
            not IsKeyMsg(Msg) and not IsDlgMsg(Msg) then
          begin
            TranslateMessage(Msg);
            if Unicode then
              DispatchMessageW(Msg)
            else
              DispatchMessage(Msg);//分发消息到调用窗口
          end;
        end
        else
          FTerminate := True;
      end;
    end;

    每一个消息循环都是通过上边的函数实现的.

    关注过程,不知不觉就发现了结果原来如此...
  • 相关阅读:
    Sql Server 2008 为开发带来的新特性
    MSMQ 与ESB
    面向服务架构(SOA)和企业服务总线(ESB)
    IBM网站 构建您的SOA 系列文章
    Visual Studio 2008 和 .NET Framework 3.5 Training Kit
    模式与实践 系列发布WCF Security Guidance 1.0
    跟NHibernate之夏一起学习NHibernate
    ORACLE一些不常用的脚本
    ORACLE已建表能否创建分区
    Access数据库问题锦集
  • 原文地址:https://www.cnblogs.com/iicc/p/5055414.html
Copyright © 2011-2022 走看看