using System;
using System.Runtime.InteropServices;
using Vanara.Extensions;
using Vanara.InteropServices;
namespace Vanara.PInvoke
{
public static partial class Shell32
{
/// Describes how a property should be treated.
[PInvokeData("Shtypes.h")]
[Flags]
public enum SHCOLSTATE
{
/// The value is displayed according to default settings for the column.
SHCOLSTATE_DEFAULT = 0x00000000,
/// The value is displayed as a string.
SHCOLSTATE_TYPE_STR = 0x00000001,
/// The value is displayed as an integer.
SHCOLSTATE_TYPE_INT = 0x00000002,
/// The value is displayed as a date/time.
SHCOLSTATE_TYPE_DATE = 0x00000003,
/// A mask for display type values SHCOLSTATE_TYPE_STR, SHCOLSTATE_TYPE_STR, and SHCOLSTATE_TYPE_DATE.
SHCOLSTATE_TYPEMASK = 0x0000000f,
/// The column should be on by default in Details view.
SHCOLSTATE_ONBYDEFAULT = 0x00000010,
/// Will be slow to compute. Perform on a background thread.
SHCOLSTATE_SLOW = 0x00000020,
/// Provided by a handler, not the folder.
SHCOLSTATE_EXTENDED = 0x00000040,
/// Not displayed in the context menu, but is listed in the More... dialog.
SHCOLSTATE_SECONDARYUI = 0x00000080,
/// Not displayed in the UI.
SHCOLSTATE_HIDDEN = 0x00000100,
/// VarCmp produces same result as IShellFolder::CompareIDs.
SHCOLSTATE_PREFER_VARCMP = 0x00000200,
/// PSFormatForDisplay produces same result as IShellFolder::CompareIDs.
SHCOLSTATE_PREFER_FMTCMP = 0x00000400,
/// Do not sort folders separately.
SHCOLSTATE_NOSORTBYFOLDERNESS = 0x00000800,
/// Only displayed in the UI.
SHCOLSTATE_VIEWONLY = 0x00010000,
/// Marks columns with values that should be read in a batch.
SHCOLSTATE_BATCHREAD = 0x00020000,
/// Grouping is disabled for this column.
SHCOLSTATE_NO_GROUPBY = 0x00040000,
/// Can't resize the column.
SHCOLSTATE_FIXED_WIDTH = 0x00001000,
/// The width is the same in all dpi.
SHCOLSTATE_NODPISCALE = 0x00002000,
/// Fixed width and height ratio.
SHCOLSTATE_FIXED_RATIO = 0x00004000,
/// Filters out new display flags.
SHCOLSTATE_DISPLAYMASK = 0x0000F000,
}
/// A value that specifies the desired format of the string.
[PInvokeData("Shtypes.h", MSDNShortId = "bb759820")]
public enum STRRET_TYPE : uint
{
/// The string is at the address specified by pOleStr member.
STRRET_WSTR = 0x0000,
///
/// The uOffset member value indicates the number of bytes from the beginning of the item identifier list where the string is located.
///
STRRET_OFFSET = 0x0001,
/// The string is returned in the cStr member.
STRRET_CSTR = 0x0002,
}
/// Contains a list of item identifiers.
[StructLayout(LayoutKind.Sequential)]
[PInvokeData("Shtypes.h", MSDNShortId = "bb773321")]
public struct ITEMIDLIST
{
/// A list of item identifiers.
public SHITEMID mkid;
}
/// Reports detailed information on an item in a Shell folder.
[StructLayout(LayoutKind.Sequential)]
[PInvokeData("Shtypes.h", MSDNShortId = "bb759781")]
public struct SHELLDETAILS
{
/// The alignment of the column heading and the subitem text in the column.
public ComCtl32.ListViewColumnFormat fmt;
/// he number of average-sized characters in the header.
public int cxChar;
///
/// An STRRET structure that includes a string with the requested information. To convert this structure to a string, use
/// StrRetToBuf or StrRetToStr.
///
public STRRET str;
}
/// Defines an item identifier.
[StructLayout(LayoutKind.Sequential)]
[PInvokeData("Shtypes.h", MSDNShortId = "bb759800")]
public struct SHITEMID
{
/// The size of identifier, in bytes, including itself.
public ushort cb;
/// A variable-length item identifier.
public byte[] abID;
}
/// Contains strings returned from the IShellFolder interface methods.
[StructLayout(LayoutKind.Explicit, Size = 264)]
[PInvokeData("Shtypes.h", MSDNShortId = "bb759820")]
public struct STRRET
{
/// A value that specifies the desired format of the string.
[FieldOffset(0)]
public STRRET_TYPE uType;
///
/// A pointer to the string. This memory must be allocated with CoTaskMemAlloc. It is the calling application's responsibility to
/// free this memory with CoTaskMemFree when it is no longer needed.
///
[FieldOffset(4)]
public StrPtrUni pOleStr; // must be freed by caller of GetDisplayNameOf
/// The offset into the item identifier list.
[FieldOffset(4)]
public uint uOffset; // Offset into SHITEMID
/// The buffer to receive the display name. CHAR[MAX_PATH]
[FieldOffset(4)]
public StrPtrAnsi cStr;
/// Performs an implicit conversion from to .
/// The instance.
/// The result of the conversion.
public static implicit operator string(in STRRET s) =>
ShlwApi.StrRetToBSTR(new PinnedObject(s), default, out var ret).Succeeded ? ret : null;
/// Returns a that represents this instance.
/// A that represents this instance.
public override string ToString() => (string)this ?? "";
}
internal class STRRETMarshaler : ICustomMarshaler
{
public static ICustomMarshaler GetInstance(string cookie) => new STRRETMarshaler();
public void CleanUpManagedData(object ManagedObj)
{
}
public void CleanUpNativeData(IntPtr pNativeData)
{
if (pNativeData == IntPtr.Zero) return;
pNativeData.ToStructure().pOleStr.Free();
Marshal.FreeCoTaskMem(pNativeData);
}
public int GetNativeDataSize() => Marshal.SizeOf(typeof(STRRET));
public IntPtr MarshalManagedToNative(object ManagedObj)
{
if (!(ManagedObj is string s)) throw new InvalidCastException();
var sr = new STRRET { uType = STRRET_TYPE.STRRET_WSTR };
sr.pOleStr.Assign(s);
return sr.MarshalToPtr(Marshal.AllocCoTaskMem, out var _);
}
public object MarshalNativeToManaged(IntPtr pNativeData) =>
pNativeData != IntPtr.Zero && ShlwApi.StrRetToBSTR(pNativeData, default, out var ret).Succeeded ? ret : null;
}
}
}