1 /**
2  * Standard message boxes.
3  *
4  * A thin wrapper over `MessageBoxW` that maps a small style enum to the right
5  * icon and buttons and returns a `DialogResult`. The native message box is
6  * fully accessible — screen readers announce the title, icon, message and
7  * buttons automatically.
8  */
9 module deft.controls.messagebox;
10 
11 version (Windows):
12 
13 import core.sys.windows.windows;
14 
15 import deft.controls.dialog : DialogResult;
16 import deft.util.strings;
17 import deft.widget : Widget;
18 
19 /// The icon (and, for `question`, the buttons) a message box shows.
20 enum MessageBoxStyle
21 {
22 	/// Informational message with an "i" icon and an OK button.
23 	info,
24 	/// Warning with a "!" icon and an OK button.
25 	warning,
26 	/// Error with a stop icon and an OK button.
27 	error,
28 	/// Question with a "?" icon and Yes/No buttons.
29 	question,
30 }
31 
32 /**
33  * Show a modal message box owned by `parent`.
34  *
35  * `info`, `warning` and `error` show a single OK button (returning
36  * `DialogResult.ok`); `question` shows Yes/No (returning `DialogResult.yes` or
37  * `DialogResult.no`). Closing the box maps to `cancel`/`no` as the platform
38  * dictates.
39  */
40 DialogResult showMessageBox(Widget parent, string text, string title,
41 	MessageBoxStyle style)
42 {
43 	HWND owner = parent !is null && parent.handle !is null
44 		? GetAncestor(parent.handle, GA_ROOT) : null;
45 
46 	UINT flags;
47 	final switch (style)
48 	{
49 	case MessageBoxStyle.info:
50 		flags = MB_OK | MB_ICONINFORMATION;
51 		break;
52 	case MessageBoxStyle.warning:
53 		flags = MB_OK | MB_ICONWARNING;
54 		break;
55 	case MessageBoxStyle.error:
56 		flags = MB_OK | MB_ICONERROR;
57 		break;
58 	case MessageBoxStyle.question:
59 		flags = MB_YESNO | MB_ICONQUESTION;
60 		break;
61 	}
62 
63 	int result = MessageBoxW(owner, text.toWStringz, title.toWStringz, flags);
64 	switch (result)
65 	{
66 	case IDOK:
67 		return DialogResult.ok;
68 	case IDYES:
69 		return DialogResult.yes;
70 	case IDNO:
71 		return DialogResult.no;
72 	default:
73 		return DialogResult.cancel;
74 	}
75 }