[x]秒后关闭Delphi对话框
是否可以让Delphi在一定时间后关闭ShowMessage或MessageDlg对话框 我想在应用程序关闭时向用户显示一条消息,但不想阻止应用程序关闭超过10秒[x]秒后关闭Delphi对话框,delphi,dialog,timeout,Delphi,Dialog,Timeout,是否可以让Delphi在一定时间后关闭ShowMessage或MessageDlg对话框 我想在应用程序关闭时向用户显示一条消息,但不想阻止应用程序关闭超过10秒 我可以让默认对话框在定义的时间后关闭,还是需要编写自己的表单?我考虑使用一个单独的线程,但它可能会让您陷入许多不必要的代码等。Windows对话框根本不是为这件事而设计的 你应该做你自己的表格。好的一面是,您可以像定时对话框一样使用带有倒计时功能的自定义代码/UI。确定。您有两种选择: 1-您可以创建自己的MessageDialog表
我可以让默认对话框在定义的时间后关闭,还是需要编写自己的表单?我考虑使用一个单独的线程,但它可能会让您陷入许多不必要的代码等。Windows对话框根本不是为这件事而设计的
你应该做你自己的表格。好的一面是,您可以像定时对话框一样使用带有倒计时功能的自定义代码/UI。确定。您有两种选择: 1-您可以创建自己的MessageDialog表单。然后,您可以使用它并添加一个TTimer,在需要时关闭表单 2-您可以继续使用showmessage并创建一个线程,该线程将使用FindWindow(查找messadialog窗口),然后关闭它
我建议您使用您自己的带有计时器的表单。它更干净更容易 否。ShowMessage和MessageDlg都是模式窗口,这意味着您的应用程序在显示时基本上处于挂起状态 您可以设计自己的带有计时器的替换对话框。在FormShow事件中,启用计时器,在FormClose事件中禁用它。在OnTimer事件中,禁用计时器,然后关闭窗体本身。尝试以下操作:
function MessageBoxTimeOut(hWnd: HWND; lpText: PChar; lpCaption: PChar;
uType: UINT; wLanguageId: WORD; dwMilliseconds: DWORD): integer;
stdcall; external user32 name 'MessageBoxTimeoutA';
我已经用了很长时间了;这是一种享受。您可以尝试使用标准的消息对话框。使用CreateMessageDialog过程从Dialogs创建对话框,然后添加所需的控件 在带有TButton的表单中,使用以下命令定义onClick:
procedure TForm1.Button1Click(Sender: TObject);
var
tim:TTimer;
begin
// create the message
AMsgDialog := CreateMessageDialog('This is a test message.',mtWarning, [mbYes, mbNo]) ;
lbl := TLabel.Create(AMsgDialog) ;
tim := TTimer.Create(AMsgDialog);
counter := 0;
// Define and adding components
with AMsgDialog do
try
Caption := 'Dialog Title' ;
Height := 169;
// Label
lbl.Parent := AMsgDialog;
lbl.Caption := 'Counting...';
lbl.Top := 121;
lbl.Left := 8;
// Timer
tim.Interval := 400;
tim.OnTimer := myOnTimer;
tim.Enabled := true;
// result of Dialog
if (ShowModal = ID_YES) then begin
Button1.Caption := 'Press YES';
end
else begin
Button1.Caption := 'Press NO';
end;
finally
Free;
end;
end;
类似以下内容的OnTimer属性:
procedure TForm1.MyOnTimer(Sender: TObject);
begin
inc(counter);
lbl.Caption := 'Counting: ' + IntToStr(counter);
if (counter >= 5) then begin
AMsgDialog.Close;
end;
end;
定义变量和程序:
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
AMsgDialog: TForm;
lbl:TLabel;
counter:integer;
procedure MyOnTimer(Sender: TObject);
end;
并对其进行测试。计时器结束倒计时时,窗体将自动关闭。与此类似,您可以添加其他类型的组件 问候。您可以用手机来完成这项工作
您可以在中找到,也可以自己调用。当模式对话框或系统消息框或类似对话框处于活动状态时(或当菜单打开时),您的应用程序实际上仍在工作,这只是一个辅助消息循环正在运行,它处理所有消息-发送或发布到它的所有消息,并且它将合成(并处理)
WM_定时器
和WM_绘制
必要时的信息
因此,无需创建线程或跳过任何其他环,只需安排关闭消息框的代码在10秒后运行。一种简单的方法是调用时不使用目标HWND
,而是使用回调函数:
procedure CloseMessageBox(AWnd: HWND; AMsg: UINT; AIDEvent: UINT_PTR;
ATicks: DWORD); stdcall;
var
Wnd: HWND;
begin
KillTimer(AWnd, AIDEvent);
// active window of the calling thread should be the message box
Wnd := GetActiveWindow;
if IsWindow(Wnd) then
PostMessage(Wnd, WM_CLOSE, 0, 0);
end;
procedure TForm1.Button1Click(Sender: TObject);
var
TimerId: UINT_PTR;
begin
TimerId := SetTimer(0, 0, 10 * 1000, @CloseMessageBox);
Application.MessageBox('Will auto-close after 10 seconds...', nil);
// prevent timer callback if user already closed the message box
KillTimer(0, TimerId);
end;
处理ommitted时出错,但这应该可以让您开始。如果您想要连接计时器关闭感兴趣的窗体,可以连接Screen.OnActiveFormChange事件并使用Screen.ActiveCustomForm
{code}
procedure abz.ActiveFormChange(Sender: TObject);
var
Timer: TTimer;
begin
if (Screen.ActiveCutomForm <> nil) and //valid form
(Screen.ActiveCutomForm.Tag = 0) and //not attached a timer yet
(Screen.ActiveCutomForm.ClassName = 'TMessageForm') //any interested form type check
then
begin
Timer := TTimer.Create(Screen.ActiveCutomForm); // let the form owned so it will be freed
Timer.Enabled := False;
Timer.Tag := Integer(Screen.ActiveCutomForm); // keep track to be used in timer event
.... setup any timer interval + event
Screen.ActiveCutomForm.Tag := Integer(Timer);
Timer.Enabled := True;
end;
end;
{code}
{code}
程序abz.ActiveFormChange(发送方:ToObject);
变量
定时器:TTimer;
开始
if(Screen.ActiveCutomForm nil)和//有效形式
(Screen.ActiveCutomForm.Tag=0)和//尚未连接计时器
(Screen.ActiveCutomForm.ClassName='TMessageForm')//任何感兴趣的表单类型检查
然后
开始
计时器:=TTimer.Create(Screen.ActiveCutomForm);//让窗体拥有它,以便将其释放
Timer.Enabled:=False;
Timer.Tag:=整数(Screen.ActiveCutomForm);//跟踪要在计时器事件中使用的内容
.... 设置任何计时器间隔+事件
Screen.ActiveCutomForm.Tag:=整数(计时器);
Timer.Enabled:=True;
结束;
结束;
{code}
享受这在windows 98和新版本中运行良好 我不使用“MessageBoxTimeOut”,因为旧的Windows98,我,没有它 这个新功能就像一个“魔咒” //添加此过程
procedure DialogBoxAutoClose(const ACaption, APrompt: string; DuracaoEmSegundos: Integer);
var
Form: TForm;
Prompt: TLabel;
DialogUnits: TPoint;
ButtonTop, ButtonWidth, ButtonHeight: Integer;
nX, Lines: Integer;
function GetAveCharSize(Canvas: TCanvas): TPoint;
var
I: Integer;
Buffer: array[0..51] of Char;
begin
for I := 0 to 25 do Buffer[I] := Chr(I + Ord('A'));
for I := 0 to 25 do Buffer[I + 26] := Chr(I + Ord('a'));
GetTextExtentPoint(Canvas.Handle, Buffer, 52, TSize(Result));
Result.X := Result.X div 52;
end;
begin
Form := TForm.Create(Application);
Lines := 0;
For nX := 1 to Length(APrompt) do
if APrompt[nX]=#13 then Inc(Lines);
with Form do
try
Font.Name:='Arial'; //mcg
Font.Size:=10; //mcg
Font.Style:=[fsBold];
Canvas.Font := Font;
DialogUnits := GetAveCharSize(Canvas);
//BorderStyle := bsDialog;
BorderStyle := bsToolWindow;
FormStyle := fsStayOnTop;
BorderIcons := [];
Caption := ACaption;
ClientWidth := MulDiv(Screen.Width div 4, DialogUnits.X, 4);
ClientHeight := MulDiv(23 + (Lines*10), DialogUnits.Y, 8);
Position := poScreenCenter;
Prompt := TLabel.Create(Form);
with Prompt do
begin
Parent := Form;
AutoSize := True;
Left := MulDiv(8, DialogUnits.X, 4);
Top := MulDiv(8, DialogUnits.Y, 8);
Caption := APrompt;
end;
Form.Width:=Prompt.Width+Prompt.Left+50; //mcg fix
Show;
Application.ProcessMessages;
finally
Sleep(DuracaoEmSegundos*1000);
Form.Free;
end;
end;
////////////////////////////这叫什么//////////////////
DialogBoxAutoClose('警报','此消息将在10秒内关闭',10)
/////////////////////////////////////////////////////////MessageBox在内部调用此函数,并将0xFFFFFF作为超时参数传递,因此删除它的概率最小(多亏了Maurizio)最好的方法是使用StationTop窗体,并使用窗体的Alpha blend属性管理计数器以使其消失,在计数结束时,只需关闭窗体,但
控件将在显示表单之前传递到所需的活动控件,这样,用户将收到一条消息,该消息将自动消失,并且不会阻止使用下一个功能,这对我来说非常酷。谢谢,这就是我所想的,在表单上添加计时器是我应该采取的方式-我只是想检查一下defaults:)请参阅我的答案以获得(简单的)第三种选择。操作系统提供的消息框比VCL消息对话框(外观)有优势.Hm…Raymond Chen不喜欢开发人员使用Windows API的未记录功能。所以我不得不对这一点投反对票。没关系;当它可供Microsoft使用时,我也使用它。对每个人来说都是他们自己的。我不知道你所说的“应用程序被暂停”到底是什么意思“,但这是错误的,-1。当模式窗口处于活动状态时,完全有可能执行代码。和