pacenotes_installer\ui/
folder_picker.rs1const BIF_RETURNONLYFSDIRS: u32 = 0x0000_0001;
2const BIF_NEWDIALOGSTYLE: u32 = 0x0000_0040;
3const MAX_PATH: usize = 260;
4
5pub unsafe fn browse_for_folder(
7 owner: windows_sys::Win32::Foundation::HWND,
8 prompt: &str,
9) -> Option<String> {
10 let title = crate::i18n::to_wide(prompt);
11 let mut browse_info: windows_sys::Win32::UI::Shell::BROWSEINFOW = core::mem::zeroed();
12 browse_info.hwndOwner = owner;
13 browse_info.lpszTitle = title.as_ptr();
14 browse_info.ulFlags = BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE;
15
16 let item_list = windows_sys::Win32::UI::Shell::SHBrowseForFolderW(&browse_info);
17 if item_list.is_null() {
18 return None;
19 }
20 let mut buffer = [0u16; MAX_PATH];
21 let found = windows_sys::Win32::UI::Shell::SHGetPathFromIDListW(item_list, buffer.as_mut_ptr());
22 windows_sys::Win32::System::Com::CoTaskMemFree(item_list as *const core::ffi::c_void);
23 if found == 0 {
24 return None;
25 }
26 let length = buffer
27 .iter()
28 .position(|&unit| unit == 0)
29 .unwrap_or(buffer.len());
30 Some(String::from_utf16_lossy(&buffer[..length]))
31}