学习win32API-消息处理

本文详细介绍了Delphi中TApplication对象如何通过ProcessMessages方法实现消息循环。解释了GetMessage、PeekMessage、TranslateMessage和DispatchMessage函数的作用,并展示了Delphi中消息循环的具体实现。

消息队列与消息循环(摘自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;

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值