消息队列与消息循环(摘自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;
每一个消息循环都是通过上边的函数实现的.
本文详细介绍了Delphi中TApplication对象如何通过ProcessMessages方法实现消息循环。解释了GetMessage、PeekMessage、TranslateMessage和DispatchMessage函数的作用,并展示了Delphi中消息循环的具体实现。
4043

被折叠的 条评论
为什么被折叠?



