Author: Jonas Bilinkevicius
I need to create a messagebox asking the user to reply either Yes or No, but with a
timeout. Is there a way to use a messagebox function with some timeout, like open
messagebox with Yes or No, and after 20 seconds reply with other information to
know that user is out?
Answer:
Solve 1:
Show the MessageBox in another thread and kill the thread when you want to remove
the messagebox under program control:
1 { ... }
2 var
3 ThreadId: Integer;
4 ThreadHandle: Integer;
5 MsgResult: Integer;
6
7 function thread_proc(p: Pointer): integer; stdcall;
8 begin
9 MsgResult := MessageBox(0, 'Some question?', 'Hey', MB_ICONQUESTION or MB_YESNO);
10 ThreadHandle := 0;
11 EndThread(0);
12 end;
13
14 procedure TForm1.Button1Click(Sender: TObject);
15 var
16 counter: integer;
17 begin
18 MsgResult := IDNO; {default answer}
19 {show MessageBox}
20 ThreadHandle := BeginThread(nil, 0, @Thread_proc, nil, 0, ThreadID);
21 counter := 20; {wait for 20 seconds}
22 while (ThreadHandle <> 0) and (counter > 0) do
23 begin
24 Sleep(1000);
25 counter := counter - 1;
26 end;
27 {if MessageBox is still visible after 20 seconds, remove it}
28 if Counter = 0 then
29 TerminateThread(ThreadHandle, 0);
30 if MsgResult = IDYES then
31 { ... }
32 else
33 { ... }
34 end;
Solve 2:
35 procedure TForm1.Button1Click(Sender: TObject);
36 var
37 R: Integer;
38 begin
39 Timer1.Interval := 20000;
40 Timer1.Enabled := true;
41 R := MessageDlg('Yes or no?', mtConfirmation, [mbYes, mbNo], 0);
42 Caption := IntToStr(R);
43 Timer1.Enabled := false;
44 end;
45
46 procedure TForm1.Timer1Timer(Sender: TObject);
47 var
48 F: TForm;
49 begin
50 F := Screen.ActiveForm;
51 if fsModal in F.FormState then
52 F.ModalResult := mrYesToAll;
53 end;
|