1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#![allow(non_snake_case)]

use crate::co;
use crate::comctl::ffi;
use crate::decl::*;
use crate::kernel::{ffi_types::*, privs::*};
use crate::ole::privs::*;

/// [`InitCommonControls`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/nf-commctrl-initcommoncontrols)
/// function.
pub fn InitCommonControls() {
	unsafe { ffi::InitCommonControls() }
}

/// [`InitCommonControlsEx`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/nf-commctrl-initcommoncontrolsex)
/// function.
pub fn InitCommonControlsEx(icce: &INITCOMMONCONTROLSEX) -> SysResult<()> {
	bool_to_sysresult(
		unsafe { ffi::InitCommonControlsEx(icce as *const _ as  _) }
	)
}

/// [`InitMUILanguage`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/nf-commctrl-initmuilanguage)
/// function.
pub fn InitMUILanguage(ui_lang: LANGID) {
	unsafe { ffi::InitMUILanguage(ui_lang.into()) }
}

/// [`TaskDialogIndirect`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/nf-commctrl-taskdialogindirect)
/// function.
///
/// Fill the [`TASKDIALOGCONFIG`](crate::TASKDIALOGCONFIG) fields you need, and
/// leave the others as default. The needed flags will be automatically set.
///
/// Returns:
/// 1. the ID of the button clicked by the user. If you passed custom
/// buttons in the `buttons` field, the corresponding ID will be wrapped in a
/// [`co::DLGID`](crate::co::DLGID) constant, whose `u16` can be retrieved by
/// calling [`co::DLGID::raw`](crate::co::DLGID::raw) method;
/// 2. the ID of the radio button selected by the user, if you used the
/// `radio_buttons` field;
/// 3. `true` if the custom check box is checked, if you used the
/// `verification_text` field.
///
/// [`HWND::TaskDialog`](crate::prelude::comctl_Hwnd::TaskDialog) is a simpler
/// version of this function.
///
/// # Examples
///
/// Simple information dialog:
///
/// ```no_run
/// use winsafe::{self as w, prelude::*, co};
///
/// w::TaskDialogIndirect(&w::TASKDIALOGCONFIG {
///     common_buttons: co::TDCBF::OK,
///     main_icon: w::IconIdTd::Td(co::TD_ICON::INFORMATION),
///     flags: co::TDF::ALLOW_DIALOG_CANCELLATION,
///     window_title: Some("Title"),
///     content: Some("Content"),
///     ..Default::default()
/// })?;
/// # w::HrResult::Ok(())
/// ```
///
/// OK/Cancel confirmation:
///
/// ```no_run
/// use winsafe::{self as w, prelude::*, co};
///
/// let (ret, _, _) = w::TaskDialogIndirect(&w::TASKDIALOGCONFIG {
///     common_buttons: co::TDCBF::OK | co::TDCBF::CANCEL,
///     main_icon: w::IconIdTd::Td(co::TD_ICON::WARNING),
///     flags: co::TDF::ALLOW_DIALOG_CANCELLATION,
///     window_title: Some("Title"),
///     content: Some("Do you want?"),
///     ..Default::default()
/// })?;
///
/// if ret == co::DLGID::OK {
///    println!("Yes.");
/// }
/// # w::HrResult::Ok(())
/// ```
pub fn TaskDialogIndirect(
	config: &TASKDIALOGCONFIG,
) -> HrResult<(co::DLGID, u16, bool)>
{
	let buf = config.to_raw();
	let mut pn_button = i32::default();
	let mut pn_radio_button = i32::default();
	let mut pf_bool: BOOL = 0;

	ok_to_hrresult(
		unsafe {
			ffi::TaskDialogIndirect(
				&buf.raw as *const _ as _,
				&mut pn_button,
				&mut pn_radio_button,
				&mut pf_bool,
			)
		},
	)?;

	Ok((
		unsafe { co::DLGID::from_raw(pn_button as _) },
		pn_radio_button as _,
		pf_bool != 0,
	))
}