using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.InteropServices;
using Vanara.Extensions;
using static Vanara.PInvoke.Ole32;
using static Vanara.PInvoke.PropSys;
namespace Vanara.Windows.Shell
{
/// A property store for a .
///
public sealed class ShellItemPropertyStore : PropertyStore
{
/// The shell item
private readonly ShellItem shellItem;
/// The flags.
private GETPROPERTYSTOREFLAGS flags = GETPROPERTYSTOREFLAGS.GPS_DEFAULT;
/// Initializes a new instance of the class.
/// The ShellItem instance.
/// The optional property changed handler.
internal ShellItemPropertyStore(ShellItem item, PropertyChangedEventHandler propChangedHandler = null)
{
shellItem = item;
Refresh();
if (propChangedHandler != null)
PropertyChanged += propChangedHandler;
}
/// Gets a property description list object containing descriptions of all properties.
/// A complete instance.
public PropertyDescriptionList Descriptions => shellItem.PropertyDescriptions;
/// Gets or sets a value indicating whether to include slow properties.
/// true if including slow properties; otherwise, false.
[DefaultValue(false)]
public bool IncludeSlow
{
get => flags.IsFlagSet(GETPROPERTYSTOREFLAGS.GPS_OPENSLOWITEM);
set
{
if (IncludeSlow == value) return;
flags = flags.SetFlags(GETPROPERTYSTOREFLAGS.GPS_OPENSLOWITEM, value);
if (value)
flags = flags.SetFlags(GETPROPERTYSTOREFLAGS.GPS_TEMPORARY | GETPROPERTYSTOREFLAGS.GPS_FASTPROPERTIESONLY, false);
Refresh();
}
}
/// Gets a value indicating whether the is read-only.
public override bool IsReadOnly => ReadOnly;
/// Gets or sets a value indicating whether to include only properties directly from the property handler.
/// true if no inherited properties; otherwise, false.
[DefaultValue(false)]
public bool NoInheritedProperties
{
get => flags.IsFlagSet(GETPROPERTYSTOREFLAGS.GPS_HANDLERPROPERTIESONLY);
set
{
if (NoInheritedProperties == value) return;
flags = flags.SetFlags(GETPROPERTYSTOREFLAGS.GPS_HANDLERPROPERTIESONLY, value);
if (value)
flags = flags.SetFlags(GETPROPERTYSTOREFLAGS.GPS_TEMPORARY | GETPROPERTYSTOREFLAGS.GPS_BESTEFFORT | GETPROPERTYSTOREFLAGS.GPS_FASTPROPERTIESONLY, false);
Refresh();
}
}
/// Gets or sets a value indicating whether properties can be read and written.
/// true if properties are read/write; otherwise, false.
[DefaultValue(true)]
public bool ReadOnly
{
get => !flags.IsFlagSet(GETPROPERTYSTOREFLAGS.GPS_READWRITE);
set
{
if (ReadOnly == value) return;
flags = flags.SetFlags(GETPROPERTYSTOREFLAGS.GPS_READWRITE, !value);
if (!value)
flags = flags.SetFlags(GETPROPERTYSTOREFLAGS.GPS_DELAYCREATION | GETPROPERTYSTOREFLAGS.GPS_TEMPORARY | GETPROPERTYSTOREFLAGS.GPS_BESTEFFORT | GETPROPERTYSTOREFLAGS.GPS_FASTPROPERTIESONLY, false);
else
flags = flags.SetFlags(GETPROPERTYSTOREFLAGS.GPS_HANDLERPROPERTIESONLY);
Refresh();
}
}
///
/// Gets or sets a value indicating whether this provides a writable store, with no initial properties, that exists
/// for the lifetime of the Shell item instance; basically, a property bag attached to the item instance..
///
/// true if temporary; otherwise, false.
[DefaultValue(false)]
public bool Temporary
{
get => flags.IsFlagSet(GETPROPERTYSTOREFLAGS.GPS_TEMPORARY);
set
{
if (Temporary == value) return;
flags = flags.SetFlags(GETPROPERTYSTOREFLAGS.GPS_TEMPORARY, value);
if (value)
{
flags = GETPROPERTYSTOREFLAGS.GPS_TEMPORARY;
ReadOnly = false;
}
else
{
flags = flags.SetFlags(GETPROPERTYSTOREFLAGS.GPS_TEMPORARY, false);
Refresh();
}
}
}
/// Gets the CLSID of a supplied property key.
/// The property key.
/// The CLSID related to the property key.
public Guid GetCLSID(PROPERTYKEY propertyKey)
{
shellItem.ThrowIfNoShellItem2();
return shellItem.iShellItem2.GetCLSID(propertyKey);
}
/// Refreshes this instance. This call is intended for internal use only and should not need to be called.
public void Refresh()
{
shellItem.ThrowIfNoShellItem2();
if (iprops != null)
Marshal.ReleaseComObject(iprops);
iprops = shellItem.iShellItem2.GetPropertyStore(flags, typeof(IPropertyStore).GUID);
}
}
}