unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;
Mark:Boolean=True;
implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
begin
while Mark do
begin
Application.ProcessMessages;
end;
end;procedure TForm1.Button2Click(Sender: TObject);
begin
Mark:=False;
end;end.开始运行后,点击button1后,在不点button2前,窗体不能正常关闭,但是最小最大化都可以,这是为什么呢?
解决方案 »
- Delphi Image控件
- Delphi 好还是C C++ java 好呢
- 兄弟们,急招人啊。
- 请问如何用insert into opendatasource导出到excel?
- 有用delphi写游戏的举手
- 如何单击dbgrideh的表头就能使数据表里的数据按表头字段排序?
- 如何获取DBGrid的列宽度变化事件?
- EMAIL了很多简历.也面试了十个单位了,还没有找到工作
- 关于timer
- 如何在客户端对SQL server数据库进行备份和恢复???
- [求助]datasnap中如何修改ADOconnection的连接字串。。。
- 那位大虾有关于tsslhttpcli与tsslhttpserver通讯的demo啊
while Mark and not Application.Terminated do
Application.ProcessMessages;这样就可以了
正是由于這段
procedure TForm1.Button1Click(Sender: TObject);
begin
while Mark do
begin
Application.ProcessMessages;
end;
end;
使得程序一直專注于處理隊列消息,沒有機會處理非隊列消息。
應該這么寫點擊關閉按鈕,會產生WM_Close,而這個消息是非隊列消息;Application.ProcessMessages并不會處理到。
正是由于這段
procedure TForm1.Button1Click(Sender: TObject);
begin
while Mark do
begin
Application.HandleMessage;
end;
end;
begin
Application.ProcessMessages;
end;
这是个死循环呀
Application.ProcessMessages;若是正常流程,Application.Terminated標志被改變,應該會收到WM_quit
嘗試在onmessage攔截WM_Quit并未發現有此消息。
1、程序收到了WM_Quit,但這個消息并不是由我們的程序發出的,而是系統給的;
2、WM_Quit只是一個退出消息循環的條件,所以我們判斷App.Terminated有效果;
3、根據你原先的寫法,即使WM_QUIT收到了,但并不會結束程序——參考App.ProcessMessage;
4、循環被打破後,窗體就有機會處理WM_CLOSE了;關于第一點,從程序和VCL源碼看,并沒有顯式地PostQuitMessage或直接發送WM_QUIT,所以推斷是系統發出的
但是我感觉WM_CLOSE应该先与WM_QUIT消息啊,一般点击关闭按钮WM_CLOSE,WM_DESTORY,WM_QUIT。
但是既然WM_CLOSE是不进队消息,那么在没有处理WM_CLOSE时,系统会直接发送WM_QUIT吗
1、即使一直ProcessMessages處理隊列消息,但只要有非隊列消息產生給窗體,OS借助中斷機制,直接調用窗口過程,傳遞消息;所以WM_Close還是會被處理。查看Form.CLose,由于你的Form1是MainForm,所以會調用App.Terminate——>PostQuitMessage——>處理Application.Terminated標志。倘若你在開另外一個窗體,然后這樣寫程序,就沒這么幸運可以關閉程序了。
2、HandleMessage只是在消息隊列沒有消息時,掛起線程而已,所以對你的問題也沒幫助;
若再開一個窗體,程序這樣寫的話,可以正常關閉才對,因為WM_Close能被處理.....
if Msg.Message <> WM_QUIT then
begin
end
else
begin
{$IF DEFINED(CLR)}
if Assigned(FOnShutDown) then FOnShutDown(self);
DoneApplication;
{$IFEND}
FTerminate := True;
end;
end;