学习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;

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

posted @ 2015-12-17 21:45  陨落流星  阅读(1252)  评论(0编辑  收藏  举报