一个报警窗体(不能手动关闭),当满足关闭条件时候在FormCloseQuery事件里设置canclose:=true;
现在当报警时候,主窗体缩小到任务拦的话,过段时间,报警消除,把主窗体放大,报警窗体不回消失。
模拟代码如下:
//单元1 ,模拟主线程
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls;type
TForm1 = class(TForm)
Timer1: TTimer;
procedure Timer1Timer(Sender: TObject);
procedure FormShow(Sender: TObject);
private
{ Private declarations }
public
i:integer;
{ Public declarations }
end;var
Form1: TForm1;
implementationuses Unit2;{$R *.dfm}procedure TForm1.Timer1Timer(Sender: TObject);
begin
i:=i-1;
if i<0 then
begin
i:=0;
form2.Close;
end;
end;procedure TForm1.FormShow(Sender: TObject);
begin
form2.show;
i:=10;
end;end.
现在当报警时候,主窗体缩小到任务拦的话,过段时间,报警消除,把主窗体放大,报警窗体不回消失。
模拟代码如下:
//单元1 ,模拟主线程
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls;type
TForm1 = class(TForm)
Timer1: TTimer;
procedure Timer1Timer(Sender: TObject);
procedure FormShow(Sender: TObject);
private
{ Private declarations }
public
i:integer;
{ Public declarations }
end;var
Form1: TForm1;
implementationuses Unit2;{$R *.dfm}procedure TForm1.Timer1Timer(Sender: TObject);
begin
i:=i-1;
if i<0 then
begin
i:=0;
form2.Close;
end;
end;procedure TForm1.FormShow(Sender: TObject);
begin
form2.show;
i:=10;
end;end.
解决方案 »
- 一个很简单的问题!
- 创建excel文件后动态加载宏
- 请教,在线急等!!!
- query1.sql.add('insert into DKH valus(select fname,fXH from users where usercode='free')');怎么不可以呀?好象问题就出在引号上了,
- 如果用多线程实现我这里的同步需要。简单扼要就好
- 用installshield 6.22编程的几个问题:(1)用Project Wizard建立了一个工程文件,经过编译后没错,
- 用StringGrid怎样实现定位
- (急救)delphi 串口转网口的设计
- Delphi编程技巧总汇--------[持续更新]
- 大虾请进,关于ListView
- 如何把select到的东西放到edit中
- 如何判断COM口已接收到数据
unit Unit2;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;type
TForm2 = class(TForm)
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form2: TForm2;implementationuses Unit1;{$R *.dfm}procedure TForm2.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
if form1.i<=0 then
CanClose:=true
else
CanClose:=false;
end;end.
begin
i:=i-1;
if i<0 then
begin
i:=0;
if Assigned(form2) then FreeAndNil(form2); //form2.Close;直接把他给KILL掉
end;
end;procedure TForm1.FormShow(Sender: TObject);
begin
if Not Assigned(form2) then form2 := TForm2.Create(self); //不存在时就创建!
form2.show;
i:=10;
end;
最小化恢复到原来状态你的FormShow事件根本不会被触发,另外我只是想找到这个引发问题的原理,解决的话途径很多,你的动态创建释放只是其中之一,谢谢你的热心.
首先你最小化的时候,系统处理了WMSysCommand消息,处理代码如下:
procedure TCustomForm.WMSysCommand(var Message: TWMSysCommand);begin
with Message do
begin
if (CmdType and $FFF0 = SC_MINIMIZE) and (Application.MainForm = Self) then
Application.WndProc(TMessage(Message))
......
end;
这句可以看出,如果你最小化的是主窗体,系统就把消息传给Application.WndProc处理
再来看看Application.WndProc
procedure TApplication.WndProc(var Message: TMessage);
with Message do
case Msg of
WM_SYSCOMMAND:
case WParam and $FFF0 of
SC_MINIMIZE: Minimize;
SC_RESTORE: Restore;
else
end;
他是调用了Minimize;
procedure TApplication.Minimize;里又调用了NormalizeTopMosts;
NormalizeTopMosts再调用DoNormalizeTopMosts(False);
而
procedure TApplication.DoNormalizeTopMosts(IncludeMain: Boolean);
var
I: Integer;
Info: TTopMostEnumInfo;
begin
if Application.Handle <> 0 then
begin
if FTopMostLevel = 0 then
begin
Info.TopWindow := Handle;
Info.IncludeMain := IncludeMain;
EnumWindows(@GetTopMostWindows, Longint(@Info));
//这里枚举了窗体,
我们再来看看GetTopMostWindowsfunction GetTopMostWindows(Handle: HWND; Info: Pointer): BOOL; stdcall;
begin
Result := True;
if GetWindow(Handle, GW_OWNER) = Application.Handle then
if (GetWindowLong(Handle, GWL_EXSTYLE) and WS_EX_TOPMOST <> 0) and
((Application.MainForm = nil) or PTopMostEnumInfo(Info)^.IncludeMain or
(Handle <> Application.MainForm.Handle)) then
Application.FTopMostList.Add(Pointer(Handle))
else
begin
PTopMostEnumInfo(Info)^.TopWindow := Handle;
Result := False;
end;
end; if GetWindow(Handle, GW_OWNER) = Application.Handle then
if (GetWindowLong(Handle, GWL_EXSTYLE) and WS_EX_TOPMOST <> 0) and
((Application.MainForm = nil) or PTopMostEnumInfo(Info)^.IncludeMain or
(Handle <> Application.MainForm.Handle)) then
Application.FTopMostList.Add(Pointer(Handle))
这里应该是把应用程序中所有真显示的窗体的Handle保存在FTopMostList里面
做一下记录,好让Restore的时候可以根据这个列表来恢复显示而从Restore中调用的RestoreTopMosts中可以看出,确实是利用了FTopMostList进行了恢复!
for I := FTopMostList.Count - 1 downto 0 do
SetWindowPos(HWND(FTopMostList[I]), HWND_TOPMOST, 0, 0, 0, 0,
SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE);所以这里,虽然你已经在TIMER里Close了窗体,但是只是把它给Hide了,FTopMostList
还是记录窗提要被恢复的信息,所以当你Restore的时候它又再度把他显示出来~~~
一点看法,应该很多不正确的地方,多多指教~
procedure TCustomForm.DoClose(var Action: TCloseAction);
begin
if Assigned(FOnClose) then FOnClose(Self, Action);
end;
procedure TCustomForm.Close;
var
CloseAction: TCloseAction;
begin
if fsModal in FFormState then
ModalResult := mrCancel
else
if CloseQuery then
begin
if FormStyle = fsMDIChild then
if biMinimize in BorderIcons then
CloseAction := caMinimize else
CloseAction := caNone
else
CloseAction := caHide;
DoClose(CloseAction);
if CloseAction <> caNone then
if Application.MainForm = Self then Application.Terminate
else if CloseAction = caHide then Hide
else if CloseAction = caMinimize then WindowState := wsMinimized
else Release;
end;
end;
通过上述代码可以看出它对非子窗体的关闭确实执行了hide处理,方便以后的调用,delphi版越来越冷,既然找到问题原因了,就结了吧