delphi 实现延时自动关闭对话框


本文整理自网络,侵删。

 {*******************************************************}
{ 一种自动关闭对话框的简单方法 }
{ 使用方法:打开对话框前调用 SetDlgAutoClose }
{ 参数1: 设定多长时间后关闭 }
{ 参数2: 是否在对话框标题栏进行倒计时提示 }
{ 取消自动关闭调用 ResetDlgAutoClose }
{*******************************************************}

unit TimerDlg;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,
Forms, ExtCtrls;


// 如果指定的时间没有操作对话框,则自动关闭
procedure ResetDlgAutoClose;
procedure SetDlgAutoClose(nTime: Integer; ADoHint: Boolean = False);

implementation


{** 如果对话框被打开,则在指定时间后关闭,并在标题栏进行提示 }
var
nWndCount: Integer = 0;
SavWnds, SavWnds2: array of THandle;
hDlgWnd: THandle = 0;
hTimerk: Integer = 0;
nTimerTick: Integer = 0;
nLastTrk: Integer = 0;
nDoHint: Integer = 0;
nCapCt: Integer = 0;
nSavCapt: String = '';
fTimer1: TTimer = nil;

function MyEnumProc(hWnd: THandle; lParam: Integer): Boolean; stdcall;
var
n: Integer;
begin
Result := True;
if lParam = 0 then
begin
if not IsWindowEnabled(hWnd) then Exit;
if not IsWindowVisible(hWnd) then Exit;
end;
n := (nWndCount + 10) div 10 * 10;
SetLength(SavWnds, n);
SavWnds[nWndCount] := hWnd;
Inc(nWndCount);
end;

procedure MyTimerProc(hWnd: THandle; uMsg: Integer;
idEvent: Integer; dwTime: Integer);
var
i, t: Integer;
function FindInArray(ar: array of THandle; hd: THandle): Boolean;
var
t: Integer;
begin
Result := False;
for t := Low(ar) to High(ar) do
begin
Result := ar[t] = hd;
if Result then Break;
end;
end;
begin
if (hDlgWnd = 0) and (SavWnds = nil) and (SavWnds2 <> nil) then
begin
nWndCount := 0;
EnumThreadWindows(GetCurrentThreadId, @MyEnumProc, 0);
SetLength(SavWnds, nWndCount);
for i := Low(SavWnds) to High(SavWnds) do
begin
if not FindInArray(SavWnds2, SavWnds[i]) then
begin
if SavWnds[i] = GetActiveWindow then
begin
hDlgWnd := SavWnds[i];
end;
end;
end;
if hDlgWnd = 0 then ResetDlgAutoClose;
nLastTrk := GetTickCount;
SetLength(nSavCapt, 500);
t := GetWindowText(hDlgWnd, PChar(nSavCapt), 500);
SetLength(nSavCapt, t);
nCapCt := 0;
end
else
if (hDlgWnd <> 0) then
begin
if not IsWindow(hDlgWnd) or
not IsWindowVisible(hDlgWnd) or
not IsWindowEnabled(hDlgWnd) then
begin
ResetDlgAutoClose;
Exit;
end;
t := GetTickCount;
t := (nTimerTick - (t - nLastTrk) - 1);
if t <= 0 then
begin
PostMessage(hDlgWnd, WM_CLOSE, 0, 0);
ResetDlgAutoClose;
end
else
if (nDoHint > 0) then
begin
t := (t + 1000) div 1000;
if nCapCt <> t then
begin
SetWindowText(hDlgWnd,
PChar(Format('(%d)%2s%s', [t, ' ', nSavCapt])));
nCapCt := t;
end;
end;
end;
end;

procedure TimerFunc(Sender: TObject);
begin
MyTimerProc(0, 0, 0, 0);
end;

procedure SetDlgAutoClose(nTime: Integer; ADoHint: Boolean = False);
var
FakeEvt: TNotifyEvent;
Ptrs: array[1..2] of Pointer absolute FakeEvt;
begin
ResetDlgAutoClose;
nWndCount := 0;
EnumThreadWindows(GetCurrentThreadId, @MyEnumProc, 1);
SetLength(SavWnds, nWndCount);
SavWnds2 := SavWnds;
SavWnds := nil;
if not Assigned(fTimer1) then
begin
fTimer1 := TTimer.Create(Application);
Ptrs[2] := nil;
Ptrs[1] := @TimerFunc;
fTimer1.OnTimer := FakeEvt;
fTimer1.Interval := 100;
fTimer1.Enabled := True;
end;
nLastTrk := GetTickCount;
nDoHint := Ord(ADoHint);
nTimerTick := nTime;
end;

procedure ResetDlgAutoClose;
begin
if hDlgWnd <> 0 then
begin
SetWindowText(hDlgWnd, PChar(nSavCapt));
end;
if Assigned(fTimer1) then
FreeAndNil(fTimer1);
nWndCount := 0;
hDlgWnd := 0;
SavWnds := nil;
SavWnds2 := nil;
nTimerTick := 0;
end;


end.

测试

procedure TForm1.Button1Click(Sender: TObject);
begin
SetDlgAutoClose(15*1000, True);
ShowMessage('This message box will close automatically,' + #13#10 +
'after fifteen seconds.');
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
SetDlgAutoClose(8000, Sender = Button3);
MessageBox(Handle, PChar('这是一个测试例子' +
#13#10 + '此消息框将在 8 秒钟后自动关闭' + #13#10 +
'只需要在调用消息框和对话框之前调用一个函数' + #13#10 +
'就可以方便的实现这种效果'),
'定时自动关闭的消息框', MB_ICONINFORMATION or MB_OKCANCEL);
end;

procedure TForm1.Button2Click(Sender: TObject);
var
dlg: TDlgTest;
begin
SetDlgAutoClose(8*1000, True);
dlg := TDlgTest.Create(Self);
dlg.ShowModal;
dlg.Free;

end;

procedure TForm1.Button5Click(Sender: TObject);
begin
ShowMessage('Normal ShowMessage');
end;

相关阅读 >>

Delphi把流中的字符串转换为utf格式

Delphi pchar与string互转

Delphi 判断网站文件是否存在

Delphi tthread中文注释

Delphi webservices 字节数组 base64编码

Delphi android检查互联网连接

Delphi 常用控件属性

Delphi ttabcontrol

Delphi判断mssql数据库中表格是否存在? 如何批量创建表格?

Delphi 拖动文件到exe 打开 获取getcommandline命令行

更多相关阅读请进入《Delphi》频道 >>



打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...