use widestring::U16CString;
use windows::{
Win32::{
System::Com::CoTaskMemFree,
UI::Shell::{
Common::ITEMIDLIST, SHCreateItemFromIDList, SIGDN, SIGDN_DESKTOPABSOLUTEEDITING,
SIGDN_DESKTOPABSOLUTEPARSING, SIGDN_FILESYSPATH, SIGDN_NORMALDISPLAY,
SIGDN_PARENTRELATIVE, SIGDN_PARENTRELATIVEEDITING, SIGDN_PARENTRELATIVEFORADDRESSBAR,
SIGDN_PARENTRELATIVEFORUI, SIGDN_PARENTRELATIVEPARSING, SIGDN_URL,
},
},
core::Result,
};
pub use windows::Win32::UI::Shell::IShellItem;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[repr(i32)]
pub enum ShellItemDisplayName {
NormalDisplay = SIGDN_NORMALDISPLAY.0,
ParentRelativeParsing = SIGDN_PARENTRELATIVEPARSING.0,
DesktopAbsoluteParsing = SIGDN_DESKTOPABSOLUTEPARSING.0,
ParentRelativeEditing = SIGDN_PARENTRELATIVEEDITING.0,
DesktopAbsoluteEditing = SIGDN_DESKTOPABSOLUTEEDITING.0,
FileSystemPath = SIGDN_FILESYSPATH.0,
Url = SIGDN_URL.0,
ParentRelativeForAddressBar = SIGDN_PARENTRELATIVEFORADDRESSBAR.0,
ParentRelative = SIGDN_PARENTRELATIVE.0,
ParentRelativeForUI = SIGDN_PARENTRELATIVEFORUI.0,
}
pub trait ShellItem {
#[doc(alias = "from_pidl")]
fn from_id_list(id_list: *const ITEMIDLIST) -> Result<IShellItem>;
fn get_display_name(&self, name: ShellItemDisplayName) -> Result<U16CString>;
}
impl ShellItem for IShellItem {
fn from_id_list(id_list: *const ITEMIDLIST) -> Result<IShellItem> {
unsafe { SHCreateItemFromIDList::<IShellItem>(id_list) }
}
fn get_display_name(&self, name: ShellItemDisplayName) -> Result<U16CString> {
let name = unsafe { self.GetDisplayName(SIGDN(name as i32)) }?;
let name_u16 = unsafe { U16CString::from_ptr_str(name.0) };
unsafe { CoTaskMemFree(Some(name.0 as _)) };
Ok(name_u16)
}
}