cDialogCountdownMsgBox class
A cDialogCountdownMsgBox shows a Windows message box that closes by itself after a number of seconds, and reports which button ended it. The box is the one that the MessageBoxTimeoutW function of user32.dll shows; the class has no window of its own.
A cDialogCountdownMsgBox is made with New: Dim box As New cDialogCountdownMsgBox. It cannot be made with CreateObject. It is not a countdown that runs on screen: the box shows the number of seconds as text that never changes, and Windows closes it when the time is up.
The properties Title, Message, CountdownSeconds, Buttons, Icon and DefaultButton describe the box, ShowDialog shows it, and ShowInfo, ShowWarning, ShowError, ShowQuestion, ShowConfirm and ShowCustom set the first five and show it in one call. Result, IsTimedOut and GetResultDescription report how it ended.
Dim box As New cDialogCountdownMsgBox
Dim answer As DialogResult
answer = box.ShowQuestion("Save the changes before closing?", "Close", 20)
Select Case answer
Case DialogResult.drYes: Debug.Print "Save"
Case DialogResult.drNo: Debug.Print "Do not save"
Case DialogResult.drTimeout: Debug.Print "No answer in 20 seconds"
End Select
Warning
In version 1.1.0.0 a box with only an OK button that closes because its time ran out reports drOK, not drTimeout, and IsTimedOut is False. This affects the default box and ShowInfo, ShowWarning and ShowError. A box with any other set of buttons reports drTimeout when it times out. No error is raised, so a program cannot tell a press of OK from the end of the time with these members alone.
Dim box As New cDialogCountdownMsgBox
Dim started As Single
started = Timer
box.ShowInfo "Backup finished.", "Backup", 5
' With OK only, the result cannot show a timeout: compare the time.
If Timer - started >= 5 Then
Debug.Print "Closed by the countdown"
Else
Debug.Print "OK was pressed"
End If
Properties
AutoClose
Whether the box closes when the time is up.
Syntax: object.AutoClose [ = value ]
- value
- A Boolean. True (the default) closes the box after CountdownSeconds seconds. False leaves it open until the user presses a button; it then shows no countdown text, whatever ShowProgress says.
Dim box As New cDialogCountdownMsgBox
Debug.Print box.AutoClose ' True
box.AutoClose = False
Debug.Print box.AutoClose ' False
Buttons
The buttons of the box.
Syntax: object.Buttons [ = value ]
- value
- A Long, usually a MessageBoxButtons member. The default is MB_OK.
The value is combined with Icon and DefaultButton by Or and passed to Windows as the style of the box. ShowInfo, ShowWarning, ShowError, ShowQuestion, ShowConfirm and ShowCustom set it.
The enumeration has the six sets of buttons that Result can report. A button that DialogResult has no member for, such as Try Again and Continue of the style 6 (Cancel, Try Again, Continue), is not mapped: ShowDialog then leaves Result as the previous call left it, or drTimeout in a new object, and returns that.
Dim box As New cDialogCountdownMsgBox
Debug.Print box.Buttons = MB_OK ' True
box.Buttons = MB_YESNOCANCEL
Debug.Print box.Buttons ' 3
CountdownSeconds
The time after which the box closes, in seconds.
Syntax: object.CountdownSeconds [ = value ]
- value
- A Long. The default is 10.
Setting it also sets RemainingSeconds. The shortened forms ShowInfo and the others take the time as an argument, store it here, and do not touch RemainingSeconds.
The countdown text that the box shows (see ShowProgress) names this value in whole seconds, also for 1 and 0: in 1 seconds.... A value of 0 or less does not close the box: it stays open until a button is pressed, and its text says in 0 seconds....
Note
The class multiplies the value by 1000 to get milliseconds. A value above 2,147,483 (about 24.8 days) overflows, and ShowDialog handles the error 6 itself: it shows a plain message box with the message and an OK button, with no icon, countdown text or other buttons, and returns drOK. The call raises nothing, but Err.Number is 6 afterwards.
Dim box As New cDialogCountdownMsgBox
Debug.Print box.CountdownSeconds ' 10
box.CountdownSeconds = 45
Debug.Print box.CountdownSeconds ' 45
Debug.Print box.RemainingSeconds ' 45
DefaultButton
The button that Enter presses.
Syntax: object.DefaultButton [ = value ]
- value
- A Long, usually a MessageBoxDefaultButton member. The default is MB_DEFBUTTON1, the first button.
With MB_YESNO and MB_DEFBUTTON2, Enter ends the box with drNo. The Show* shortened forms do not change this property.
Dim box As New cDialogCountdownMsgBox
Debug.Print box.DefaultButton = MB_DEFBUTTON1 ' True
box.Buttons = MB_YESNO
box.DefaultButton = MB_DEFBUTTON2
Debug.Print box.DefaultButton ' 256
Icon
The icon of the box.
Syntax: object.Icon [ = value ]
- value
- A Long, usually a MessageBoxIcons member. The default is MB_ICONINFORMATION.
The Show* shortened forms set it; each form names its icon. The enumeration has no member for a box without an icon.
Dim box As New cDialogCountdownMsgBox
Debug.Print box.Icon = MB_ICONINFORMATION ' True
box.Icon = MB_ICONSTOP
Debug.Print box.Icon ' 16
Message
The text of the box.
Syntax: object.Message [ = value ]
- value
- A String. The default is an empty string.
The box shows this text; when the countdown text is on (see ShowProgress), it follows after a blank line.
Dim box As New cDialogCountdownMsgBox
Debug.Print Len(box.Message) ' 0
box.Message = "Do you want to continue?"
Debug.Print box.Message ' Do you want to continue?
OwnerHwnd
The window that owns the box.
Syntax: object.OwnerHwnd [ = value ]
- value
- A LongPtr, the handle of a window. The default is 0, no owner.
With an owner, the box is shown over it and the owner cannot be used while the box is open. Reset sets it back to 0.
Sub AskFromForm(ByVal parentWindow As LongPtr)
Dim box As New cDialogCountdownMsgBox
box.OwnerHwnd = parentWindow
Debug.Print box.ShowConfirm("Discard the draft?", "Draft", 15)
End Sub
RemainingSeconds
The seconds left, read-only.
Syntax: object.RemainingSeconds As Long
Returns the value that CountdownSeconds was last set to by the property. It does not count down, neither while the box is open nor afterwards, so it is of no use for showing the time left.
Dim box As New cDialogCountdownMsgBox
box.CountdownSeconds = 30
Debug.Print box.RemainingSeconds ' 30
Result
How the last box ended, read-only.
Syntax: object.Result As DialogResult
The button that ended the last call of ShowDialog, or drTimeout. A new object, and one after Reset, holds drTimeout before any box has been shown.
Dim box As New cDialogCountdownMsgBox
Debug.Print box.Result = DialogResult.drTimeout ' True
Debug.Print box.Result ' 32000
ShowProgress
Whether the box tells the number of seconds.
Syntax: object.ShowProgress [ = value ]
- value
- A Boolean. The default is True.
When this and AutoClose are True, the box adds a blank line and This message will close automatically in N seconds... to Message, where N is CountdownSeconds. The text is fixed: it does not count down and the box has no progress bar. When False, only the message is shown; the box still closes when the time is up.
Dim box As New cDialogCountdownMsgBox
Debug.Print box.ShowProgress ' True
box.ShowProgress = False
Debug.Print box.ShowProgress ' False
Title
The title of the box.
Syntax: object.Title [ = value ]
- value
- A String. The default is
Message.
Dim box As New cDialogCountdownMsgBox
Debug.Print box.Title ' Message
box.Title = "Backup"
Debug.Print box.Title ' Backup
Methods
GetResultDescription
Names the result in words.
Syntax: object.GetResultDescription ( ) As String
Returns OK, Cancel, Abort, Retry, Ignore, Yes, No or Timeout (Auto-close) for the current Result. In a new object it returns Timeout (Auto-close).
Dim box As New cDialogCountdownMsgBox
Debug.Print box.GetResultDescription() ' Timeout (Auto-close)
IsTimedOut
Whether the last box was closed by the countdown.
Syntax: object.IsTimedOut ( ) As Boolean
Returns True when Result is drTimeout. That is also the case in a new object before any box has been shown. A box with only an OK button that times out gives False, as the warning above describes.
Dim box As New cDialogCountdownMsgBox
Debug.Print box.IsTimedOut() ' True
Reset
Restores every property to its starting value.
Syntax: object.Reset
Sets Title to Message, Message to an empty string, CountdownSeconds and RemainingSeconds to 10, Buttons to MB_OK, Icon to MB_ICONINFORMATION, DefaultButton to MB_DEFBUTTON1, ShowProgress and AutoClose to True, OwnerHwnd to 0 and Result to drTimeout.
Dim box As New cDialogCountdownMsgBox
box.Title = "Backup"
box.CountdownSeconds = 3
box.AutoClose = False
box.Reset
Debug.Print box.Title ' Message
Debug.Print box.CountdownSeconds ' 10
Debug.Print box.AutoClose ' True
ShowConfirm
Shows a box with Yes, No and Cancel.
Syntax: object.ShowConfirm ( message [ , title [ , seconds ] ] ) As DialogResult
- message
- required The text of the box.
- title
- optional The title. The default is
Confirm. - seconds
- optional The time before the box closes. The default is 30.
Sets Message, Title, CountdownSeconds, Buttons (MB_YESNOCANCEL) and Icon (MB_ICONQUESTION), then calls ShowDialog. The other properties keep their values. The result is drYes, drNo, drCancel or drTimeout; Esc and the close button of the box give drCancel.
Dim box As New cDialogCountdownMsgBox
Select Case box.ShowConfirm("Overwrite the file?", "Save")
Case DialogResult.drYes: Debug.Print "Overwrite"
Case DialogResult.drNo: Debug.Print "Choose another name"
Case DialogResult.drCancel: Debug.Print "Cancelled"
Case DialogResult.drTimeout: Debug.Print "No answer"
End Select
ShowCustom
Shows a box with the buttons and the icon that are passed.
Syntax: object.ShowCustom ( message , title , buttons , icon [ , seconds ] ) As DialogResult
- message
- required The text of the box.
- title
- required The title.
- buttons
- required A Long, a MessageBoxButtons member.
- icon
- required A Long, a MessageBoxIcons member.
- seconds
- optional The time before the box closes. The default is 10.
Sets the five properties that correspond to the arguments, then calls ShowDialog. The arguments are numbers, not captions: the class does not offer button captions of its own.
Dim box As New cDialogCountdownMsgBox
Dim answer As DialogResult
answer = box.ShowCustom("Try the upload again?", "Upload", MB_RETRYCANCEL, MB_ICONEXCLAMATION, 20)
Debug.Print box.GetResultDescription()
ShowDialog
Shows the box that the properties describe.
Syntax: object.ShowDialog ( ) As DialogResult
Shows the box and waits until a button is pressed, the box is closed, or the time is up. The call combines Buttons, Icon and DefaultButton into the style, takes the time from CountdownSeconds when AutoClose is True (otherwise there is no limit), adds the countdown text when ShowProgress is True, and stores the answer in Result, which it also returns.
The box is modal. Enter presses DefaultButton. Esc and the close button end a box that has only OK (the result is drOK) or has a Cancel button (drCancel); a box with Yes and No only ignores both.
See Buttons for a button that is not mapped and CountdownSeconds for a time that is too long, and the warning at the top of the page for the timeout of a box with OK only.
Dim box As New cDialogCountdownMsgBox
box.Title = "Session"
box.Message = "Your session is about to end. Stay signed in?"
box.Buttons = MB_YESNO
box.Icon = MB_ICONQUESTION
box.DefaultButton = MB_DEFBUTTON1
box.CountdownSeconds = 30
If box.ShowDialog() = DialogResult.drYes Then
Debug.Print "Stay signed in"
Else
Debug.Print "Sign out"
End If
ShowError
Shows an error box with an OK button.
Syntax: object.ShowError ( message [ , title [ , seconds ] ] ) As DialogResult
- message
- required The text of the box.
- title
- optional The title. The default is
Error. - seconds
- optional The time before the box closes. The default is 20.
Sets Buttons to MB_OK and Icon to MB_ICONSTOP and the other three properties as ShowConfirm does, then calls ShowDialog. The result is drOK whether OK was pressed or the time ran out.
Dim box As New cDialogCountdownMsgBox
box.ShowError "The file could not be saved.", "Save"
ShowInfo
Shows an information box with an OK button.
Syntax: object.ShowInfo ( message [ , title [ , seconds ] ] ) As DialogResult
- message
- required The text of the box.
- title
- optional The title. The default is
Information. - seconds
- optional The time before the box closes. The default is 10.
Sets Buttons to MB_OK and Icon to MB_ICONINFORMATION and the other three properties as ShowConfirm does, then calls ShowDialog. The result is drOK whether OK was pressed or the time ran out.
Dim box As New cDialogCountdownMsgBox
box.ShowInfo "The report was exported.", "Export", 8
ShowQuestion
Shows a box with Yes and No.
Syntax: object.ShowQuestion ( message [ , title [ , seconds ] ] ) As DialogResult
- message
- required The text of the box.
- title
- optional The title. The default is
Question. - seconds
- optional The time before the box closes. The default is 30.
Sets Buttons to MB_YESNO and Icon to MB_ICONQUESTION and the other three properties as ShowConfirm does, then calls ShowDialog. The result is drYes, drNo or drTimeout. Esc and the close button of the box do nothing.
Dim box As New cDialogCountdownMsgBox
If box.ShowQuestion("Restart now?", "Update", 30) = DialogResult.drYes Then
Debug.Print "Restarting"
ElseIf box.IsTimedOut() Then
Debug.Print "No answer; restart later"
End If
ShowWarning
Shows a warning box with an OK button.
Syntax: object.ShowWarning ( message [ , title [ , seconds ] ] ) As DialogResult
- message
- required The text of the box.
- title
- optional The title. The default is
Warning. - seconds
- optional The time before the box closes. The default is 15.
Sets Buttons to MB_OK and Icon to MB_ICONEXCLAMATION and the other three properties as ShowConfirm does, then calls ShowDialog. The result is drOK whether OK was pressed or the time ran out.
Dim box As New cDialogCountdownMsgBox
box.ShowWarning "The disk is almost full.", "Disk"
Enumerations
The four enumerations are declared in the class and are used by their member names, such as MB_YESNO and DialogResult.drYes.
DialogResult
The result of a box.
| Member | Value | Meaning |
|---|---|---|
| drOK | 1 | OK. Also the result of a box with only OK that timed out |
| drCancel | 2 | Cancel, Esc or the close button |
| drAbort | 3 | Abort |
| drRetry | 4 | Retry |
| drIgnore | 5 | Ignore |
| drYes | 6 | Yes |
| drNo | 7 | No |
| drTimeout | 32000 | The time ran out |
MessageBoxButtons
The sets of buttons for Buttons.
| Member | Value | Buttons |
|---|---|---|
| MB_OK | 0 | OK |
| MB_OKCANCEL | 1 | OK, Cancel |
| MB_ABORTRETRYIGNORE | 2 | Abort, Retry, Ignore |
| MB_YESNOCANCEL | 3 | Yes, No, Cancel |
| MB_YESNO | 4 | Yes, No |
| MB_RETRYCANCEL | 5 | Retry, Cancel |
MessageBoxIcons
The icons for Icon.
| Member | Value | Icon |
|---|---|---|
| MB_ICONSTOP | 16 | A red circle with a cross |
| MB_ICONQUESTION | 32 | A question mark |
| MB_ICONEXCLAMATION | 48 | An exclamation mark |
| MB_ICONINFORMATION | 64 | The letter i |
MessageBoxDefaultButton
The default buttons for DefaultButton.
| Member | Value | Default button |
|---|---|---|
| MB_DEFBUTTON1 | 0 | The first button |
| MB_DEFBUTTON2 | 256 | The second button |
| MB_DEFBUTTON3 | 512 | The third button |
Example
This example asks a question that has a safe answer when nobody replies, and treats a timeout as the answer No.
Dim box As New cDialogCountdownMsgBox
Dim answer As DialogResult
box.Title = "Unsaved changes"
box.Message = "Close the document without saving?"
box.Buttons = MB_YESNO
box.Icon = MB_ICONEXCLAMATION
box.DefaultButton = MB_DEFBUTTON2
box.CountdownSeconds = 30
answer = box.ShowDialog()
If answer = DialogResult.drYes Then
Debug.Print "Closing without saving"
Else
Debug.Print "Keeping the document: " & box.GetResultDescription()
End If
See Also
- cDialogInputBox class – asks for one line of text
- cDialogProgress class – tracks the progress of a task
- TBMANLIB_Dialog package – overview