winsafe\comctl/
structs.rs

1#![allow(non_camel_case_types, non_snake_case)]
2
3use std::marker::PhantomData;
4
5use crate::co;
6use crate::comctl::{callbacks, privs::*};
7use crate::decl::*;
8use crate::kernel::{ffi_types::*, privs::*};
9use crate::macros::*;
10use crate::prelude::*;
11
12/// [`BUTTON_IMAGELIST`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-button_imagelist)
13/// struct.
14#[repr(C)]
15pub struct BUTTON_IMAGELIST {
16	pub himl: HIMAGELIST,
17	pub margin: RECT,
18	pub uAlign: co::BIA,
19}
20
21/// [`BUTTON_SPLITINFO`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-button_splitinfo)
22/// struct.
23#[repr(C)]
24pub struct BUTTON_SPLITINFO {
25	pub mask: co::BCSIF,
26	pub himlGlyph: HIMAGELIST,
27	pub uSplitStyle: co::BCSS,
28	pub size: SIZE,
29}
30
31/// [`COLORSCHEME`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-colorscheme)
32/// struct.
33#[repr(C)]
34pub struct COLORSCHEME {
35	dwSize: u32,
36	pub clrBtnHighlight: COLORREF,
37	pub clrBtnShadow: COLORREF,
38}
39
40impl_default!(COLORSCHEME, dwSize);
41
42/// [`DATETIMEPICKERINFO`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-datetimepickerinfo)
43/// struct.
44#[repr(C)]
45pub struct DATETIMEPICKERINFO {
46	cbSize: u32,
47	pub rcCheck: RECT,
48	pub stateCheck: co::STATE_SYSTEM,
49	pub rcButton: RECT,
50	pub stateButton: co::STATE_SYSTEM,
51	pub hwndEdit: HWND,
52	pub hwndUD: HWND,
53	pub hwndDropDown: HWND,
54}
55
56impl_default!(DATETIMEPICKERINFO, cbSize);
57
58/// [`EDITBALLOONTIP`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-editballoontip)
59/// struct.
60#[repr(C)]
61pub struct EDITBALLOONTIP<'a, 'b> {
62	cbStruct: u32,
63	pszTitle: *mut u16,
64	pszText: *mut u16,
65	pub ttiIcon: co::TTI,
66
67	_pszTitle: PhantomData<&'a mut u16>,
68	_pszText: PhantomData<&'b mut u16>,
69}
70
71impl_default!(EDITBALLOONTIP, cbStruct, 'a, 'b);
72
73impl<'a, 'b> EDITBALLOONTIP<'a, 'b> {
74	pub_fn_string_ptr_get_set!('a, pszTitle, set_pszTitle);
75	pub_fn_string_ptr_get_set!('b, pszText, set_pszText);
76}
77
78/// [`HDITEM`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-hditemw)
79/// struct.
80#[repr(C)]
81pub struct HDITEM<'a> {
82	pub mask: co::HDI,
83	pub cxy: i32,
84	pszText: *mut u16,
85	pub hbm: HBITMAP,
86	cchTextMax: i32,
87	pub fmt: co::HDF,
88	pub lParam: isize,
89	pub iImage: i32,
90	pub iOrder: i32,
91	pub typeFilter: co::HDFT,
92	pub pvFilter: *mut std::ffi::c_void,
93	pub state: co::HDIS,
94
95	_pszText: PhantomData<&'a mut u16>,
96}
97
98impl_default!(HDITEM, 'a);
99
100impl<'a> HDITEM<'a> {
101	pub_fn_string_buf_get_set!('a, pszText, set_pszText, raw_pszText, cchTextMax);
102}
103
104/// [`HDHITTESTINFO`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-hdhittestinfo)
105/// struct.
106#[repr(C)]
107#[derive(Default)]
108pub struct HDHITTESTINFO {
109	pub pt: POINT,
110	pub flags: co::HHT,
111	pub iItem: i32,
112}
113
114/// [`HDLAYOUT`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-hdlayout)
115/// struct.
116#[repr(C)]
117pub struct HDLAYOUT<'a, 'b> {
118	prc: *mut RECT,
119	pwpos: *mut WINDOWPOS,
120
121	_prc: PhantomData<&'a mut RECT>,
122	_pwpos: PhantomData<&'b mut WINDOWPOS>,
123}
124
125impl_default!(HDLAYOUT, 'a, 'b);
126
127impl<'a, 'b> HDLAYOUT<'a, 'b> {
128	pub_fn_ptr_get_set!('a, prc, set_prc, RECT);
129	pub_fn_ptr_get_set!('b, pwpos, set_pwpos, WINDOWPOS);
130}
131
132/// [`INITCOMMONCONTROLSEX`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-initcommoncontrolsex)
133/// struct
134#[repr(C)]
135pub struct INITCOMMONCONTROLSEX {
136	dwSize: u32,
137	pub icc: co::ICC,
138}
139
140impl_default!(INITCOMMONCONTROLSEX, dwSize);
141
142/// [`LITEM`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-litem)
143/// struct.
144#[repr(C)]
145pub struct LITEM {
146	pub mask: co::LIF,
147	pub iLink: i32,
148	pub state: co::LIS,
149	pub stateMask: co::LIS,
150	szID: [u16; MAX_LINKID_TEXT],
151	szUrl: [u16; L_MAX_URL_LENGTH],
152}
153
154impl_default!(LITEM);
155
156impl LITEM {
157	pub_fn_string_arr_get_set!(szID, set_szID);
158	pub_fn_string_arr_get_set!(szUrl, set_szUrl);
159}
160
161/// [`LVBKIMAGE`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-lvbkimagew)
162/// struct.
163#[repr(C)]
164pub struct LVBKIMAGE<'a> {
165	pub uFlags: co::LVBKIF,
166	pub hbm: HBITMAP,
167	pszImage: *mut u16,
168	cchImageMax: u32,
169	pub xOffsetPercent: i32,
170	pub yOffsetPercent: i32,
171
172	_pszImage: PhantomData<&'a mut u16>,
173}
174
175impl_default!(LVBKIMAGE, 'a);
176
177impl<'a> LVBKIMAGE<'a> {
178	pub_fn_string_buf_get_set!('a, pszImage, set_pszImage, raw_pszImage, cchImageMax);
179}
180
181/// [`LVCOLUMN`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-lvcolumnw)
182/// struct.
183#[repr(C)]
184pub struct LVCOLUMN<'a> {
185	pub mask: co::LVCF,
186	pub fmt: co::LVCFMT_C,
187	pub cx: i32,
188	pszText: *mut u16,
189	cchTextMax: i32,
190	pub iSubItem: i32,
191	pub iImage: i32,
192	pub iOrder: i32,
193	pub cxMin: i32,
194	pub cxDefault: i32,
195	pub cxIdeal: i32,
196
197	_pszText: PhantomData<&'a mut u16>,
198}
199
200impl_default!(LVCOLUMN, 'a);
201
202impl<'a> LVCOLUMN<'a> {
203	pub_fn_string_buf_get_set!('a, pszText, set_pszText, raw_pszText, cchTextMax);
204}
205
206/// [`LVFINDINFO`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-lvfindinfow)
207/// struct.
208#[repr(C)]
209pub struct LVFINDINFO<'a> {
210	pub flags: co::LVFI,
211	psz: *mut u16,
212	pub lParam: isize,
213	pub pt: POINT,
214	pub vkDirection: co::VK_DIR,
215
216	_psz: PhantomData<&'a mut u16>,
217}
218
219impl_default!(LVFINDINFO, 'a);
220
221impl<'a> LVFINDINFO<'a> {
222	pub_fn_string_ptr_get_set!('a, psz, set_psz);
223}
224
225/// [`LVFOOTERINFO`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-lvfooterinfo)
226/// struct.
227#[repr(C)]
228pub struct LVFOOTERINFO<'a> {
229	pub mask: co::LVFF,
230	pszText: *mut u16,
231	cchTextMax: i32,
232	pub cItems: u32,
233
234	_pszText: PhantomData<&'a mut u16>,
235}
236
237impl_default!(LVFOOTERINFO, 'a);
238
239impl<'a> LVFOOTERINFO<'a> {
240	pub_fn_string_buf_get_set!('a, pszText, set_pszText, raw_pszText, cchTextMax);
241}
242
243/// [`LVFOOTERITEM`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-lvfooteritem)
244/// struct.
245#[repr(C)]
246pub struct LVFOOTERITEM<'a> {
247	pub mask: co::LVFIF,
248	pub iItem: i32,
249	pszText: *mut u16,
250	cchTextMax: i32,
251	pub state: co::LVFIS,
252	pub stateMask: co::LVFIS,
253
254	_pszText: PhantomData<&'a mut u16>,
255}
256
257impl_default!(LVFOOTERITEM, 'a);
258
259impl<'a> LVFOOTERITEM<'a> {
260	pub_fn_string_buf_get_set!('a, pszText, set_pszText, raw_pszText, cchTextMax);
261}
262
263/// [`LVGROUP`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-lvgroup)
264/// struct.
265#[repr(C)]
266pub struct LVGROUP<'a, 'b, 'c, 'd, 'e, 'f, 'g> {
267	cbSize: u32,
268	pub mask: co::LVGF,
269	pszHeader: *mut u16,
270	cchHeader: i32,
271	pszFooter: *mut u16,
272	cchFooter: i32,
273	pub iGroupId: i32,
274	pub stateMask: co::LVGS,
275	pub state: co::LVGS,
276	pub uAlign: co::LVGA_FH,
277	pszSubtitle: *mut u16,
278	cchSubtitle: i32,
279	pszTask: *mut u16,
280	cchTask: i32,
281	pszDescriptionTop: *mut u16,
282	cchDescriptionTop: i32,
283	pszDescriptionBottom: *mut u16,
284	cchDescriptionBottom: i32,
285	pub iTitleImage: i32,
286	pub iExtendedImage: i32,
287	pub iFirstItem: i32,
288	pub cItems: u32,
289	pszSubsetTitle: *mut u16,
290	cchSubsetTitle: i32,
291
292	_pszHeader: PhantomData<&'a mut u16>,
293	_pszFooter: PhantomData<&'b mut u16>,
294	_pszSubtitle: PhantomData<&'c mut u16>,
295	_pszTask: PhantomData<&'d mut u16>,
296	_pszDescriptionTop: PhantomData<&'e mut u16>,
297	_pszDescriptionBottom: PhantomData<&'f mut u16>,
298	_pszSubsetTitle: PhantomData<&'g mut u16>,
299}
300
301impl_default!(LVGROUP, cbSize, 'a, 'b, 'c, 'd, 'e, 'f, 'g);
302
303impl<'a, 'b, 'c, 'd, 'e, 'f, 'g> LVGROUP<'a, 'b, 'c, 'd, 'e, 'f, 'g> {
304	pub_fn_string_buf_get_set!('a, pszHeader, set_pszHeader, raw_pszHeader, cchHeader);
305	pub_fn_string_buf_get_set!('b, pszFooter, set_pszFooter, raw_pszFooter, cchFooter);
306	pub_fn_string_buf_get_set!('c, pszSubtitle, set_pszSubtitle, raw_pszSubtitle, cchSubtitle);
307	pub_fn_string_buf_get_set!('d, pszTask, set_pszTask, raw_pszTask, cchTask);
308	pub_fn_string_buf_get_set!('e, pszDescriptionTop, set_pszDescriptionTop, raw_pszDescriptionTop, cchDescriptionTop);
309	pub_fn_string_buf_get_set!('f, pszDescriptionBottom, set_pszDescriptionBottom, raw_pszDescriptionBottom, cchDescriptionBottom);
310	pub_fn_string_buf_get_set!('g, pszSubsetTitle, set_pszSubsetTitle, raw_pszSubsetTitle, cchSubsetTitle);
311}
312
313/// [`LVGROUPMETRICS`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-lvgroupmetrics)
314/// struct.
315#[repr(C)]
316pub struct LVGROUPMETRICS {
317	cbSize: u32,
318	pub mask: co::LVGMF,
319	pub Left: u32,
320	pub Top: u32,
321	pub Right: u32,
322	pub Bottom: u32,
323	pub crLeft: COLORREF,
324	pub crTop: COLORREF,
325	pub crRight: COLORREF,
326	pub crBottom: COLORREF,
327	pub crHeader: COLORREF,
328	pub crFooter: COLORREF,
329}
330
331impl_default!(LVGROUPMETRICS, cbSize);
332
333/// [`LVHITTESTINFO`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-lvhittestinfo)
334/// struct.
335#[repr(C)]
336#[derive(Default)]
337pub struct LVHITTESTINFO {
338	pub pt: POINT,
339	pub flags: co::LVHT,
340	pub iItem: i32,
341	pub iSubItem: i32,
342	pub iGroup: i32,
343}
344
345/// [`LVINSERTGROUPSORTED`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-lvinsertgroupsorted)
346/// struct.
347#[repr(C)]
348pub struct LVINSERTGROUPSORTED<'a, 'b, 'c, 'd, 'e, 'f, 'g> {
349	pub pfnGroupCompare: Option<PFNLVGROUPCOMPARE>,
350	pub pvData: usize,
351	pub lvGroup: LVGROUP<'a, 'b, 'c, 'd, 'e, 'f, 'g>,
352}
353
354impl<'a, 'b, 'c, 'd, 'e, 'f, 'g> Default for LVINSERTGROUPSORTED<'a, 'b, 'c, 'd, 'e, 'f, 'g> {
355	fn default() -> Self {
356		Self {
357			pfnGroupCompare: None,
358			pvData: 0,
359			lvGroup: LVGROUP::default(), // has cbSize, so we can't use impl_default_size macro
360		}
361	}
362}
363
364/// [`LVINSERTMARK`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-lvinsertmark)
365/// struct.
366#[repr(C)]
367pub struct LVINSERTMARK {
368	cbSize: u32,
369	pub dwFlags: co::LVIM,
370	pub iItem: i32,
371	dwReserved: u32,
372}
373
374impl_default!(LVINSERTMARK);
375
376/// [`LVITEM`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-lvitemw)
377/// struct.
378#[repr(C)]
379pub struct LVITEM<'a> {
380	pub mask: co::LVIF,
381	pub iItem: i32,
382	pub iSubItem: i32,
383	pub state: co::LVIS,
384	pub stateMask: co::LVIS,
385	pszText: *mut u16,
386	cchTextMax: i32,
387	pub iImage: i32,
388	pub lParam: isize,
389	pub iIndent: i32,
390	pub iGroupId: co::LVI_GROUPID,
391	pub cColumns: u32,
392	pub puColumns: *mut i32,
393	pub piColFmt: *mut co::LVCFMT_I,
394	pub iGroup: i32,
395
396	_pszText: PhantomData<&'a mut u16>,
397}
398
399impl_default!(LVITEM, 'a);
400
401impl<'a> LVITEM<'a> {
402	pub_fn_string_buf_get_set!('a, pszText, set_pszText, raw_pszText, cchTextMax);
403}
404
405/// [`LVITEMINDEX`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-lvitemindex)
406/// struct.
407#[repr(C)]
408#[derive(Default, Clone, Copy, PartialEq, Eq)]
409pub struct LVITEMINDEX {
410	pub iItem: i32,
411	pub iGroup: i32,
412}
413
414/// [`LVSETINFOTIP`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-lvsetinfotip)
415/// struct.
416#[repr(C)]
417pub struct LVSETINFOTIP<'a> {
418	cbSize: u32,
419	pub dwFlags: u32, // unspecified
420	pszText: *mut u16,
421	pub iItem: i32,
422	pub iSubItem: i32,
423
424	_pszText: PhantomData<&'a mut u16>,
425}
426
427impl_default!(LVSETINFOTIP, cbSize, 'a);
428
429impl<'a> LVSETINFOTIP<'a> {
430	pub_fn_string_ptr_get_set!('a, pszText, set_pszText);
431}
432
433/// [`LVTILEINFO`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-lvtileinfo)
434/// struct.
435#[repr(C)]
436pub struct LVTILEINFO<'a> {
437	cbSize: u32,
438	pub iItem: i32,
439	cColumns: u32,
440	puColumns: *mut u32,
441	piColFmt: *mut co::LVCFMT_C,
442
443	_puColumns: PhantomData<&'a mut u32>,
444}
445
446impl_default!(LVTILEINFO, cbSize, 'a);
447
448impl<'a> LVTILEINFO<'a> {
449	/// Returns the `puColumns` field.
450	#[must_use]
451	pub const fn puColumns(&self) -> Option<&'a mut [u32]> {
452		unsafe {
453			match self.puColumns.as_mut() {
454				Some(_) => Some(std::slice::from_raw_parts_mut(self.puColumns, self.cColumns as _)),
455				None => None,
456			}
457		}
458	}
459
460	/// Returns the `piColFmt` field.
461	#[must_use]
462	pub const fn piColFmt(&self) -> Option<&'a mut [co::LVCFMT_C]> {
463		unsafe {
464			match self.puColumns.as_mut() {
465				Some(_) => Some(std::slice::from_raw_parts_mut(self.piColFmt, self.cColumns as _)),
466				None => None,
467			}
468		}
469	}
470
471	/// Sets the `puColumns` and `piColFmt` fields.
472	///
473	/// # Panics
474	///
475	/// Panics if `puColumns` and `piColFmt` slices have different lengths.
476	pub fn set_puColumns_piColFmt(&mut self, val: Option<(&'a mut [u32], &'a mut [co::LVCFMT_C])>) {
477		if let Some(val) = val {
478			if val.0.len() != val.1.len() {
479				panic!("Different slice lengths: {} and {}.", val.0.len(), val.1.len());
480			}
481			self.cColumns = val.0.len() as _;
482			self.puColumns = val.0.as_mut_ptr();
483			self.piColFmt = val.1.as_mut_ptr();
484		} else {
485			self.cColumns = 0;
486			self.puColumns = std::ptr::null_mut();
487			self.piColFmt = std::ptr::null_mut();
488		}
489	}
490}
491
492/// [`LVTILEVIEWINFO`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-lvtileviewinfo)
493/// struct.
494#[repr(C)]
495pub struct LVTILEVIEWINFO {
496	cbSize: u32,
497	pub dwMask: co::LVTVIM,
498	pub dwFlags: co::LVTVIF,
499	pub sizeTile: SIZE,
500	pub cLines: i32,
501	pub rcLabelMargin: RECT,
502}
503
504impl_default!(LVTILEVIEWINFO, cbSize);
505
506/// [`MCGRIDINFO`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-mcgridinfo)
507/// struct.
508#[repr(C)]
509pub struct MCGRIDINFO<'a> {
510	cbSize: u32,
511	pub dwPart: co::MCGIP,
512	pub dwFlags: co::MCGIF,
513	pub iCalendar: i32,
514	pub iRow: i32,
515	pub iCol: i32,
516	bSelected: BOOL,
517	pub stStart: SYSTEMTIME,
518	pub stEnd: SYSTEMTIME,
519	pub rc: RECT,
520	pszName: *mut u16,
521	cchName: usize,
522
523	_pszName: PhantomData<&'a mut u16>,
524}
525
526impl_default!(MCGRIDINFO, cbSize, 'a);
527
528impl<'a> MCGRIDINFO<'a> {
529	pub_fn_bool_get_set!(bSelected, set_bSelected);
530	pub_fn_string_buf_get_set!('a, pszName, set_pszName, raw_pszName, cchName);
531}
532
533/// [`MCHITTESTINFO`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-mchittestinfo)
534/// struct.
535#[repr(C)]
536pub struct MCHITTESTINFO {
537	cbSize: u32,
538	pub pt: POINT,
539	pub uHit: co::MCHT,
540	pub st: SYSTEMTIME,
541	pub rc: RECT,
542	pub iOffset: i32,
543	pub iRow: i32,
544	pub iCol: i32,
545}
546
547impl_default!(MCHITTESTINFO, cbSize);
548
549/// [`MONTHDAYSTATE`](https://learn.microsoft.com/en-us/windows/win32/controls/monthdaystate)
550/// struct.
551#[repr(transparent)]
552#[derive(Default, Clone, Copy, PartialEq, Eq)]
553pub struct MONTHDAYSTATE(u32);
554
555impl MONTHDAYSTATE {
556	/// Returns the state of the bit corresponding to the given day index.
557	///
558	/// # Panics
559	///
560	/// Panics if `index` is greater than 31.
561	#[must_use]
562	pub fn get_day(&self, index: u8) -> bool {
563		if index > 31 {
564			panic!("MONTHDAYSTATE max index is 31, tried to get {}.", index)
565		} else {
566			((self.0 >> index) & 1) != 0
567		}
568	}
569
570	/// Sets the state of the bit corresponding to the given day index.
571	///
572	/// # Panics
573	///
574	/// Panics if `index` is greater than 31.
575	pub fn set_day(&mut self, index: u8, state: bool) {
576		if index > 31 {
577			panic!("MONTHDAYSTATE max index is 31, tried to set {}.", index)
578		} else if state {
579			self.0 |= 1 << index;
580		} else {
581			self.0 &= !(1 << index);
582		}
583	}
584}
585
586/// [`NMBCDROPDOWN`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-nmbcdropdown)
587/// struct.
588#[repr(C)]
589pub struct NMBCDROPDOWN {
590	pub hdr: NMHDR,
591	pub rcButton: RECT,
592}
593
594/// [`NMBCHOTITEM`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-nmbchotitem)
595/// struct.
596#[repr(C)]
597pub struct NMBCHOTITEM {
598	pub hdr: NMHDR,
599	pub dwFlags: co::HICF,
600}
601
602/// [`NMCHAR`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-nmchar)
603/// struct.
604#[repr(C)]
605pub struct NMCHAR {
606	pub hdr: NMHDR,
607	pub ch: u32,
608	pub dwItemPrev: u32,
609	pub dwItemNext: u32,
610}
611
612/// [`NMCUSTOMDRAW`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-nmcustomdraw)
613/// struct.
614#[repr(C)]
615pub struct NMCUSTOMDRAW {
616	pub hdr: NMHDR,
617	pub dwDrawStage: co::CDDS,
618	pub hdc: HDC,
619	pub rc: RECT,
620	pub dwItemSpec: usize,
621	pub uItemState: co::CDIS,
622	pub lItemlParam: isize,
623}
624
625/// [`NMDATETIMECHANGE`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-nmdatetimechange)
626/// struct.
627#[repr(C)]
628pub struct NMDATETIMECHANGE {
629	pub nmhdr: NMHDR,
630	pub dwFlags: co::GDT,
631	pub st: SYSTEMTIME,
632}
633
634/// [`NMDATETIMEFORMAT`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-nmdatetimeformatw)
635/// struct.
636#[repr(C)]
637pub struct NMDATETIMEFORMAT<'a> {
638	pub nmhdr: NMHDR,
639	pszFormat: *mut u16,
640	pub st: SYSTEMTIME,
641	pszDisplay: *mut u16,
642	szDisplay: [u16; 64], // used as a buffer to pszDisplay
643
644	_pszFormat: PhantomData<&'a mut u16>,
645}
646
647impl_default!(NMDATETIMEFORMAT, 'a);
648
649impl<'a> NMDATETIMEFORMAT<'a> {
650	pub_fn_string_ptr_get_set!('a, pszFormat, set_pszFormat);
651
652	/// Returns the `pszDisplay` field.
653	#[must_use]
654	pub fn pszDisplay(&self) -> String {
655		unsafe { WString::from_wchars_nullt(self.pszDisplay) }.to_string()
656	}
657
658	/// Sets the `pszDisplay` field.
659	pub fn set_pszDisplay(&mut self, text: &str) {
660		WString::from_str(text).copy_to_slice(&mut self.szDisplay);
661	}
662}
663
664/// [`NMDATETIMEFORMATQUERY`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-nmdatetimeformatqueryw)
665/// struct.
666#[repr(C)]
667pub struct NMDATETIMEFORMATQUERY<'a> {
668	pub nmhdr: NMHDR,
669	pszFormat: *mut u16,
670	pub szMax: SIZE,
671
672	_pszFormat: PhantomData<&'a mut u16>,
673}
674
675impl_default!(NMDATETIMEFORMATQUERY, 'a);
676
677impl<'a> NMDATETIMEFORMATQUERY<'a> {
678	pub_fn_string_ptr_get_set!('a, pszFormat, set_pszFormat);
679}
680
681/// [`NMDATETIMESTRING`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-nmdatetimestringw)
682/// struct.
683#[repr(C)]
684pub struct NMDATETIMESTRING<'a> {
685	pub nmhdr: NMHDR,
686	pszUserString: *mut u16,
687	pub st: SYSTEMTIME,
688	pub dwFlags: co::GDT,
689
690	_pszUserString: PhantomData<&'a mut u16>,
691}
692
693impl_default!(NMDATETIMESTRING, 'a);
694
695impl<'a> NMDATETIMESTRING<'a> {
696	pub_fn_string_ptr_get_set!('a, pszUserString, set_pszUserString);
697}
698
699/// [`NMDATETIMEWMKEYDOWN`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-nmdatetimewmkeydownw)
700/// struct.
701#[repr(C)]
702pub struct NMDATETIMEWMKEYDOWN<'a> {
703	pub nmhdr: NMHDR,
704	pub nVirtKey: i32,
705	pszFormat: *mut u16,
706	pub st: SYSTEMTIME,
707
708	_pszFormat: PhantomData<&'a mut u16>,
709}
710
711impl_default!(NMDATETIMEWMKEYDOWN, 'a);
712
713impl<'a> NMDATETIMEWMKEYDOWN<'a> {
714	pub_fn_string_ptr_get_set!('a, pszFormat, set_pszFormat);
715}
716
717/// [`NMDAYSTATE`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-nmdaystate)
718/// struct.
719#[repr(C)]
720pub struct NMDAYSTATE<'a> {
721	pub nmhdr: NMHDR,
722	pub stStart: SYSTEMTIME,
723	cDayState: i32,
724	prgDayState: *mut MONTHDAYSTATE,
725
726	_prgDayState: PhantomData<&'a mut MONTHDAYSTATE>,
727}
728
729impl_default!(NMDAYSTATE, 'a);
730
731impl<'a> NMDAYSTATE<'a> {
732	pub_fn_array_buf_get_set!('a, prgDayState, set_prgDayState, cDayState, MONTHDAYSTATE);
733}
734
735/// [`NMHDDISPINFO`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-nmhddispinfow)
736/// struct.
737#[repr(C)]
738pub struct NMHDDISPINFO<'a> {
739	pub hdr: NMHDR,
740	pub iItem: i32,
741	pub mask: co::HDI,
742	pszText: *mut u16,
743	cchTextMax: i32,
744	pub iImage: i32,
745	pub lParam: isize,
746
747	_pszText: PhantomData<&'a mut u16>,
748}
749
750impl_default!(NMHDDISPINFO, 'a);
751
752impl<'a> NMHDDISPINFO<'a> {
753	pub_fn_string_buf_get_set!('a, pszText, set_pszText, raw_pszText, cchTextMax);
754}
755
756/// [`NMHDFILTERBTNCLICK`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-nmhdfilterbtnclick)
757/// struct.
758#[repr(C)]
759pub struct NMHDFILTERBTNCLICK {
760	pub hdr: NMHDR,
761	pub iItem: i32,
762	pub rc: RECT,
763}
764
765impl_default!(NMHDFILTERBTNCLICK);
766
767/// [`NMHDR`](https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-nmhdr)
768/// struct.
769#[repr(C)]
770#[derive(PartialEq, Eq)]
771pub struct NMHDR {
772	/// A window handle to the control sending the message.
773	pub hwndFrom: HWND,
774	idFrom: usize,
775	/// Notification code sent in
776	/// [`WM_NOTIFY`](https://learn.microsoft.com/en-us/windows/win32/controls/wm-notify).
777	pub code: NmhdrCode,
778}
779
780impl_default!(NMHDR);
781
782impl NMHDR {
783	/// Returns the `idFrom` field, the ID of the control sending the message.
784	#[must_use]
785	pub const fn idFrom(&self) -> u16 {
786		self.idFrom as _
787	}
788
789	/// Sets the `idFrom` field, the ID of the control sending the message.
790	pub const fn set_idFrom(&mut self, val: u16) {
791		self.idFrom = val as _
792	}
793}
794
795/// Notification code returned in [`NMHDR`](crate::NMHDR) struct. This code is
796/// convertible to/from the specific common control notification codes –
797/// [`LVN`](crate::co::LVN), [`TVN`](crate::co::TVN), etc.
798///
799/// # Examples
800///
801/// ```no_run
802/// use winsafe::{self as w, prelude::*, co};
803///
804/// // Convert LVN to NmhrCode:
805/// let code = w::NmhdrCode::from(co::LVN::ITEMCHANGED);
806///
807/// // Convert NmhrCode to LVN – fails it code is not a valid LVN:
808/// let lvn = co::LVN::try_from(code)?;
809/// # w::SysResult::Ok(())
810/// ```
811#[repr(transparent)]
812#[derive(Default, Clone, Copy, PartialEq, Eq)]
813pub struct NmhdrCode(i32);
814
815impl From<i32> for NmhdrCode {
816	fn from(v: i32) -> Self {
817		Self(v)
818	}
819}
820
821impl PartialOrd for NmhdrCode {
822	fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
823		self.0.partial_cmp(&other.0)
824	}
825}
826impl Ord for NmhdrCode {
827	fn cmp(&self, other: &Self) -> std::cmp::Ordering {
828		self.0.cmp(&other.0)
829	}
830}
831
832impl std::fmt::Display for NmhdrCode {
833	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
834		write!(f, "{}", self.0)
835	}
836}
837
838impl NmhdrCode {
839	#[must_use]
840	pub(crate) const fn from_code(v: i32) -> Self {
841		Self(v)
842	}
843
844	/// Returns the primitive integer underlying value.
845	///
846	/// This method is similar to [`Into`](std::convert::Into), but it is
847	/// `const`, therefore it can be used in
848	/// [const contexts](https://doc.rust-lang.org/reference/const_eval.html).
849	#[must_use]
850	pub const fn raw(&self) -> i32 {
851		self.0
852	}
853}
854
855/// [`NMHEADER`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-nmheaderw)
856/// struct.
857#[repr(C)]
858pub struct NMHEADER<'a> {
859	pub hdr: NMHDR,
860	pub iItem: i32,
861	pub iButton: i32,
862	pitem: *mut HDITEM<'a>,
863
864	_pitem: PhantomData<&'a mut HDITEM<'a>>,
865}
866
867impl_default!(NMHEADER, 'a);
868
869impl<'a> NMHEADER<'a> {
870	pub_fn_ptr_get_set!('a, pitem, set_pitem, HDITEM<'a>);
871}
872
873/// [`NMITEMACTIVATE`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-nmitemactivate)
874/// struct.
875#[repr(C)]
876pub struct NMITEMACTIVATE {
877	pub hdr: NMHDR,
878	pub iItem: i32,
879	pub iSubItem: i32,
880	pub uNewState: co::LVIS,
881	pub uOldState: co::LVIS,
882	pub uChanged: co::LVIF,
883	pub ptAction: POINT,
884	pub lParam: isize,
885	pub uKeyFlags: co::LVKF,
886}
887
888/// [`NMOBJECTNOTIFY`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-nmobjectnotify)
889/// struct.
890#[repr(C)]
891pub struct NMOBJECTNOTIFY<'a> {
892	pub hdr: NMHDR,
893	pub iItem: i32,
894	piid: *mut co::IID,
895	Object: COMPTR,
896	pub hrResult: co::HRESULT,
897	pub dwFlags: u32,
898
899	_piid: PhantomData<&'a mut co::IID>,
900}
901
902impl_default!(NMOBJECTNOTIFY, 'a);
903impl_drop_comptr!(Object, NMOBJECTNOTIFY, 'a);
904
905impl<'a> NMOBJECTNOTIFY<'a> {
906	pub_fn_ptr_get_set!('a, piid, set_piid, co::IID);
907	pub_fn_comptr_get_set!(Object, set_Object, ole_IUnknown);
908}
909
910/// [`NMIPADDRESS`](https://learn.microsoft.com/en-us/windows/win32/api/Commctrl/ns-commctrl-nmipaddress)
911/// struct.
912#[repr(C)]
913pub struct NMIPADDRESS {
914	pub hdr: NMHDR,
915	pub iField: i32,
916	pub iValue: i32,
917}
918
919/// [`NMLINK`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-nmlink)
920/// struct.
921#[repr(C)]
922pub struct NMLINK {
923	pub hdr: NMHDR,
924	pub item: LITEM,
925}
926
927/// [`NMLISTVIEW`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-nmlistview)
928/// struct.
929#[repr(C)]
930pub struct NMLISTVIEW {
931	pub hdr: NMHDR,
932	pub iItem: i32,
933	pub iSubItem: i32,
934	pub uNewState: co::LVIS,
935	pub uOldState: co::LVIS,
936	pub uChanged: co::LVIF,
937	pub ptAction: POINT,
938	pub lParam: isize,
939}
940
941/// [`NMLVCACHEHINT`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-nmlvcachehint)
942/// struct.
943#[repr(C)]
944pub struct NMLVCACHEHINT {
945	pub hdr: NMHDR,
946	pub iFrom: i32,
947	pub iTo: i32,
948}
949
950/// [`NMLVCUSTOMDRAW`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-nmlvcustomdraw)
951/// struct.
952#[repr(C)]
953pub struct NMLVCUSTOMDRAW {
954	pub mcd: NMCUSTOMDRAW,
955	pub clrText: COLORREF,
956	pub clrTextBk: COLORREF,
957	pub iSubItem: i32,
958	pub dwItemType: co::LVCDI,
959	pub clrFace: COLORREF,
960	pub iIconEffect: i32,
961	pub iIconPhase: i32,
962	pub iPartId: i32,
963	pub iStateId: i32,
964	pub rcText: RECT,
965	pub uAlign: co::LVGA_HEADER,
966}
967
968/// [`NMLVDISPINFO`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-nmlvdispinfow)
969/// struct.
970#[repr(C)]
971pub struct NMLVDISPINFO<'a> {
972	pub hdr: NMHDR,
973	pub item: LVITEM<'a>,
974}
975
976/// [`NMLVEMPTYMARKUP`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-nmlvemptymarkup)
977/// struct.
978#[repr(C)]
979pub struct NMLVEMPTYMARKUP {
980	pub hdr: NMHDR,
981	pub dwFlags: co::EMF,
982	szMarkup: [u16; L_MAX_URL_LENGTH],
983}
984
985impl_default!(NMLVEMPTYMARKUP);
986
987impl NMLVEMPTYMARKUP {
988	pub_fn_string_arr_get_set!(szMarkup, set_szMarkup);
989}
990
991/// [`NMLVFINDITEM`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-nmlvfinditemw)
992/// struct.
993#[repr(C)]
994pub struct NMLVFINDITEM<'a> {
995	pub hdr: NMHDR,
996	pub iStart: i32,
997	pub lvfi: LVFINDINFO<'a>,
998}
999
1000/// [`NMLVGETINFOTIP`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-nmlvgetinfotipw)
1001/// struct.
1002#[repr(C)]
1003pub struct NMLVGETINFOTIP<'a> {
1004	pub hdr: NMHDR,
1005	pub dwFlags: co::LVGIT,
1006	pszText: *mut u16,
1007	cchTextMax: i32,
1008	pub iItem: i32,
1009	pub iSubItem: i32,
1010	pub lParam: isize,
1011
1012	_pszText: PhantomData<&'a mut u16>,
1013}
1014
1015impl_default!(NMLVGETINFOTIP, 'a);
1016
1017impl<'a> NMLVGETINFOTIP<'a> {
1018	pub_fn_string_buf_get_set!('a, pszText, set_pszText, raw_pszText, cchTextMax);
1019}
1020
1021/// [`NMLVKEYDOWN`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-nmlvkeydown)
1022/// struct.
1023#[repr(C)]
1024pub struct NMLVKEYDOWN {
1025	pub hdr: NMHDR,
1026	pub wVKey: co::VK,
1027	flags: u32,
1028}
1029
1030impl_default!(NMLVKEYDOWN);
1031
1032/// [`NMLVLINK`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-nmlvlink)
1033/// struct.
1034#[repr(C)]
1035pub struct NMLVLINK {
1036	pub hdr: NMHDR,
1037	pub link: LITEM,
1038	pub iItem: i32,
1039	pub iSubItem: i32,
1040}
1041
1042/// [`NMLVODSTATECHANGE`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-nmlvodstatechange)
1043/// struct.
1044#[repr(C)]
1045pub struct NMLVODSTATECHANGE {
1046	pub hdr: NMHDR,
1047	pub iFrom: i32,
1048	pub iTo: i32,
1049	pub uNewState: co::LVIS,
1050	pub uOldState: co::LVIS,
1051}
1052
1053/// [`NMLVSCROLL`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-nmlvscroll)
1054/// struct.
1055#[repr(C)]
1056pub struct NMLVSCROLL {
1057	pub hdr: NMHDR,
1058	pub dx: i32,
1059	pub dy: i32,
1060}
1061
1062/// [`NMMOUSE`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-nmmouse)
1063/// struct.
1064#[repr(C)]
1065pub struct NMMOUSE {
1066	pub hdr: NMHDR,
1067	pub dwItemSpec: usize,
1068	pub dwItemData: usize,
1069	pub pt: POINT,
1070	pub dwHitInfo: isize,
1071}
1072
1073/// [`NMTRBTHUMBPOSCHANGING`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-nmtrbthumbposchanging)
1074/// struct.
1075#[repr(C)]
1076pub struct NMTRBTHUMBPOSCHANGING {
1077	pub hdr: NMHDR,
1078	pub dwPos: u32,
1079	pub nReason: co::TB,
1080}
1081
1082/// [`NMSELCHANGE`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-nmselchange)
1083/// struct.
1084#[repr(C)]
1085pub struct NMSELCHANGE {
1086	pub nmhdr: NMHDR,
1087	pub stSelStart: SYSTEMTIME,
1088	pub stSelEnd: SYSTEMTIME,
1089}
1090
1091/// [`NMTCKEYDOWN`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-nmtckeydown)
1092/// struct.
1093#[repr(C)]
1094pub struct NMTCKEYDOWN {
1095	pub hdr: NMHDR,
1096	pub wVKey: co::VK,
1097	pub flags: u32,
1098}
1099
1100impl_default!(NMTCKEYDOWN);
1101
1102/// [`NMTREEVIEW`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-nmtreevieww)
1103/// struct.
1104#[repr(C)]
1105pub struct NMTREEVIEW<'a, 'b> {
1106	pub hdr: NMHDR,
1107	pub action: u32, // actual type varies
1108	pub itemOld: TVITEM<'a>,
1109	pub itemNew: TVITEM<'b>,
1110	pub ptDrag: POINT,
1111}
1112
1113/// [`NMTVCUSTOMDRAW`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-nmtvcustomdraw)
1114/// stuct.
1115#[repr(C)]
1116pub struct NMTVCUSTOMDRAW {
1117	pub nmcd: NMCUSTOMDRAW,
1118	pub clrText: COLORREF,
1119	pub clrTextBk: COLORREF,
1120	pub iLevel: i32,
1121}
1122
1123/// [`NMTVITEMCHANGE`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-nmtvitemchange)
1124/// struct.
1125#[repr(C)]
1126pub struct NMTVITEMCHANGE {
1127	pub hdr: NMHDR,
1128	pub uChanged: co::TVIF,
1129	pub hItem: HTREEITEM,
1130	pub uStateNew: co::TVIS,
1131	pub uStateOld: co::TVIS,
1132	pub lParam: isize,
1133}
1134
1135/// [`NMUPDOWN`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-nmupdown)
1136/// struct.
1137#[repr(C)]
1138pub struct NMUPDOWN {
1139	pub hdr: NMHDR,
1140	pub iPos: i32,
1141	pub iDelta: i32,
1142}
1143
1144/// [`NMVIEWCHANGE`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-nmviewchange)
1145/// struct.
1146#[repr(C)]
1147pub struct NMVIEWCHANGE {
1148	pub nmhdr: NMHDR,
1149	pub dwOldView: co::MCMV,
1150	pub dwNewView: co::MCMV,
1151}
1152
1153/// [`PBRANGE`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-pbrange)
1154/// struct.
1155#[repr(C)]
1156#[derive(Default, Clone, Copy, PartialEq, Eq)]
1157pub struct PBRANGE {
1158	pub iLow: i32,
1159	pub iHigh: i32,
1160}
1161
1162/// [`PROPSHEETHEADER`](https://learn.microsoft.com/en-us/windows/win32/controls/pss-propsheetheader)
1163/// struct.
1164///
1165/// This struct is passed to [`PropertySheet`](crate::PropertySheet), which is
1166/// very unsafe. Prefer using the [`gui::PropSheet`](crate::gui::PropSheet) high
1167/// level abstraction.
1168#[repr(C)]
1169pub struct PROPSHEETHEADER<'a, 'b, 'c, 'd, 'e, 'f> {
1170	dwSize: u32,
1171	pub dwFlags: co::PSH,
1172	pub hwndParent: HWND,
1173	pub hInstance: HINSTANCE,
1174	hIcon_pszIcon: *mut std::ffi::c_void, // union
1175	pszCaption: *mut u16,
1176	pub nPages: u32,
1177	union0: PROPSHEETHEADER_union0,
1178	ppsp_phpage: *mut std::ffi::c_void, // union,
1179	pub pfnCallback: Option<PFNPROPSHEETCALLBACK>,
1180	hbmWatermark_pszbmWatermark: *mut std::ffi::c_void, // union
1181	pub hplWatermark: HPALETTE,
1182	hbmHeader_pszbmHeader: *mut std::ffi::c_void, // union
1183
1184	_pszIcon: PhantomData<&'a u16>,
1185	_pszTitle: PhantomData<&'b mut u16>,
1186	_pStartPage: PhantomData<&'c mut u16>,
1187	_ppsp_phpage: PhantomData<&'d [PROPSHEETPAGE]>,
1188	_pszbmWatermark: PhantomData<&'e mut u16>,
1189	_pszbmHeader: PhantomData<&'f mut u16>,
1190}
1191
1192#[repr(C)]
1193union PROPSHEETHEADER_union0 {
1194	nStartPage: u32,
1195	pStartPage: *const u16,
1196}
1197
1198impl_default!(PROPSHEETHEADER, dwSize, 'a, 'b, 'c, 'd, 'e, 'f);
1199
1200impl<'a, 'b, 'c, 'd, 'e, 'f> PROPSHEETHEADER<'a, 'b, 'c, 'd, 'e, 'f> {
1201	/// Sets the `hIcon` field, which is part of an union.
1202	pub const fn set_hIcon(&mut self, hicon: HICON) {
1203		self.hIcon_pszIcon = hicon.ptr();
1204	}
1205
1206	/// Sets the `pszIcon` field, which is part of an union.
1207	pub fn set_pszIcon(&mut self, buf: &'a mut IdStr) {
1208		self.hIcon_pszIcon = match buf {
1209			IdStr::Id(id) => *id as _,
1210			IdStr::Str(wstr) => unsafe { wstr.as_mut_ptr() as _ },
1211		};
1212	}
1213
1214	pub_fn_string_ptr_get_set!('b, pszCaption, set_pszCaption);
1215
1216	/// Sets the `nStartPage` field, which is part of an union.
1217	pub const fn set_nStartPage(&mut self, n: u32) {
1218		self.union0.nStartPage = n;
1219	}
1220
1221	/// Sets the `pStartPage` field, which is part of an union.
1222	pub fn set_pStartPage(&mut self, buf: &'c mut WString) {
1223		self.union0.pStartPage = unsafe { buf.as_mut_ptr() } as _;
1224	}
1225
1226	/// Sets the `ppsp` field, which is part of an union.
1227	pub const fn set_ppsp(&mut self, pages: &'d [PROPSHEETPAGE]) {
1228		self.ppsp_phpage = pages as *const _ as _;
1229	}
1230
1231	/// Sets the `phpage` field, which is part of an union.
1232	pub const fn set_phpage(&mut self, pages: &'d [HPROPSHEETPAGE]) {
1233		self.ppsp_phpage = pages as *const _ as _;
1234	}
1235
1236	/// Sets the `hbmWatermark` field, which is part of an union.
1237	pub const fn set_hbmWatermark(&mut self, hbm: HBITMAP) {
1238		self.hbmWatermark_pszbmWatermark = hbm.ptr();
1239	}
1240
1241	/// Sets the `pszbmWatermark` field, which is part of an union.
1242	pub fn set_pszbmWatermark(&mut self, buf: &'e mut IdStr) {
1243		self.hbmWatermark_pszbmWatermark = match buf {
1244			IdStr::Id(id) => *id as _,
1245			IdStr::Str(wstr) => unsafe { wstr.as_mut_ptr() as _ },
1246		};
1247	}
1248
1249	/// Sets the `hbmHeader` field, which is part of an union.
1250	pub const fn set_hbmHeader(&mut self, hbm: HBITMAP) {
1251		self.hbmHeader_pszbmHeader = hbm.ptr();
1252	}
1253
1254	/// Sets the `pszbmHeader` field, which is part of an union.
1255	pub fn set_pszbmHeader(&mut self, buf: &'f mut IdStr) {
1256		self.hbmHeader_pszbmHeader = match buf {
1257			IdStr::Id(id) => *id as _,
1258			IdStr::Str(wstr) => unsafe { wstr.as_mut_ptr() as _ },
1259		};
1260	}
1261}
1262
1263/// [`PROPSHEETPAGE`](https://learn.microsoft.com/en-us/windows/win32/controls/pss-propsheetpage)
1264/// struct.
1265///
1266/// This struct is passed to [`PropertySheet`](crate::PropertySheet), which is
1267/// very unsafe. Prefer using the [`gui::PropSheet`](crate::gui::PropSheet) high
1268/// level abstraction.
1269#[repr(C)]
1270pub struct PROPSHEETPAGE {
1271	dwSize: u32,
1272	pub dwFlags: co::PSP,
1273	pub hInstance: HINSTANCE,
1274	pub pszTemplate_pResource: *mut std::ffi::c_void, // union
1275	pub hIcon_pszIcon: *mut std::ffi::c_void,         // union
1276	pub pszTitle: *const u16,
1277	pub pfnDlgProc: Option<DLGPROC>,
1278	pub lParam: isize,
1279	pub pfnCallback: Option<LPFNPSPCALLBACK>,
1280	pub pcRefParent: *mut u32,
1281	pub pszHeaderTitle: *const u16,
1282	pub pszHeaderSubTitle: *const u16,
1283	pub hActCtx: HACTCTX,
1284	pub hbmHeader_pszbmHeader: *mut std::ffi::c_void, // union
1285}
1286
1287impl_default!(PROPSHEETPAGE, dwSize);
1288
1289/// [`PSHNOTIFY`](https://learn.microsoft.com/en-us/windows/win32/api/prsht/ns-prsht-pshnotify)
1290/// struct.
1291#[repr(C)]
1292pub struct PSHNOTIFY {
1293	pub hdr: NMHDR,
1294	pub lParam: isize,
1295}
1296
1297/// [`TASKDIALOGCONFIG`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-taskdialog_button)
1298/// struct.
1299///
1300/// Used with [`TaskDialogIndirect`](crate::TaskDialogIndirect) function.
1301///
1302/// Not all `flags` constants are available, some of them are automatically set
1303/// as you fill other parameters.
1304#[derive(Default)]
1305pub struct TASKDIALOGCONFIG<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, 'k, 'l, 'm, 'n, 'o, 'p> {
1306	pub hwnd_parent: Option<&'a HWND>,
1307	pub hinstance: Option<&'b HINSTANCE>,
1308	pub flags: co::TDF,
1309	/// Predefined buttons. Will be placed after the custom `buttons`.
1310	pub common_buttons: co::TDCBF,
1311	/// Window caption. If not specified, the .exe name is used.
1312	pub window_title: Option<&'c str>,
1313	pub main_icon: IconIdTd<'d>,
1314	/// Text shown before the main content, in a larger font.
1315	pub main_instruction: Option<&'e str>,
1316	/// The main text of the dialog.
1317	pub content: Option<&'f str>,
1318	/// Command ID and button text. Will be placed before the predefined
1319	/// `common_buttons`.
1320	pub buttons: &'g [(u16, &'h str)],
1321	/// Any ID from `common_buttons` or `buttons`.
1322	pub default_button_id: u16,
1323	/// Command ID and radio button text.
1324	pub radio_buttons: &'i [(u16, &'j str)],
1325	/// Any ID from `radio_buttons`.
1326	pub default_radio_button_id: u16,
1327	/// Text of the label of the verification check box.
1328	pub verification_text: Option<&'k str>,
1329	/// Text of the collapsible section.
1330	pub more_info: Option<&'l str>,
1331	/// Text of the button that expands/collapses `more_info`, when the section
1332	/// is expanded.
1333	pub more_info_btn_expanded: Option<&'m str>,
1334	/// Text of the button that expands/collapses `more_info`, when the section
1335	/// is collapsed.
1336	pub more_info_btn_collapsed: Option<&'n str>,
1337	pub footer_icon: IconId<'o>,
1338	pub footer_text: Option<&'p str>,
1339	pub callback: Option<Box<dyn Fn(&HWND, Tdn) -> co::HRESULT>>,
1340	pub width: u32,
1341}
1342
1343impl<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, 'k, 'l, 'm, 'n, 'o, 'p>
1344	TASKDIALOGCONFIG<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, 'k, 'l, 'm, 'n, 'o, 'p>
1345{
1346	pub(in crate::comctl) fn to_raw(&self) -> TASKDIALOGCONFIG_buf {
1347		let mut raw = TASKDIALOGCONFIG_raw::default();
1348		raw.hwndParent = unsafe { self.hwnd_parent.unwrap_or(&HWND::NULL).raw_copy() };
1349		raw.hInstance = unsafe { self.hinstance.unwrap_or(&HINSTANCE::NULL).raw_copy() };
1350		raw.dwFlags = self.flags;
1351		raw.dwCommonButtons = self.common_buttons;
1352
1353		let w_title = self
1354			.window_title // must force heap because variable will be moved
1355			.map_or(WString::new(), |s| WString::from_str_force_heap(s));
1356		raw.pszWindowTitle = w_title.as_ptr();
1357
1358		match &self.main_icon {
1359			IconIdTd::None => {
1360				let new_flags = raw.dwFlags | TDF_USE_HICON_MAIN;
1361				raw.dwFlags = new_flags;
1362			},
1363			IconIdTd::Icon(h) => {
1364				raw.hMainIcon = h.ptr();
1365				let new_flags = raw.dwFlags | TDF_USE_HICON_MAIN;
1366				raw.dwFlags = new_flags;
1367			},
1368			IconIdTd::Id(id) => {
1369				raw.hMainIcon = MAKEINTRESOURCE(*id as _) as _;
1370			},
1371			IconIdTd::Td(td) => {
1372				raw.hMainIcon = td.raw() as _;
1373			},
1374		}
1375
1376		let w_instruc = self
1377			.main_instruction
1378			.map_or(WString::new(), |s| WString::from_str_force_heap(s));
1379		raw.pszMainInstruction = w_instruc.as_ptr();
1380
1381		let w_content = self
1382			.content
1383			.map_or(WString::new(), |s| WString::from_str_force_heap(s));
1384		raw.pszContent = w_content.as_ptr();
1385
1386		let btns_buf: (Vec<_>, Vec<_>) = self
1387			.buttons
1388			.iter()
1389			.map(|(id, txt)| {
1390				let txt_buf = WString::from_str_force_heap(*txt);
1391				let btn_buf = TASKDIALOG_BUTTON {
1392					nButtonID: *id as _,
1393					pszButtonText: txt_buf.as_ptr(),
1394				};
1395				(txt_buf, btn_buf)
1396			})
1397			.unzip();
1398		raw.cButtons = btns_buf.1.len() as _;
1399		raw.pButtons = btns_buf.1.as_ptr() as _;
1400		raw.nDefaultButton = self.default_button_id as _;
1401
1402		let radios_buf: (Vec<_>, Vec<_>) = self
1403			.radio_buttons
1404			.iter()
1405			.map(|(id, txt)| {
1406				let txt_buf = WString::from_str_force_heap(*txt);
1407				let btn_buf = TASKDIALOG_BUTTON {
1408					nButtonID: *id as _,
1409					pszButtonText: txt_buf.as_ptr(),
1410				};
1411				(txt_buf, btn_buf)
1412			})
1413			.unzip();
1414		raw.cRadioButtons = radios_buf.1.len() as _;
1415		raw.pRadioButtons = radios_buf.1.as_ptr() as _;
1416		raw.nDefaultRadioButton = self.default_radio_button_id as _;
1417
1418		let w_verif = self
1419			.verification_text
1420			.map_or(WString::new(), |s| WString::from_str_force_heap(s));
1421		raw.pszVerificationText = w_verif.as_ptr();
1422
1423		let w_more_info = self
1424			.more_info
1425			.map_or(WString::new(), |s| WString::from_str_force_heap(s));
1426		raw.pszExpandedInformation = w_more_info.as_ptr();
1427
1428		let w_expanded_info = self
1429			.more_info_btn_expanded
1430			.map_or(WString::new(), |s| WString::from_str_force_heap(s));
1431		raw.pszExpandedControlText = w_expanded_info.as_ptr();
1432
1433		let w_collapsed_info = self
1434			.more_info_btn_collapsed
1435			.map_or(WString::new(), |s| WString::from_str_force_heap(s));
1436		raw.pszCollapsedControlText = w_collapsed_info.as_ptr();
1437
1438		match &self.footer_icon {
1439			IconId::None => {
1440				let new_flags = raw.dwFlags | TDF_USE_HICON_FOOTER;
1441				raw.dwFlags = new_flags;
1442			},
1443			IconId::Icon(h) => {
1444				raw.hFooterIcon = h.ptr();
1445				let new_flags = raw.dwFlags | TDF_USE_HICON_FOOTER;
1446				raw.dwFlags = new_flags;
1447			},
1448			IconId::Id(id) => {
1449				raw.hFooterIcon = MAKEINTRESOURCE(*id as _) as _;
1450			},
1451		}
1452
1453		let w_footer = self
1454			.footer_text
1455			.map_or(WString::new(), |s| WString::from_str_force_heap(s));
1456		raw.pszFooter = w_footer.as_ptr();
1457
1458		raw.pfCallback = Some(callbacks::func_task_dialog_callback);
1459		raw.lpCallbackData = self as *const _ as _; // object will exist until TaskDialogIndirect() returns
1460		raw.cxWidth = self.width;
1461
1462		TASKDIALOGCONFIG_buf {
1463			raw,
1464			w_title,
1465			w_instruc,
1466			w_content,
1467			btns_buf,
1468			radios_buf,
1469			w_verif,
1470			w_more_info,
1471			w_expanded_info,
1472			w_collapsed_info,
1473			w_footer,
1474		}
1475	}
1476}
1477
1478#[allow(unused)]
1479pub(in crate::comctl) struct TASKDIALOGCONFIG_buf {
1480	pub(in crate::comctl) raw: TASKDIALOGCONFIG_raw,
1481	w_title: WString,
1482	w_instruc: WString,
1483	w_content: WString,
1484	btns_buf: (Vec<WString>, Vec<TASKDIALOG_BUTTON>),
1485	radios_buf: (Vec<WString>, Vec<TASKDIALOG_BUTTON>),
1486	w_verif: WString,
1487	w_more_info: WString,
1488	w_expanded_info: WString,
1489	w_collapsed_info: WString,
1490	w_footer: WString,
1491}
1492
1493#[repr(C, packed)]
1494pub(in crate::comctl) struct TASKDIALOGCONFIG_raw {
1495	cbSize: u32,
1496	pub(in crate::comctl) hwndParent: HWND,
1497	pub(in crate::comctl) hInstance: HINSTANCE,
1498	pub(in crate::comctl) dwFlags: co::TDF,
1499	pub(in crate::comctl) dwCommonButtons: co::TDCBF,
1500	pub(in crate::comctl) pszWindowTitle: *const u16,
1501	pub(in crate::comctl) hMainIcon: *const std::ffi::c_void, // union with pszMainIcon
1502	pub(in crate::comctl) pszMainInstruction: *const u16,
1503	pub(in crate::comctl) pszContent: *const u16,
1504	pub(in crate::comctl) cButtons: u32,
1505	pub(in crate::comctl) pButtons: *const TASKDIALOG_BUTTON,
1506	pub(in crate::comctl) nDefaultButton: i32, // actually co::DLGID, which is u16
1507	pub(in crate::comctl) cRadioButtons: u32,
1508	pub(in crate::comctl) pRadioButtons: *mut TASKDIALOG_BUTTON,
1509	pub(in crate::comctl) nDefaultRadioButton: i32,
1510	pub(in crate::comctl) pszVerificationText: *const u16,
1511	pub(in crate::comctl) pszExpandedInformation: *const u16,
1512	pub(in crate::comctl) pszExpandedControlText: *const u16,
1513	pub(in crate::comctl) pszCollapsedControlText: *const u16,
1514	pub(in crate::comctl) hFooterIcon: *const std::ffi::c_void, // union with pszFooterIcon
1515	pub(in crate::comctl) pszFooter: *const u16,
1516	pub(in crate::comctl) pfCallback: Option<PFTASKDIALOGCALLBACK>,
1517	pub(in crate::comctl) lpCallbackData: usize,
1518	pub(in crate::comctl) cxWidth: u32,
1519}
1520
1521impl_default!(TASKDIALOGCONFIG_raw, cbSize);
1522
1523#[repr(C, packed)]
1524pub(in crate::comctl) struct TASKDIALOG_BUTTON {
1525	pub(in crate::comctl) nButtonID: i32,
1526	pub(in crate::comctl) pszButtonText: *const u16,
1527}
1528
1529impl_default!(TASKDIALOG_BUTTON);
1530
1531/// [`TBADDBITMAP`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-tbaddbitmap)
1532/// struct.
1533#[repr(C)]
1534pub struct TBADDBITMAP {
1535	hInst: HINSTANCE,
1536	nID: usize,
1537}
1538
1539impl_default!(TBADDBITMAP);
1540
1541impl TBADDBITMAP {
1542	/// Returns the `hInst` and `nID` fields.
1543	#[must_use]
1544	pub fn nID(&self) -> BmpIdbRes {
1545		if self.hInst.ptr() as isize == HINST_COMMCTRL {
1546			BmpIdbRes::Idb(unsafe { co::IDB::from_raw(self.nID) })
1547		} else if self.hInst == HINSTANCE::NULL {
1548			BmpIdbRes::Bmp(unsafe { HBITMAP::from_ptr(self.nID as _) })
1549		} else {
1550			unsafe { BmpIdbRes::Res(IdStr::from_ptr(self.nID as _), self.hInst.raw_copy()) }
1551		}
1552	}
1553
1554	/// Sets the `hInst` and `nID` fields.
1555	pub fn set_nID(&mut self, val: &BmpIdbRes) {
1556		*self = match val {
1557			BmpIdbRes::Idb(idb) => Self {
1558				hInst: unsafe { HINSTANCE::from_ptr(HINST_COMMCTRL as _) },
1559				nID: idb.raw(),
1560			},
1561			BmpIdbRes::Bmp(bmp) => Self {
1562				hInst: HINSTANCE::NULL,
1563				nID: bmp.ptr() as _,
1564			},
1565			BmpIdbRes::Res(res, hInst) => Self {
1566				hInst: unsafe { hInst.raw_copy() },
1567				nID: res.as_ptr() as _,
1568			},
1569		}
1570	}
1571}
1572
1573/// [`TBBUTTON`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-tbbutton)
1574/// struct.
1575#[repr(C)]
1576pub struct TBBUTTON<'a> {
1577	pub iBitmap: i32,
1578	pub idCommand: i32,
1579	pub fsState: co::TBSTATE,
1580	fsStyle: u8,        // BTNS is actually u32 window style
1581	bReserved: [u8; 6], // assumes 64-bit architecture
1582	pub dwData: usize,
1583	iString: isize,
1584
1585	_iString: PhantomData<&'a mut u16>,
1586}
1587
1588impl_default!(TBBUTTON, 'a);
1589
1590impl<'a> TBBUTTON<'a> {
1591	/// Returns the `fsStyle` field.
1592	#[must_use]
1593	pub const fn fsStyle(&self) -> co::BTNS {
1594		unsafe { co::BTNS::from_raw(self.fsStyle as _) }
1595	}
1596
1597	/// Sets the `fsStyle` field.
1598	pub const fn set_fsStyle(&mut self, val: co::BTNS) {
1599		self.fsStyle = val.raw() as _;
1600	}
1601
1602	/// Returns the `iString` field.
1603	#[must_use]
1604	pub fn iString(&self) -> IdxStr {
1605		if IS_INTRESOURCE(self.iString as _) {
1606			IdxStr::Idx(self.iString as _)
1607		} else {
1608			IdxStr::Str(unsafe { WString::from_wchars_nullt(self.iString as _) })
1609		}
1610	}
1611
1612	/// Sets the `iString` field.
1613	pub fn set_iString(&mut self, val: &'a mut IdxStr) {
1614		self.iString = match val {
1615			IdxStr::Idx(i) => *i as _,
1616			IdxStr::Str(s) => unsafe { s.as_mut_ptr() as _ },
1617		};
1618	}
1619}
1620
1621/// [`TBBUTTONINFO`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-tbbuttoninfow)
1622/// struct.
1623#[repr(C)]
1624pub struct TBBUTTONINFO<'a> {
1625	cbSize: u32,
1626	pub dwMask: co::TBIF,
1627	pub idCommand: i32,
1628	pub iImage: i32,
1629	pub fsState: co::TBSTATE,
1630	fsStyle: u8, // BTNS is actually u32 window style
1631	pub cx: u16,
1632	pub lParam: usize,
1633	pszText: *mut u16,
1634	cchText: i32,
1635
1636	_pszText: PhantomData<&'a mut u16>,
1637}
1638
1639impl_default!(TBBUTTONINFO, cbSize, 'a);
1640
1641impl<'a> TBBUTTONINFO<'a> {
1642	/// Returns the `fsStyle` field.
1643	#[must_use]
1644	pub const fn fsStyle(&self) -> co::BTNS {
1645		unsafe { co::BTNS::from_raw(self.fsStyle as _) }
1646	}
1647
1648	/// Sets the `fsStyle` field.
1649	pub const fn set_fsStyle(&mut self, val: co::BTNS) {
1650		self.fsStyle = val.raw() as _;
1651	}
1652
1653	pub_fn_string_buf_get_set!('a, pszText, set_pszText, raw_pszText, cchText);
1654}
1655
1656/// [`TBINSERTMARK`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-tbinsertmark)
1657/// struct.
1658#[repr(C)]
1659#[derive(Default)]
1660pub struct TBINSERTMARK {
1661	pub iButton: i32,
1662	pub dwFlags: co::TBIMHT,
1663}
1664
1665/// [`TBMETRICS`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-tbmetrics)
1666/// struct.
1667#[repr(C)]
1668pub struct TBMETRICS {
1669	cbSize: u32,
1670	pub dwMask: co::TBMF,
1671	pub cxPad: i32,
1672	pub cyPad: i32,
1673	pub cxBarPad: i32,
1674	pub cyBarPad: i32,
1675	pub cxButtonSpacing: i32,
1676	pub cyButtonSpacing: i32,
1677}
1678
1679impl_default!(TBMETRICS, cbSize);
1680
1681/// [`TBREPLACEBITMAP`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-tbreplacebitmap)
1682/// struct.
1683#[repr(C)]
1684pub struct TBREPLACEBITMAP {
1685	hInstOld: HINSTANCE,
1686	nIDOld: usize,
1687	hInstNew: HINSTANCE,
1688	nIDNew: usize,
1689	pub nButtons: i32,
1690}
1691
1692impl_default!(TBREPLACEBITMAP);
1693
1694impl TBREPLACEBITMAP {
1695	/// Returns the `hInstOld` and `nIDOld` fields.
1696	#[must_use]
1697	pub fn olds(&self) -> BmpInstId {
1698		if self.hInstOld == HINSTANCE::NULL {
1699			BmpInstId::Bmp(unsafe { HBITMAP::from_ptr(self.nIDOld as _) })
1700		} else {
1701			BmpInstId::InstId(unsafe { self.hInstOld.raw_copy() }, self.nIDOld as _)
1702		}
1703	}
1704
1705	/// Sets the `hInstOld` and `nIDOld` fields.
1706	pub fn set_olds(&mut self, val: BmpInstId) {
1707		match val {
1708			BmpInstId::Bmp(hbmp) => {
1709				self.hInstOld = HINSTANCE::NULL;
1710				self.nIDOld = hbmp.ptr() as _;
1711			},
1712			BmpInstId::InstId(hinst, id) => {
1713				self.hInstOld = hinst;
1714				self.nIDOld = id as _;
1715			},
1716		}
1717	}
1718
1719	/// Returns the `hInstNew` and `nIDNew` fields.
1720	#[must_use]
1721	pub fn news(&self) -> BmpInstId {
1722		if self.hInstNew == HINSTANCE::NULL {
1723			BmpInstId::Bmp(unsafe { HBITMAP::from_ptr(self.nIDNew as _) })
1724		} else {
1725			BmpInstId::InstId(unsafe { self.hInstNew.raw_copy() }, self.nIDNew as _)
1726		}
1727	}
1728
1729	/// Sets the `hInstNew` and `nIDNew` fields.
1730	pub fn set_news(&mut self, val: BmpInstId) {
1731		match val {
1732			BmpInstId::Bmp(hbmp) => {
1733				self.hInstNew = HINSTANCE::NULL;
1734				self.nIDNew = hbmp.ptr() as _;
1735			},
1736			BmpInstId::InstId(hinst, id) => {
1737				self.hInstNew = hinst;
1738				self.nIDNew = id as _;
1739			},
1740		}
1741	}
1742}
1743
1744/// [`TCHITTESTINFO`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-tchittestinfo)
1745/// struct.
1746#[repr(C)]
1747pub struct TCHITTESTINFO {
1748	pub pt: POINT,
1749	pub flags: co::TCHT,
1750}
1751
1752impl_default!(TCHITTESTINFO);
1753
1754/// [`TCITEM`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-tcitemw)
1755/// struct.
1756#[repr(C)]
1757pub struct TCITEM<'a> {
1758	pub mask: co::TCIF,
1759	pub dwState: co::TCIS,
1760	pub dwStateMask: co::TCIS,
1761	pszText: *mut u16,
1762	cchTextMax: i32,
1763	pub iImage: i32,
1764	pub lParam: isize,
1765
1766	_pszText: PhantomData<&'a mut u16>,
1767}
1768
1769impl_default!(TCITEM, 'a);
1770
1771impl<'a> TCITEM<'a> {
1772	pub_fn_string_buf_get_set!('a, pszText, set_pszText, raw_pszText, cchTextMax);
1773}
1774
1775/// [`TVHITTESTINFO`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-tvhittestinfo)
1776/// struct.
1777#[repr(C)]
1778pub struct TVHITTESTINFO {
1779	pub pt: POINT,
1780	pub flags: co::TVHT,
1781	pub hitem: HTREEITEM,
1782}
1783
1784/// [`TVINSERTSTRUCT`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-tvinsertstructw)
1785/// struct.
1786#[repr(C)]
1787pub struct TVINSERTSTRUCT<'a> {
1788	pub hParent: HTREEITEM,
1789	hInsertAfter: isize,
1790	pub itemex: TVITEMEX<'a>,
1791}
1792
1793impl_default!(TVINSERTSTRUCT, 'a);
1794
1795impl<'a> TVINSERTSTRUCT<'a> {
1796	/// Returns the `hInsertAfter` field.
1797	#[must_use]
1798	pub fn hInsertAfter(&self) -> TreeitemTvi {
1799		TreeitemTvi::from_isize(self.hInsertAfter)
1800	}
1801
1802	/// Sets the `hInsertAfter` field.
1803	pub fn set_hInsertAfter(&mut self, val: TreeitemTvi) {
1804		self.hInsertAfter = val.into();
1805	}
1806}
1807
1808/// [`TVITEMEX`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-tvitemexw)
1809/// struct.
1810#[repr(C)]
1811pub struct TVITEMEX<'a> {
1812	pub mask: co::TVIF,
1813	pub hItem: HTREEITEM,
1814	pub state: co::TVIS,
1815	pub stateMask: co::TVIS,
1816	pszText: *mut u16,
1817	cchTextMax: i32,
1818	pub iImage: i32,
1819	pub iSelectedImage: i32,
1820	pub cChildren: i32,
1821	pub lParam: isize,
1822	pub iIntegral: i32,
1823	pub uStateEx: co::TVIS_EX,
1824	hwnd: HWND,
1825	pub iExpandedImage: i32,
1826	iReserved: i32,
1827
1828	_pszText: PhantomData<&'a mut u16>,
1829}
1830
1831impl_default!(TVITEMEX, 'a);
1832
1833impl<'a> TVITEMEX<'a> {
1834	pub_fn_string_buf_get_set!('a, pszText, set_pszText, raw_pszText, cchTextMax);
1835}
1836
1837/// [`TVITEM`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-tvitemw)
1838/// struct.
1839#[repr(C)]
1840pub struct TVITEM<'a> {
1841	pub mask: co::TVIF,
1842	pub hItem: HTREEITEM,
1843	pub state: co::TVIS,
1844	pub stateMask: co::TVIS,
1845	pszText: *mut u16,
1846	cchTextMax: i32,
1847	pub iImage: i32,
1848	pub iSelectedImage: i32,
1849	pub cChildren: i32,
1850	pub lParam: isize,
1851
1852	_pszText: PhantomData<&'a mut u16>,
1853}
1854
1855impl_default!(TVITEM, 'a);
1856
1857impl<'a> TVITEM<'a> {
1858	pub_fn_string_buf_get_set!('a, pszText, set_pszText, raw_pszText, cchTextMax);
1859}
1860
1861/// [`TVSORTCB`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-tvsortcb)
1862/// struct.
1863#[repr(C)]
1864pub struct TVSORTCB {
1865	pub hParent: HTREEITEM,
1866	pub lpfnCompare: Option<PFNTVCOMPARE>,
1867	pub lParam: isize,
1868}
1869
1870impl_default!(TVSORTCB);
1871
1872/// [`UDACCEL`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-udaccel)
1873/// struct.
1874#[repr(C)]
1875#[derive(Default)]
1876pub struct UDACCEL {
1877	pub nSec: u32,
1878	pub nInc: u32,
1879}