不知道是否可以这样理解:
我把Button1Click函数看成是整个主线程回调函数的一部分,当Button1Click没返回的时候,也就是说主线程的回调函数没返回,主线程无法响应主线程登记消息队列中下一条消息的,鉴于DELPHI中有ProcessMessages这招,看下ProcessMessages里面的代码,居然是一套消息循环机制,在线程内再建立一个消息循环系统?我的理解是主线程中已经有Application.Run内建的消息循环机制了,现在在回调函数之内再建立一个消息循环机制?是不是之后所有的消息循环都会在ProcessMessages里面处理,而不在Application.Run里面处理?还是有其他理解?
另外参考代码中,我把Application.ProcessMessages;注释掉程序进入死循环无法响应任何消息,这个能理解。但是当我把Application.ProcessMessages;启用起来,我可以拖动窗口,能很快刷新出来,这个正是DELPHI的出发点,也能理解,但是我再点击这个Button1Click,注意到因为有ProcessMessages作用,程序会响应我的Button1Click,代码会重入到Button1Click中,不奇怪吗?如果我还点,还点… 那要重入多少次?单线程内该代码多次重入并且每部分代码都有一个消息循环,并且死循环一直都在?
好像是有个术语叫“接管消息机制”,在Form.ShowModal中就是这样的吧?我的理解有很多不对的地方,希望各位能够指出,因为一切实在是太费解了… 现在我想知道的是Application.ProcessMessages 和 Application.Run是如何协作工作的?另外Form.ShowModal 和 Application.Run又是如何协作的呢?参考代码:var
Busy: Boolean;
ExitFlag: Boolean;procedure TForm1.Button1Click(Sender: TObject);
begin
if Busy then Exit;
//Busy := true; //这行去掉不要
while true do
begin
Application.ProcessMessages; //
if ExitFlag then Break;
end;
Busy := false;
end;procedure TForm1.Button2Click(Sender: TObject);
begin
ExitFlag := true;
end;
我把Button1Click函数看成是整个主线程回调函数的一部分,当Button1Click没返回的时候,也就是说主线程的回调函数没返回,主线程无法响应主线程登记消息队列中下一条消息的,鉴于DELPHI中有ProcessMessages这招,看下ProcessMessages里面的代码,居然是一套消息循环机制,在线程内再建立一个消息循环系统?我的理解是主线程中已经有Application.Run内建的消息循环机制了,现在在回调函数之内再建立一个消息循环机制?是不是之后所有的消息循环都会在ProcessMessages里面处理,而不在Application.Run里面处理?还是有其他理解?
另外参考代码中,我把Application.ProcessMessages;注释掉程序进入死循环无法响应任何消息,这个能理解。但是当我把Application.ProcessMessages;启用起来,我可以拖动窗口,能很快刷新出来,这个正是DELPHI的出发点,也能理解,但是我再点击这个Button1Click,注意到因为有ProcessMessages作用,程序会响应我的Button1Click,代码会重入到Button1Click中,不奇怪吗?如果我还点,还点… 那要重入多少次?单线程内该代码多次重入并且每部分代码都有一个消息循环,并且死循环一直都在?
好像是有个术语叫“接管消息机制”,在Form.ShowModal中就是这样的吧?我的理解有很多不对的地方,希望各位能够指出,因为一切实在是太费解了… 现在我想知道的是Application.ProcessMessages 和 Application.Run是如何协作工作的?另外Form.ShowModal 和 Application.Run又是如何协作的呢?参考代码:var
Busy: Boolean;
ExitFlag: Boolean;procedure TForm1.Button1Click(Sender: TObject);
begin
if Busy then Exit;
//Busy := true; //这行去掉不要
while true do
begin
Application.ProcessMessages; //
if ExitFlag then Break;
end;
Busy := false;
end;procedure TForm1.Button2Click(Sender: TObject);
begin
ExitFlag := true;
end;
是不是说之后的所有消息都会在Application.ProcessMessages中处理,直到该重入代码全部处理完毕?
var
Msg: TMsg;
begin
while ProcessMessage(Msg) do {loop};
end;function TApplication.ProcessMessage(var Msg: TMsg): Boolean;
var
Handled: Boolean;
begin
Result := False;
if PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then
begin
Result := True;
if Msg.Message <> WM_QUIT then
begin
Handled := False;
if Assigned(FOnMessage) then FOnMessage(Msg, Handled);
if not IsHintMsg(Msg) and not Handled and not IsMDIMsg(Msg) and
not IsKeyMsg(Msg) and not IsDlgMsg(Msg) then
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
end
else
FTerminate := True;
end;
end;消息循环本来是Delphi维护处理的,而你进入死循环后,原来由Delphi处理的消息循环被阻塞,现在由你自己调用消息处理函数。PeekMessage,TranslateMessage,DispatchMessage。
1.凡是在该主线程中发生的其他任何消息都会经过ProcessMessages中的DispatchMessage
//消息分为队列消息与非队列消息!只有发送到系统消息队列的消息(用PostMessage),才通过主线程的消息泵来GetMessage和DispatchMessage,其它的一些消息直接发送到窗口函数上(SendMessage),由于SendMessage属于阻塞式处理,所以一个消息处理不完毕,会阻塞整个消息队列!
2.当主线程登记消息队列中再没有其他的消息到来的时候,主线程会继续死循环,但是由于还是在死循环
当主线程的消息队列中没有消息时,GetMessage所在线程会处于sleep状态
----------------------------------
好像不是吧
About Messages and Message Queues
哈哈,我才小星星一个,哪能跟你们超星级别的比啊!不过还是谢谢你们!liangpei2008:
谢谢你的指正!
POSTMESSAGE发送的才经过消息队列吧