是否有可能在一定時間後讓Delphi關閉ShowMessage或MessageDlg對話框?[x]秒後關閉Delphi對話框
我想在應用程序關閉時向用戶顯示消息,但不想停止應用程序關閉超過10秒鐘左右。
我可以獲得默認對話框以在指定時間後關閉,還是需要編寫自己的表單?
是否有可能在一定時間後讓Delphi關閉ShowMessage或MessageDlg對話框?[x]秒後關閉Delphi對話框
我想在應用程序關閉時向用戶顯示消息,但不想停止應用程序關閉超過10秒鐘左右。
我可以獲得默認對話框以在指定時間後關閉,還是需要編寫自己的表單?
當模態對話框或系統消息框或類似項處於活動狀態(或菜單打開時)時,您的應用程序實際上仍在工作,它只是一個正在運行的處理所有消息的輔助消息循環 - 所有消息已發送或已發佈並在必要時合成(並處理)WM_TIMER
和WM_PAINT
消息。
所以沒有必要創建一個線程或通過任何其他跳火圈,你只需要安排其關閉這10秒鐘過去後要運行的消息框代碼。一個簡單的方法來做到這一點是調用SetTimer()
沒有目標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,但這應該讓你開始。
我想過使用一個單獨的線程,但它可能會讓你陷入很多不必要的代碼等等.Windows對話框根本就不是用於這個東西的。
你應該做你自己的形式。好的一面是,你可以通過像定時對話框那樣的倒數計時器來定製代碼/ UI。
好的。您有2個選擇:
1 - 您可以創建自己的MessageDialog表單。然後,您可以使用它並添加一個TTimer,以便在需要時關閉表單。
2 - 您可以繼續使用showmessage並創建一個使用FindWindow的線程(查找messadialog窗口),然後關閉它。
我建議你使用你自己的窗體上有一個計時器。它更乾淨,更容易。
看看這個:http://www.delphipages.com/forum/showthread.php?t=166197 – 2010-12-17 15:59:07
謝謝,這就是我認爲,並在窗體上添加一個計時器是我會走的方式 - 只是認爲我會檢查默認值:) – 2010-12-17 16:04:54
請參閱我的答案(簡單)第三選擇。操作系統提供的消息框優於VCL消息對話框(外觀和感覺)。 – mghie 2010-12-17 19:53:52
不,ShowMessage和MessageDlg都是模式窗口,這意味着您的應用程序在顯示時基本暫停。
您可以設計自己的替換對話框,其上有一個定時器。在FormShow事件中,啓用計時器,並在FormClose事件中禁用它。在OnTimer事件中,禁用計時器,然後關閉窗體本身。
我不知道你的意思是什麼「應用程序被暫停」,但它是錯誤的,-1。在模態窗口處於活動狀態時執行代碼是完全可能的。 – mghie 2010-12-17 19:49:43
試試這個:
function MessageBoxTimeOut(hWnd: HWND; lpText: PChar; lpCaption: PChar;
uType: UINT; wLanguageId: WORD; dwMilliseconds: DWORD): integer;
stdcall; external user32 name 'MessageBoxTimeoutA';
我一直在使用這個相當長的一段時間;它工作的一種享受。
嗯...當開發人員使用Windows API的**未公開**功能時,Raymond Chen不喜歡它。所以我不得不在這個問題上倒下。 – 2010-12-17 17:39:56
沒關係;當它可供Microsoft使用時,我也使用它。給每個人自己。 – Restless 2010-12-20 16:16:31
使用示例:http://edn.embarcadero.com/print/32736 – 2013-11-05 09:53:52
您可以嘗試使用標準的消息對話框。使用對話框中的CreateMessageDialog過程創建對話框,然後添加所需的控件。
在具有一個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;
而測試它。
當定時器最終CountDown時,窗體自動關閉。類似的,你可以添加其他類型的組件。
問候。
您可以使用WTSSendMessage來做到這一點。
您可以在JWA libraries找到這些信息,或者自己調用它。
您可以掛鉤的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}
享受興趣形式
這工作正常與Windows 98和newers ...
我不使用 「MessageBoxTimeOut」,因爲舊的Windows 98,ME,沒有它...
這新的功能就像一個 「魅力」 ..
//添加此過程
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的內部調用此函數,並傳遞作爲0xFFFFFFFF的超時參數,所以它被移除的可能性是最小的(由於莫里吉奧爲該)
最好的辦法是使用stayontop形式和管理計數器使用形式的alfpha混合屬性,在計數結束剛剛關閉的形式消失,但 控制將被傳遞到顯示窗體之前所需的主動控制,這種方式,用戶將有一條消息自動消失,並且不會阻止下一個功能的使用,對我來說非常酷的技巧。
http://blogs.msdn.com/b/oldnewthing/archive/2005/03/01/382380.aspx和http://blogs.msdn.com/b/oldnewthing/archive/2005/03/04 /385100.aspx – 2010-12-17 22:31:50