#![allow(non_snake_case)]
#![allow(non_camel_case_types)]
use std::sync::Arc;
pub mod iter;
pub mod types;
use types::*;
use crate::sys::*;
use windows::core::BSTR;
use windows::core::HRESULT;
use windows::core::Interface;
use windows::Win32::Media::Multimedia::NS_E_PROPERTY_NOT_FOUND;
use windows::Win32::System::Com::{CoInitializeEx, CoCreateInstance, CLSCTX_ALL, COINIT_MULTITHREADED};
use windows::Win32::System::Com::{VARIANT_0, VARIANT_0_0, VARIANT_0_0_0};
type DATE = f64; type LONG = i32;
use widestring::ucstring::U16CString;
use num_traits::FromPrimitive;
mod private {
use super::*;
pub trait ComObjectWrapper {
type WrappedType: Interface;
fn from_com_object(com_object: Self::WrappedType, iTunes: Arc<iTunes>) -> Self;
fn com_object(&self) -> &Self::WrappedType;
fn iTunes(&self) -> Arc<iTunes>;
}
}
use private::ComObjectWrapper;
pub trait ITunesRelatedObject: private::ComObjectWrapper {
fn iTunes_instance(&self) -> Arc<iTunes> {
self.iTunes()
}
}
macro_rules! com_wrapper_struct {
($(#[$attr:meta])* $struct_name:ident) => {
::paste::paste! {
com_wrapper_struct!($(#[$attr])* $struct_name as [<IIT $struct_name>]);
}
};
($(#[$attr:meta])* $struct_name:ident as $com_type:ident) => {
$(#[$attr])*
pub struct $struct_name {
com_object: crate::sys::$com_type,
iTunes: Arc<iTunes>,
}
impl private::ComObjectWrapper for $struct_name {
type WrappedType = $com_type;
fn from_com_object(com_object: crate::sys::$com_type, iTunes: Arc<iTunes>) -> Self {
Self {
com_object, iTunes
}
}
fn com_object(&self) -> &crate::sys::$com_type {
&self.com_object
}
fn iTunes(&self) -> Arc<iTunes> {
Arc::clone(&self.iTunes)
}
}
impl ITunesRelatedObject for $struct_name {}
}
}
macro_rules! str_to_bstr {
($string_name:ident, $bstr_name:ident) => {
let wide = U16CString::from_str_truncate($string_name);
let $bstr_name = BSTR::from_wide(wide.as_slice())?;
}
}
macro_rules! no_args {
($(#[$attr:meta])* $vis:vis $func_name:ident) => {
no_args!($(#[$attr])* $vis $func_name as <Self as ComObjectWrapper>::WrappedType);
};
($(#[$attr:meta])* $vis:vis $func_name:ident as $inherited_type:ty) => {
$(#[$attr])*
$vis fn $func_name(&self) -> windows::core::Result<()> {
let inherited_obj = self.com_object().cast::<$inherited_type>()?;
let result: HRESULT = unsafe{ inherited_obj.$func_name() };
result.ok()
}
};
}
macro_rules! get_bstr {
($(#[$attr:meta])* $vis:vis $func_name:ident) => {
get_bstr!($(#[$attr])* $vis $func_name as <Self as ComObjectWrapper>::WrappedType);
};
($(#[$attr:meta])* $vis:vis $func_name:ident as $inherited_type:ty) => {
$(#[$attr])*
$vis fn $func_name(&self) -> windows::core::Result<String> {
let mut bstr = BSTR::default();
let inherited_obj = self.com_object().cast::<$inherited_type>()?;
let result = unsafe{ inherited_obj.$func_name(&mut bstr) };
result.ok()?;
let v: Vec<u16> = bstr.as_wide().to_vec();
Ok(U16CString::from_vec_truncate(v).to_string_lossy())
}
}
}
macro_rules! internal_set_bstr {
($(#[$attr:meta])* $vis:vis $func_name:ident ( $key:ident ) as $inherited_type:ty) => {
$(#[$attr])*
$vis fn $func_name(&self, $key: &str) -> windows::core::Result<()> {
str_to_bstr!($key, bstr);
let inherited_obj = self.com_object().cast::<$inherited_type>()?;
let result = unsafe{ inherited_obj.$func_name(bstr) };
result.ok()
}
};
}
macro_rules! set_bstr {
($(#[$attr:meta])* $vis:vis $key:ident) => {
set_bstr!($(#[$attr])* $vis $key as <Self as ComObjectWrapper>::WrappedType);
};
($(#[$attr:meta])* $vis:vis $key:ident as $inherited_type:ty) => {
::paste::paste! {
internal_set_bstr!($(#[$attr])* $vis [<set_ $key>] ( $key ) as $inherited_type);
}
};
($(#[$attr:meta])* $vis:vis $key:ident, no_set_prefix) => {
internal_set_bstr!($(#[$attr])* $vis $key ($key) as <Self as ComObjectWrapper>::WrappedType);
};
}
macro_rules! get_long {
($(#[$attr:meta])* $vis:vis $func_name:ident) => {
get_long!($(#[$attr])* $vis $func_name as <Self as ComObjectWrapper>::WrappedType);
};
($(#[$attr:meta])* $vis:vis $func_name:ident as $inherited_type:ty) => {
$(#[$attr])*
$vis fn $func_name(&self) -> windows::core::Result<LONG> {
let mut value: LONG = 0;
let inherited_obj = self.com_object().cast::<$inherited_type>()?;
let result = unsafe{ inherited_obj.$func_name(&mut value as *mut LONG) };
result.ok()?;
Ok(value)
}
};
}
macro_rules! get_rating {
($(#[$attr:meta])* $vis:vis $func_name:ident) => {
get_rating!($(#[$attr])* $vis $func_name as <Self as ComObjectWrapper>::WrappedType);
};
($(#[$attr:meta])* $vis:vis $func_name:ident as $inherited_type:ty) => {
$(#[$attr])*
$vis fn $func_name(&self) -> windows::core::Result<Rating> {
let mut value: LONG = 0;
let inherited_obj = self.com_object().cast::<$inherited_type>()?;
let result = unsafe{ inherited_obj.$func_name(&mut value as *mut LONG) };
result.ok()?;
Ok(value.into())
}
};
}
macro_rules! internal_set_long {
($(#[$attr:meta])* $vis:vis $func_name:ident ( $key:ident ) as $inherited_type:ty) => {
$(#[$attr])*
$vis fn $func_name(&self, $key: LONG) -> windows::core::Result<()> {
let inherited_obj = self.com_object().cast::<$inherited_type>()?;
let result = unsafe{ inherited_obj.$func_name($key) };
result.ok()
}
};
}
macro_rules! set_long {
($(#[$attr:meta])* $vis:vis $key:ident) => {
::paste::paste! {
set_long!($(#[$attr])* $vis $key as <Self as ComObjectWrapper>::WrappedType);
}
};
($(#[$attr:meta])* $vis:vis $key:ident as $inherited_type:ty) => {
::paste::paste! {
internal_set_long!($(#[$attr])* $vis [<set_ $key>] ($key) as $inherited_type);
}
};
($(#[$attr:meta])* $vis:vis $key:ident, no_set_prefix) => {
::paste::paste! {
internal_set_long!($(#[$attr])* $vis $key ($key) as <Self as ComObjectWrapper>::WrappedType);
}
};
}
macro_rules! set_rating {
($(#[$attr:meta])* $vis:vis $key:ident) => {
::paste::paste! {
set_rating!($(#[$attr])* $vis $key as <Self as ComObjectWrapper>::WrappedType);
}
};
($(#[$attr:meta])* $vis:vis $key:ident as $inherited_type:ty) => {
::paste::paste! {
$(#[$attr])*
$vis fn [<set_ $key>](&self, $key: Rating) -> windows::core::Result<()> {
let long_rating = $key.into();
let inherited_obj = self.com_object().cast::<$inherited_type>()?;
let result = unsafe{ inherited_obj.[<set_ $key>](long_rating) };
result.ok()
}
}
};
}
macro_rules! set_playlist {
($(#[$attr:meta])* $vis:vis $func_name:ident ( $arg:ident )) => {
::paste::paste! {
$(#[$attr])*
$vis fn [<set_ $func_name>](&self, $arg: &Playlist) -> windows::core::Result<()> {
let vplaylist = $arg.as_variant();
let result = unsafe{ self.com_object.[<set_ $func_name>](vplaylist.as_raw() as *const VARIANT) };
result.ok()
}
}
};
}
macro_rules! get_f64 {
($(#[$attr:meta])* $vis:vis $func_name:ident, $float_name:ty) => {
get_f64!($(#[$attr])* $vis $func_name, $float_name as <Self as ComObjectWrapper>::WrappedType);
};
($(#[$attr:meta])* $vis:vis $func_name:ident, $float_name:ty as $inherited_type:ty) => {
$(#[$attr])*
$vis fn $func_name(&self) -> windows::core::Result<$float_name> {
let mut value: f64 = 0.0;
let inherited_obj = self.com_object().cast::<$inherited_type>()?;
let result = unsafe{ inherited_obj.$func_name(&mut value) };
result.ok()?;
Ok(value)
}
};
}
macro_rules! set_f64 {
($(#[$attr:meta])* $vis:vis $key:ident, $float_name:ty) => {
set_f64!($(#[$attr])* $vis $key, $float_name as <Self as ComObjectWrapper>::WrappedType);
};
($(#[$attr:meta])* $vis:vis $key:ident, $float_name:ty as $inherited_type:ty) => {
::paste::paste! {
$(#[$attr])*
$vis fn [<set _$key>](&self, $key: $float_name) -> windows::core::Result<()> {
let inherited_obj = self.com_object().cast::<$inherited_type>()?;
let result = unsafe{ inherited_obj.[<set _$key>]($key) };
result.ok()
}
}
}
}
macro_rules! get_double {
($(#[$attr:meta])* $vis:vis $key:ident) => {
get_f64!($(#[$attr])* $vis $key, f64);
};
($(#[$attr:meta])* $vis:vis $key:ident as $inherited_type:ty) => {
get_f64!($(#[$attr])* $vis $key, f64 as $inherited_type);
}
}
macro_rules! set_double {
($(#[$attr:meta])* $vis:vis $key:ident) => {
set_f64!($(#[$attr])* $vis $key, f64);
}
}
macro_rules! get_date {
($(#[$attr:meta])* $vis:vis $key:ident) => {
get_f64!($(#[$attr])* $vis $key, DATE);
};
($(#[$attr:meta])* $vis:vis $key:ident as $inherited_type:ty) => {
get_f64!($(#[$attr])* $vis $key, DATE as $inherited_type);
};
}
macro_rules! set_date {
($(#[$attr:meta])* $vis:vis $key:ident) => {
set_f64!($(#[$attr])* $vis $key, DATE);
};
($(#[$attr:meta])* $vis:vis $key:ident as $inherited_type:ty) => {
set_f64!($(#[$attr])* $vis $key, DATE as $inherited_type);
};
}
macro_rules! get_bool {
($(#[$attr:meta])* $vis:vis $func_name:ident) => {
get_bool!($(#[$attr])* $vis $func_name as <Self as ComObjectWrapper>::WrappedType);
};
($(#[$attr:meta])* $vis:vis $func_name:ident as $inherited_type:ty) => {
::paste::paste! {
$(#[$attr])*
$vis fn [<is _$func_name>](&self) -> windows::core::Result<bool> {
let mut value = crate::sys::FALSE;
let inherited_obj = self.com_object().cast::<$inherited_type>()?;
let result = unsafe{ inherited_obj.$func_name(&mut value) };
result.ok()?;
Ok(value.as_bool())
}
}
};
}
macro_rules! internal_set_bool {
($(#[$attr:meta])* $vis:vis $func_name:ident ( $key:ident ) as $inherited_type:ty) => {
$(#[$attr])*
$vis fn $func_name(&self, $key: bool) -> windows::core::Result<()> {
let variant_bool = match $key {
true => crate::sys::TRUE,
false => crate::sys::FALSE,
};
let inherited_obj = self.com_object().cast::<$inherited_type>()?;
let result = unsafe{ inherited_obj.$func_name(variant_bool) };
result.ok()
}
};
}
macro_rules! set_bool {
($(#[$attr:meta])* $vis:vis $key:ident) => {
set_bool!($(#[$attr])* $vis $key as <Self as ComObjectWrapper>::WrappedType);
};
($(#[$attr:meta])* $vis:vis $key:ident as $inherited_type:ty) => {
::paste::paste! {
internal_set_bool!($(#[$attr])* $vis [<set_ $key>] ( $key ) as $inherited_type);
}
};
($(#[$attr:meta])* $vis:vis $key:ident, no_set_prefix) => {
internal_set_bool!($(#[$attr])* $vis $key ($key) as <Self as ComObjectWrapper>::WrappedType);
}
}
macro_rules! get_enum {
($(#[$attr:meta])* $vis:vis $fn_name:ident -> $enum_type:ty) => {
get_enum!($(#[$attr])* $vis $fn_name -> $enum_type as <Self as ComObjectWrapper>::WrappedType);
};
($(#[$attr:meta])* $vis:vis $fn_name:ident -> $enum_type:ty as $inherited_type:ty) => {
$(#[$attr])*
$vis fn $fn_name(&self) -> windows::core::Result<$enum_type> {
let mut value: $enum_type = FromPrimitive::from_i32(0).unwrap();
let inherited_obj = self.com_object().cast::<$inherited_type>()?;
let result = unsafe{ inherited_obj.$fn_name(&mut value as *mut _) };
result.ok()?;
Ok(value)
}
};
}
macro_rules! set_enum {
($(#[$attr:meta])* $vis:vis $fn_name:ident, $enum_type:ty) => {
set_enum!($(#[$attr])* $vis $fn_name, $enum_type as <Self as ComObjectWrapper>::WrappedType);
};
($(#[$attr:meta])* $vis:vis $fn_name:ident, $enum_type:ty as $inherited_type:ty) => {
::paste::paste! {
$(#[$attr])*
$vis fn [<set _$fn_name>](&self, value: $enum_type) -> windows::core::Result<()> {
let inherited_obj = self.com_object().cast::<$inherited_type>()?;
let result = unsafe{ inherited_obj.[<set _$fn_name>](value) };
result.ok()
}
}
};
}
macro_rules! create_wrapped_object {
($obj_type:ty, $out_obj:ident, $iTunes:ident) => {
match $out_obj {
None => Err(windows::core::Error::new(
NS_E_PROPERTY_NOT_FOUND, windows::h!("Item not found").clone(),
)),
Some(com_object) => Ok(
<$obj_type>::from_com_object(com_object, $iTunes)
)
}
};
}
macro_rules! get_object {
($(#[$attr:meta])* $vis:vis $fn_name:ident -> $obj_type:ty) => {
get_object!($(#[$attr])* $vis $fn_name -> $obj_type as <Self as ComObjectWrapper>::WrappedType);
};
($(#[$attr:meta])* $vis:vis $fn_name:ident -> $obj_type:ty as $inherited_type:ty) => {
$(#[$attr])*
$vis fn $fn_name(&self) -> windows::core::Result<$obj_type> {
let mut out_obj = None;
let inherited_obj = self.com_object().cast::<$inherited_type>()?;
let result = unsafe{ inherited_obj.$fn_name(&mut out_obj as *mut _) };
result.ok()?;
let iTunes_arc = self.iTunes();
create_wrapped_object!($obj_type, out_obj, iTunes_arc)
}
};
}
macro_rules! get_object_from_str {
($(#[$attr:meta])* $vis:vis $fn_name:ident ( $arg_name:ident ) -> $obj_type:ty) => {
get_object_from_str!($(#[$attr])* $vis $fn_name($arg_name) -> $obj_type as <Self as ComObjectWrapper>::WrappedType);
};
($(#[$attr:meta])* $vis:vis $fn_name:ident ( $arg_name:ident ) -> $obj_type:ty as $inherited_type:ty) => {
$(#[$attr])*
$vis fn $fn_name(&self, $arg_name: &str) -> windows::core::Result<$obj_type> {
str_to_bstr!($arg_name, bstr);
let inherited_obj = self.com_object().cast::<$inherited_type>()?;
let mut out_obj = None;
let result = unsafe{ inherited_obj.$fn_name(bstr, &mut out_obj as *mut _) };
result.ok()?;
let iTunes_arc = self.iTunes();
create_wrapped_object!($obj_type, out_obj, iTunes_arc)
}
};
}
macro_rules! get_object_from_variant {
($(#[$attr:meta])* $vis:vis $fn_name:ident ( $arg_name:ident ) -> $obj_type:ty) => {
get_object_from_variant!($(#[$attr])* $vis $fn_name($arg_name) -> $obj_type as <Self as ComObjectWrapper>::WrappedType);
};
($(#[$attr:meta])* $vis:vis $fn_name:ident ( $arg_name:ident ) -> $obj_type:ty as $inherited_type:ty) => {
$(#[$attr])*
$vis fn $fn_name<T>(&self, $arg_name:&Variant<T>) -> windows::core::Result<$obj_type> {
let inherited_obj = self.com_object().cast::<$inherited_type>()?;
let mut out_obj = None;
let result = unsafe{ inherited_obj.$fn_name($arg_name.as_raw() as *const VARIANT, &mut out_obj as *mut _) };
result.ok()?;
let iTunes_arc = self.iTunes();
create_wrapped_object!($obj_type, out_obj, iTunes_arc)
}
};
}
macro_rules! get_object_from_long {
($(#[$attr:meta])* $vis:vis $fn_name:ident ( $arg_name:ident ) -> $obj_type:ty) => {
get_object_from_long!($(#[$attr])* $vis $fn_name($arg_name) -> $obj_type as <Self as ComObjectWrapper>::WrappedType);
};
($(#[$attr:meta])* $vis:vis $fn_name:ident ( $arg_name:ident ) -> $obj_type:ty as $inherited_type:ty) => {
$(#[$attr])*
$vis fn $fn_name(&self, $arg_name:LONG) -> windows::core::Result<$obj_type> {
let inherited_obj = self.com_object().cast::<$inherited_type>()?;
let mut out_obj = None;
let result = unsafe{ inherited_obj.$fn_name($arg_name, &mut out_obj as *mut _) };
result.ok()?;
let iTunes_arc = self.iTunes();
create_wrapped_object!($obj_type, out_obj, iTunes_arc)
}
};
}
macro_rules! set_object {
($(#[$attr:meta])* $vis:vis $fn_name:ident, $obj_type:ty) => {
::paste::paste! {
$(#[$attr])*
$vis fn [<set _$fn_name>](&self, data: $obj_type) -> windows::core::Result<()> {
let object_to_set = data.com_object();
let result = unsafe{ self.com_object.[<set _$fn_name>](object_to_set as *const _) };
result.ok()
}
}
}
}
macro_rules! item_by_name {
($(#[$attr:meta])* $vis:vis $obj_type:ty) => {
$(#[$attr])*
$vis fn ItemByName(&self, name: &str) -> windows::core::Result<$obj_type> {
str_to_bstr!(name, bstr);
let mut out_obj = None;
let result = unsafe{ self.com_object.ItemByName(bstr, &mut out_obj as *mut _) };
result.ok()?;
let iTunes_arc = self.iTunes();
create_wrapped_object!($obj_type, out_obj, iTunes_arc)
}
}
}
macro_rules! item_by_persistent_id {
($(#[$attr:meta])* $vis:vis $obj_type:ty) => {
$(#[$attr])*
$vis fn ItemByPersistentID(&self, id: PersistentId) -> windows::core::Result<$obj_type> {
let b = id.to_le_bytes();
let id_low = i32::from_le_bytes(b[..4].try_into().unwrap());
let id_high = i32::from_le_bytes(b[4..].try_into().unwrap());
let mut out_obj = None;
let result = unsafe{ self.com_object.ItemByPersistentID(id_high, id_low, &mut out_obj as *mut _) };
result.ok()?;
let iTunes_arc = self.iTunes();
create_wrapped_object!($obj_type, out_obj, iTunes_arc)
}
}
}
pub trait Iterable {
type Item;
fn Count(&self) -> windows::core::Result<LONG>;
fn item(&self, index: LONG) -> windows::core::Result<<Self as Iterable>::Item>;
}
macro_rules! iterator {
($obj_type:ty, $item_type:ident) => {
impl $obj_type {
pub fn iter(&self) -> windows::core::Result<iter::Iterator<$obj_type, $item_type>> {
iter::Iterator::new(&self)
}
}
impl Iterable for $obj_type {
type Item = $item_type;
get_long!(Count);
fn item(&self, index: LONG) -> windows::core::Result<<Self as Iterable>::Item> {
let mut out_obj = None;
let result = unsafe{ self.com_object.Item(index, &mut out_obj as *mut _) };
result.ok()?;
let iTunes_arc = self.iTunes();
create_wrapped_object!($item_type, out_obj, iTunes_arc)
}
}
}
}
#[derive(Debug, Eq, PartialEq)]
pub struct ObjectIDs {
pub sourceID: LONG,
pub playlistID: LONG,
pub trackID: LONG,
pub databaseID: LONG,
}
pub trait IITObjectWrapper: private::ComObjectWrapper {
fn GetITObjectIDs(&self) -> windows::core::Result<ObjectIDs> {
let mut sourceID: LONG = 0;
let mut playlistID: LONG = 0;
let mut trackID: LONG = 0;
let mut databaseID: LONG = 0;
let iitobject = self.com_object().cast::<IITObject>().unwrap();
let result = unsafe{ iitobject.GetITObjectIDs(
&mut sourceID as *mut LONG,
&mut playlistID as *mut LONG,
&mut trackID as *mut LONG,
&mut databaseID as *mut LONG,
) };
result.ok()?;
Ok(ObjectIDs{
sourceID,
playlistID,
trackID,
databaseID,
})
}
fn as_variant(&self) -> Variant<Self::WrappedType> {
let idispatch = self.com_object().cast::<windows::Win32::System::Com::IDispatch>().unwrap();
Variant::new(VARIANT{
Anonymous: VARIANT_0 {
Anonymous: std::mem::ManuallyDrop::new(VARIANT_0_0 {
vt: windows::Win32::System::Com::VT_DISPATCH,
Anonymous: VARIANT_0_0_0 {
pdispVal: std::mem::ManuallyDrop::new(Some(idispatch)),
},
..Default::default()
})
}
})
}
fn persistent_id(&self) -> windows::core::Result<PersistentId> {
self.iTunes().GetITObjectPersistentID(&self.as_variant())
}
get_bstr!(
Name as IITObject);
set_bstr!(
Name as IITObject);
get_long!(
Index as IITObject);
get_long!(
sourceID as IITObject);
get_long!(
playlistID as IITObject);
get_long!(
trackID as IITObject);
get_long!(
TrackDatabaseID as IITObject);
}
pub enum PossibleIITObject {
Source(Source),
Playlist(Playlist),
Track(Track),
}
impl PossibleIITObject {
fn from_com_object(com_object: IITObject, iTunes: Arc<iTunes>) -> windows::core::Result<PossibleIITObject> {
if let Ok(source) = com_object.cast::<IITSource>() {
Ok(PossibleIITObject::Source(Source::from_com_object(source, iTunes)))
} else if let Ok(playlist) = com_object.cast::<IITPlaylist>() {
Ok(PossibleIITObject::Playlist(Playlist::from_com_object(playlist, iTunes)))
} else if let Ok(track) = com_object.cast::<IITTrack>() {
Ok(PossibleIITObject::Track(Track::from_com_object(track, iTunes)))
} else {
Err(windows::core::Error::new(
NS_E_PROPERTY_NOT_FOUND, windows::h!("Item not found").clone(),
))
}
}
pub fn as_source(&self) -> Option<&Source> {
match self {
PossibleIITObject::Source(s) => Some(s),
_ => None
}
}
pub fn as_playlist(&self) -> Option<&Playlist> {
match self {
PossibleIITObject::Playlist(p) => Some(p),
_ => None
}
}
pub fn as_track(&self) -> Option<&Track> {
match self {
PossibleIITObject::Track(t) => Some(t),
_ => None
}
}
}
com_wrapper_struct!(
Source);
impl IITObjectWrapper for Source {}
impl Source {
get_enum!(
pub Kind -> ITSourceKind);
get_double!(
pub Capacity);
get_double!(
pub FreeSpace);
get_object!(
pub Playlists -> PlaylistCollection);
}
com_wrapper_struct!(
PlaylistCollection);
impl PlaylistCollection {
item_by_name!(
pub Playlist);
item_by_persistent_id!(
pub Playlist);
}
iterator!(PlaylistCollection, Playlist);
pub trait IITPlaylistWrapper: private::ComObjectWrapper {
fn as_user_playlist(&self) -> Option<UserPlaylist> {
let com_user_pl = self.com_object().cast::<IITUserPlaylist>().ok()?;
let iTunes = self.iTunes();
Some(UserPlaylist::from_com_object(com_user_pl, iTunes))
}
no_args!(
Delete as IITPlaylist);
no_args!(
PlayFirstTrack as IITPlaylist);
fn Print(&self, showPrintDialog: bool, printKind: ITPlaylistPrintKind, theme: String) -> windows::core::Result<()> {
let show = if showPrintDialog { TRUE } else { FALSE };
str_to_bstr!(theme, theme);
let inherited_obj = self.com_object().cast::<IITPlaylist>()?;
let result = unsafe{ inherited_obj.Print(show, printKind, theme) };
result.ok()
}
fn Search(&self, searchText: String, searchFields: ITPlaylistSearchField) -> windows::core::Result<TrackCollection> {
str_to_bstr!(searchText, searchText);
let mut out_obj = None;
let inherited_obj = self.com_object().cast::<IITPlaylist>()?;
let result = unsafe{ inherited_obj.Search(searchText, searchFields, &mut out_obj as *mut _) };
result.ok()?;
let iTunes_arc = self.iTunes();
create_wrapped_object!(TrackCollection, out_obj, iTunes_arc)
}
get_enum!(
Kind -> ITPlaylistKind as IITPlaylist);
get_object!(
Source -> Source as IITPlaylist);
get_long!(
Duration as IITPlaylist);
get_bool!(
Shuffle as IITPlaylist);
set_bool!(
Shuffle as IITPlaylist);
get_double!(
Size as IITPlaylist);
get_enum!(
SongRepeat -> ITPlaylistRepeatMode as IITPlaylist);
set_enum!(
SongRepeat, ITPlaylistRepeatMode as IITPlaylist);
get_bstr!(
Time as IITPlaylist);
get_bool!(
Visible as IITPlaylist);
get_object!(
Tracks -> TrackCollection as IITPlaylist);
}
com_wrapper_struct!(
Playlist);
impl IITObjectWrapper for Playlist {}
impl IITPlaylistWrapper for Playlist {}
com_wrapper_struct!(
TrackCollection);
impl TrackCollection {
get_object_from_long!(
pub ItemByPlayOrder(Index) -> Track);
item_by_name!(
pub Track);
item_by_persistent_id!(
pub Track);
}
iterator!(TrackCollection, Track);
pub trait IITTrackWrapper: private::ComObjectWrapper {
no_args!(
Delete as IITTrack);
no_args!(
Play as IITTrack);
get_object_from_str!(
AddArtworkFromFile(filePath) -> Artwork as IITTrack);
get_enum!(
Kind -> ITTrackKind as IITTrack);
get_object!(
Playlist -> Playlist as IITTrack);
get_bstr!(
Album as IITTrack);
set_bstr!(
Album as IITTrack);
get_bstr!(
Artist as IITTrack);
set_bstr!(
Artist as IITTrack);
get_long!(
BitRate as IITTrack);
get_long!(
BPM as IITTrack);
set_long!(
BPM as IITTrack);
get_bstr!(
Comment as IITTrack);
set_bstr!(
Comment as IITTrack);
get_bool!(
Compilation as IITTrack);
set_bool!(
Compilation as IITTrack);
get_bstr!(
Composer as IITTrack);
set_bstr!(
Composer as IITTrack);
get_date!(
DateAdded as IITTrack);
get_long!(
DiscCount as IITTrack);
set_long!(
DiscCount as IITTrack);
get_long!(
DiscNumber as IITTrack);
set_long!(
DiscNumber as IITTrack);
get_long!(
Duration as IITTrack);
get_bool!(
Enabled as IITTrack);
set_bool!(
Enabled as IITTrack);
get_bstr!(
EQ as IITTrack);
set_bstr!(
EQ as IITTrack);
set_long!(
Finish as IITTrack);
get_long!(
Finish as IITTrack);
get_bstr!(
Genre as IITTrack);
set_bstr!(
Genre as IITTrack);
get_bstr!(
Grouping as IITTrack);
set_bstr!(
Grouping as IITTrack);
get_bstr!(
KindAsString as IITTrack);
get_date!(
ModificationDate as IITTrack);
get_long!(
PlayedCount as IITTrack);
set_long!(
PlayedCount as IITTrack);
get_date!(
PlayedDate as IITTrack);
set_date!(
PlayedDate as IITTrack);
get_long!(
PlayOrderIndex as IITTrack);
get_rating!(
Rating as IITTrack);
set_rating!(
Rating as IITTrack);
get_long!(
SampleRate as IITTrack);
get_long!(
Size as IITTrack);
get_long!(
Start as IITTrack);
set_long!(
Start as IITTrack);
get_bstr!(
Time as IITTrack);
get_long!(
TrackCount as IITTrack);
set_long!(
TrackCount as IITTrack);
get_long!(
TrackNumber as IITTrack);
set_long!(
TrackNumber as IITTrack);
get_long!(
VolumeAdjustment as IITTrack);
set_long!(
VolumeAdjustment as IITTrack);
get_long!(
Year as IITTrack);
set_long!(
Year as IITTrack);
get_object!(
Artwork -> ArtworkCollection as IITTrack);
}
com_wrapper_struct!(
Track);
impl IITObjectWrapper for Track {}
impl IITTrackWrapper for Track {}
impl Track {
pub fn as_file_or_cd_track(&self) -> Option<FileOrCDTrack> {
let foct = self.com_object.cast::<IITFileOrCDTrack>().ok()?;
let iTunes_arc = self.iTunes();
Some(FileOrCDTrack::from_com_object(foct, iTunes_arc))
}
}
com_wrapper_struct!(
Artwork);
impl Artwork {
no_args!(
pub Delete);
set_bstr!(
pub SetArtworkFromFile, no_set_prefix);
set_bstr!(
pub SaveArtworkToFile, no_set_prefix);
get_enum!(
pub Format -> ITArtworkFormat);
get_bool!(
pub IsDownloadedArtwork);
get_bstr!(
pub Description);
set_bstr!(
pub Description);
}
com_wrapper_struct!(
ArtworkCollection);
impl ArtworkCollection {}
iterator!(ArtworkCollection, Artwork);
com_wrapper_struct!(
SourceCollection);
impl SourceCollection {
item_by_name!(
pub Source);
item_by_persistent_id!(
pub Source);
}
iterator!(SourceCollection, Source);
com_wrapper_struct!(
Encoder);
impl Encoder {
get_bstr!(
pub Name);
get_bstr!(
pub Format);
}
com_wrapper_struct!(
EncoderCollection);
impl EncoderCollection {
item_by_name!(
pub Encoder);
}
iterator!(EncoderCollection, Encoder);
com_wrapper_struct!(
EQPreset);
impl EQPreset {
get_bstr!(
pub Name);
get_bool!(
pub Modifiable);
get_double!(
pub Preamp);
set_double!(
pub Preamp);
get_double!(
pub Band1);
set_double!(
pub Band1);
get_double!(
pub Band2);
set_double!(
pub Band2);
get_double!(
pub Band3);
set_double!(
pub Band3);
get_double!(
pub Band4);
set_double!(
pub Band4);
get_double!(
pub Band5);
set_double!(
pub Band5);
get_double!(
pub Band6);
set_double!(
pub Band6);
get_double!(
pub Band7);
set_double!(
pub Band7);
get_double!(
pub Band8);
set_double!(
pub Band8);
get_double!(
pub Band9);
set_double!(
pub Band9);
get_double!(
pub Band10);
set_double!(
pub Band10);
internal_set_bool!(
pub Delete(updateAllTracks) as <Self as ComObjectWrapper>::WrappedType);
pub fn Rename(&self, newName: String, updateAllTracks: bool) -> windows::core::Result<()> {
str_to_bstr!(newName, bstr);
let var_bool = if updateAllTracks { TRUE } else { FALSE };
let result = unsafe { self.com_object.Rename(bstr, var_bool) };
result.ok()
}
}
com_wrapper_struct!(
EQPresetCollection);
impl EQPresetCollection {
item_by_name!(
pub EQPreset);
}
iterator!(EQPresetCollection, EQPreset);
com_wrapper_struct!(
OperationStatus);
impl OperationStatus {
get_bool!(
pub InProgress);
get_object!(
pub Tracks -> TrackCollection);
}
#[derive(Debug)]
pub struct ConversionStatus {
pub trackName: String,
pub progressValue: LONG,
pub maxProgressValue: LONG,
}
com_wrapper_struct!(
ConvertOperationStatus);
impl ConvertOperationStatus {
pub fn GetConversionStatus(&self) -> windows::core::Result<ConversionStatus> {
let mut bstr = BSTR::default();
let mut progressValue = 0;
let mut maxProgressValue = 0;
let result = unsafe{ self.com_object.GetConversionStatus(&mut bstr, &mut progressValue as *mut LONG, &mut maxProgressValue as *mut LONG) };
result.ok()?;
let v: Vec<u16> = bstr.as_wide().to_vec();
let trackName = U16CString::from_vec_truncate(v).to_string_lossy();
Ok(ConversionStatus{ trackName, progressValue, maxProgressValue })
}
no_args!(
pub StopConversion);
get_bstr!(
pub trackName);
get_long!(
pub progressValue);
get_long!(
pub maxProgressValue);
}
com_wrapper_struct!(
LibraryPlaylist);
impl IITObjectWrapper for LibraryPlaylist {}
impl IITPlaylistWrapper for LibraryPlaylist {}
impl LibraryPlaylist {
get_object_from_str!(
pub AddFile(filePath) -> OperationStatus);
get_object_from_variant!(
pub AddFiles(filePaths) -> OperationStatus);
get_object_from_str!(
pub AddURL(URL) -> URLTrack);
get_object_from_variant!(
pub AddTrack(iTrackToAdd) -> Track);
}
com_wrapper_struct!(
URLTrack);
impl IITObjectWrapper for URLTrack {}
impl IITTrackWrapper for URLTrack {}
impl URLTrack {
get_bstr!(
pub URL);
set_bstr!(
pub URL);
get_bool!(
pub Podcast);
no_args!(
pub UpdatePodcastFeed);
no_args!(
pub DownloadPodcastEpisode);
get_bstr!(
pub Category);
set_bstr!(
pub Category);
get_bstr!(
pub Description);
set_bstr!(
pub Description);
get_bstr!(
pub LongDescription);
set_bstr!(
pub LongDescription);
no_args!(
pub Reveal);
get_rating!(
pub AlbumRating);
set_rating!(
pub AlbumRating);
get_enum!(
pub AlbumRatingKind -> ITRatingKind);
get_enum!(
pub ratingKind -> ITRatingKind);
get_object!(
pub Playlists -> PlaylistCollection);
}
com_wrapper_struct!(
UserPlaylist);
impl IITObjectWrapper for UserPlaylist {}
impl IITPlaylistWrapper for UserPlaylist {}
impl UserPlaylist {
get_object_from_str!(
pub AddFile(filePath) -> OperationStatus);
get_object_from_variant!(
pub AddFiles(filePaths) -> OperationStatus);
get_object_from_str!(
pub AddURL(URL) -> URLTrack);
get_object_from_variant!(
pub AddTrack(iTrackToAdd) -> Track);
get_bool!(
pub Shared);
set_bool!(
pub Shared);
get_bool!(
pub Smart);
get_enum!(
pub SpecialKind -> ITUserPlaylistSpecialKind);
get_object!(
pub Parent -> UserPlaylist);
get_object_from_str!(
pub CreatePlaylist(playlistName) -> Playlist);
get_object_from_str!(
pub CreateFolder(folderName) -> Playlist);
set_playlist!(
pub Parent(iParentPlayList));
no_args!(
pub Reveal);
}
com_wrapper_struct!(
Visual);
impl Visual {
get_bstr!(
pub Name);
}
com_wrapper_struct!(
VisualCollection);
impl VisualCollection {
item_by_name!(
pub Visual);
}
iterator!(VisualCollection, Visual);
com_wrapper_struct!(
Window);
impl Window {
get_bstr!(
pub Name);
get_enum!(
pub Kind -> ITWindowKind);
get_bool!(
pub Visible);
set_bool!(
pub Visible);
get_bool!(
pub Resizable);
get_bool!(
pub Minimized);
set_bool!(
pub Minimized);
get_bool!(
pub Maximizable);
get_bool!(
pub Maximized);
set_bool!(
pub Maximized);
get_bool!(
pub Zoomable);
get_bool!(
pub Zoomed);
set_bool!(
pub Zoomed);
get_long!(
pub Top);
set_long!(
pub Top);
get_long!(
pub Left);
set_long!(
pub Left);
get_long!(
pub Bottom);
set_long!(
pub Bottom);
get_long!(
pub Right);
set_long!(
pub Right);
get_long!(
pub Width);
set_long!(
pub Width);
get_long!(
pub Height);
set_long!(
pub Height);
}
com_wrapper_struct!(
BrowserWindow);
impl BrowserWindow {
get_bool!(
pub MiniPlayer);
set_bool!(
pub MiniPlayer);
get_object!(
pub SelectedTracks -> TrackCollection);
get_object!(
pub SelectedPlaylist -> Playlist);
set_playlist!(
pub SelectedPlaylist(iPlaylist));
}
com_wrapper_struct!(
WindowCollection);
impl WindowCollection {
item_by_name!(
pub Window);
}
iterator!(WindowCollection, Window);
#[derive(Debug, Eq, PartialEq)]
pub struct PlayerButtonState {
pub previousEnabled: bool,
pub playPauseStopState: ITPlayButtonState,
pub nextEnabled: bool,
}
pub struct iTunes {
com_object: crate::sys::IiTunes,
}
impl private::ComObjectWrapper for iTunes {
type WrappedType = crate::sys::IiTunes;
fn from_com_object(_com_object: crate::sys::IiTunes, _iTunes: Arc<iTunes>) -> Self {
panic!("This function is not supposed to be called");
}
fn com_object(&self) -> &crate::sys::IiTunes {
&self.com_object
}
fn iTunes(&self) -> Arc<iTunes> {
Arc::new(Self{
com_object: self.com_object.clone()
})
}
}
impl iTunes {
pub fn new() -> windows::core::Result<Self> {
unsafe {
CoInitializeEx(None, COINIT_MULTITHREADED)?;
}
Ok(Self {
com_object: unsafe { CoCreateInstance(&crate::sys::ITUNES_APP_COM_GUID, None, CLSCTX_ALL)? },
})
}
no_args!(
pub BackTrack);
no_args!(
pub FastForward);
no_args!(
pub NextTrack);
no_args!(
pub Pause);
no_args!(
pub Play);
set_bstr!(
pub PlayFile, no_set_prefix);
no_args!(
pub PlayPause);
no_args!(
pub PreviousTrack);
no_args!(
pub Resume);
no_args!(
pub Rewind);
no_args!(
pub Stop);
get_object_from_str!(
pub ConvertFile(filePath) -> OperationStatus);
get_object_from_variant!(
pub ConvertFiles(filePaths) -> OperationStatus);
get_object_from_variant!(
pub ConvertTrack(iTrackToConvert) -> OperationStatus);
get_object_from_variant!(
pub ConvertTracks(iTracksToConvert) -> OperationStatus);
pub fn CheckVersion(&self, majorVersion: LONG, minorVersion: LONG) -> windows::core::Result<bool> {
let mut bool_result = FALSE;
let result = unsafe{ self.com_object.CheckVersion(majorVersion, minorVersion, &mut bool_result) };
result.ok()?;
Ok(bool_result.as_bool())
}
pub fn GetITObjectByID(&self, ids: ObjectIDs) -> windows::core::Result<PossibleIITObject> {
let mut out_obj: Option<IITObject> = None;
let result = unsafe{ self.com_object.GetITObjectByID(
ids.sourceID,
ids.playlistID,
ids.trackID,
ids.databaseID,
&mut out_obj as *mut _
) };
result.ok()?;
match out_obj {
None => Err(windows::core::Error::new(
NS_E_PROPERTY_NOT_FOUND, windows::h!("Item not found").clone(),
)),
Some(obj) => {
let iTunes_arc = self.iTunes();
PossibleIITObject::from_com_object(obj, iTunes_arc)
},
}
}
get_object_from_str!(
pub CreatePlaylist(playlistName) -> Playlist);
set_bstr!(
pub OpenURL, no_set_prefix);
no_args!(
pub GotoMusicStoreHomePage);
no_args!(
pub UpdateIPod);
no_args!(
pub Quit);
get_object!(
pub Sources -> SourceCollection);
get_object!(
pub Encoders -> EncoderCollection);
get_object!(
pub EQPresets -> EQPresetCollection);
get_object!(
pub Visuals -> VisualCollection);
get_object!(
pub Windows -> WindowCollection);
get_long!(
pub SoundVolume);
set_long!(
pub SoundVolume);
get_bool!(
pub Mute);
set_bool!(
pub Mute);
get_enum!(
pub PlayerState -> ITPlayerState);
get_long!(
pub PlayerPosition);
set_long!(
pub PlayerPosition);
get_object!(
pub CurrentEncoder -> Encoder);
set_object!(
pub CurrentEncoder, Encoder);
get_bool!(
pub VisualsEnabled);
set_bool!(
pub VisualsEnabled);
get_bool!(
pub FullScreenVisuals);
set_bool!(
pub FullScreenVisuals);
get_enum!(
pub VisualSize -> ITVisualSize);
set_enum!(
pub VisualSize, ITVisualSize);
get_object!(
pub CurrentVisual -> Visual);
set_object!(
pub CurrentVisual, Visual);
get_bool!(
pub EQEnabled);
set_bool!(
pub EQEnabled);
get_object!(
pub CurrentEQPreset -> EQPreset);
set_object!(
pub CurrentEQPreset, EQPreset);
get_bstr!(
pub CurrentStreamTitle);
get_bstr!(
pub set_CurrentStreamURL);
get_object!(
pub BrowserWindow -> BrowserWindow);
get_object!(
pub EQWindow -> Window);
get_object!(
pub LibrarySource -> Source);
get_object!(
pub LibraryPlaylist -> LibraryPlaylist);
get_object!(
pub CurrentTrack -> Track);
get_object!(
pub CurrentPlaylist -> Playlist);
get_object!(
pub SelectedTracks -> TrackCollection);
get_bstr!(
pub Version);
set_long!(
pub SetOptions, no_set_prefix);
get_object_from_str!(
pub ConvertFile2(filePath) -> ConvertOperationStatus);
get_object_from_variant!(
pub ConvertFiles2(filePaths) -> ConvertOperationStatus);
get_object_from_variant!(
pub ConvertTrack2(iTrackToConvert) -> ConvertOperationStatus);
get_object_from_variant!(
pub ConvertTracks2(iTracksToConvert) -> ConvertOperationStatus);
get_bool!(
pub AppCommandMessageProcessingEnabled);
set_bool!(
pub AppCommandMessageProcessingEnabled);
get_bool!(
pub ForceToForegroundOnDialog);
set_bool!(
pub ForceToForegroundOnDialog);
get_object_from_str!(
pub CreateEQPreset(eqPresetName) -> EQPreset);
pub fn CreatePlaylistInSource(&self, playlistName: &str, source: &Source) -> windows::core::Result<Playlist> {
str_to_bstr!(playlistName, bstr);
let vsource = source.as_variant();
let mut out_playlist = None;
let result = unsafe{ self.com_object.CreatePlaylistInSource(bstr, vsource.as_raw() as *const VARIANT, &mut out_playlist as *mut _) };
result.ok()?;
let iTunes_arc = self.iTunes();
create_wrapped_object!(Playlist, out_playlist, iTunes_arc)
}
pub fn GetPlayerButtonsState(&self) -> windows::core::Result<PlayerButtonState> {
let mut previousEnabled = FALSE;
let mut playPauseStopState = ITPlayButtonState::ITPlayButtonStatePlayDisabled;
let mut nextEnabled = FALSE;
let result = unsafe{ self.com_object.GetPlayerButtonsState(&mut previousEnabled, &mut playPauseStopState, &mut nextEnabled) };
result.ok()?;
Ok(PlayerButtonState{
previousEnabled: previousEnabled.as_bool(),
playPauseStopState,
nextEnabled: nextEnabled.as_bool(),
})
}
pub fn PlayerButtonClicked(&self, playerButton: ITPlayerButton, playerButtonModifierKeys: LONG) -> windows::core::Result<()> {
let result = unsafe{ self.com_object.PlayerButtonClicked(playerButton, playerButtonModifierKeys) };
result.ok()
}
pub fn CanSetShuffle(&self, iPlaylist: &Playlist) -> windows::core::Result<bool> {
let vplaylist = iPlaylist.as_variant();
let mut out_bool = FALSE;
let result = unsafe{ self.com_object.CanSetShuffle(vplaylist.as_raw() as *const VARIANT, &mut out_bool) };
result.ok()?;
Ok(out_bool.as_bool())
}
pub fn CanSetSongRepeat(&self, iPlaylist: &Playlist) -> windows::core::Result<bool> {
let vplaylist = iPlaylist.as_variant();
let mut out_bool = FALSE;
let result = unsafe{ self.com_object.CanSetSongRepeat(vplaylist.as_raw() as *const VARIANT, &mut out_bool) };
result.ok()?;
Ok(out_bool.as_bool())
}
get_object!(
pub ConvertOperationStatus -> ConvertOperationStatus);
set_bstr!(
pub SubscribeToPodcast, no_set_prefix);
no_args!(
pub UpdatePodcastFeeds);
get_object_from_str!(
pub CreateFolder(folderName) -> Playlist);
pub fn CreateFolderInSource(&self, folderName: &str, iSource: &Source) -> windows::core::Result<Playlist> {
str_to_bstr!(folderName, bstr);
let vsource = iSource.as_variant();
let mut out_playlist = None;
let result = unsafe{ self.com_object.CreateFolderInSource(bstr, vsource.as_raw() as *const VARIANT, &mut out_playlist as *mut _) };
result.ok()?;
let iTunes_arc = self.iTunes();
create_wrapped_object!(Playlist, out_playlist, iTunes_arc)
}
get_bool!(
pub SoundVolumeControlEnabled);
get_bstr!(
pub LibraryXMLPath);
pub fn GetITObjectPersistentID<T>(&self, iObject: &Variant<T>) -> windows::core::Result<PersistentId> {
let mut highID: LONG = 0;
let mut lowID: LONG = 0;
let result = unsafe{ self.com_object.GetITObjectPersistentIDs(iObject.as_raw() as *const VARIANT, &mut highID, &mut lowID) };
result.ok()?;
let bytes = [lowID.to_le_bytes(), highID.to_le_bytes()].concat();
Ok(PersistentId::from_le_bytes(bytes.try_into().unwrap())) }
get_long!(
pub PlayerPositionMS);
set_long!(
pub PlayerPositionMS);
}
com_wrapper_struct!(
AudioCDPlaylist);
impl IITObjectWrapper for AudioCDPlaylist {}
impl IITPlaylistWrapper for AudioCDPlaylist {}
impl AudioCDPlaylist {
get_bstr!(
pub Artist);
get_bool!(
pub Compilation);
get_bstr!(
pub Composer);
get_long!(
pub DiscCount);
get_long!(
pub DiscNumber);
get_bstr!(
pub Genre);
get_long!(
pub Year);
no_args!(
pub Reveal);
}
com_wrapper_struct!(
IPodSource);
impl IITObjectWrapper for IPodSource {}
impl IPodSource {
no_args!(
pub UpdateIPod);
no_args!(
pub EjectIPod);
get_bstr!(
pub SoftwareVersion);
}
com_wrapper_struct!(
FileOrCDTrack);
impl IITObjectWrapper for FileOrCDTrack {}
impl IITTrackWrapper for FileOrCDTrack {}
impl FileOrCDTrack {
get_bstr!(
pub Location);
no_args!(
pub UpdateInfoFromFile);
get_bool!(
pub Podcast);
no_args!(
pub UpdatePodcastFeed);
get_bool!(
pub RememberBookmark);
set_bool!(
pub RememberBookmark);
get_bool!(
pub ExcludeFromShuffle);
set_bool!(
pub ExcludeFromShuffle);
get_bstr!(
pub Lyrics);
set_bstr!(
pub Lyrics);
get_bstr!(
pub Category);
set_bstr!(
pub Category);
get_bstr!(
pub Description);
set_bstr!(
pub Description);
get_bstr!(
pub LongDescription);
set_bstr!(
pub LongDescription);
get_long!(
pub BookmarkTime);
set_long!(
pub BookmarkTime);
get_enum!(
pub VideoKind -> ITVideoKind);
set_enum!(
pub VideoKind, ITVideoKind);
get_long!(
pub SkippedCount);
set_long!(
pub SkippedCount);
get_date!(
pub SkippedDate);
set_date!(
pub SkippedDate);
get_bool!(
pub PartOfGaplessAlbum);
set_bool!(
pub PartOfGaplessAlbum);
get_bstr!(
pub AlbumArtist);
set_bstr!(
pub AlbumArtist);
get_bstr!(
pub Show);
set_bstr!(
pub Show);
get_long!(
pub SeasonNumber);
set_long!(
pub SeasonNumber);
get_bstr!(
pub EpisodeID);
set_bstr!(
pub EpisodeID);
get_long!(
pub EpisodeNumber);
set_long!(
pub EpisodeNumber);
pub fn Size(&self) -> windows::core::Result<i64> {
let mut highSize = 0;
let mut lowSize = 0;
let result = unsafe{ self.com_object.Size64High(&mut highSize) };
result.ok()?;
let result = unsafe{ self.com_object.Size64Low(&mut lowSize) };
result.ok()?;
let bytes = [lowSize.to_le_bytes(), highSize.to_le_bytes()].concat();
Ok(i64::from_le_bytes(bytes.try_into().unwrap())) }
get_bool!(
pub Unplayed);
set_bool!(
pub Unplayed);
get_bstr!(
pub SortAlbum);
set_bstr!(
pub SortAlbum);
get_bstr!(
pub SortAlbumArtist);
set_bstr!(
pub SortAlbumArtist);
get_bstr!(
pub SortArtist);
set_bstr!(
pub SortArtist);
get_bstr!(
pub SortComposer);
set_bstr!(
pub SortComposer);
get_bstr!(
pub SortName);
set_bstr!(
pub SortName);
get_bstr!(
pub SortShow);
set_bstr!(
pub SortShow);
no_args!(
pub Reveal);
get_rating!(
pub AlbumRating);
set_rating!(
pub AlbumRating);
get_enum!(
pub AlbumRatingKind -> ITRatingKind);
get_enum!(
pub ratingKind -> ITRatingKind);
get_object!(
pub Playlists -> PlaylistCollection);
set_bstr!(
pub Location);
get_date!(
pub ReleaseDate);
}
com_wrapper_struct!(
PlaylistWindow);
impl PlaylistWindow {
get_object!(
pub SelectedTracks -> TrackCollection);
get_object!(
pub Playlist -> Playlist);
}