学习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;
每一个消息循环都是通过上边的函数实现的.
关注过程,不知不觉就发现了结果原来如此...