diff --git a/src/Files.App.CsWin32/ComPtr`1.cs b/src/Files.App.CsWin32/ComPtr`1.cs
deleted file mode 100644
index 2cceed532893..000000000000
--- a/src/Files.App.CsWin32/ComPtr`1.cs
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright (c) Files Community
-// Licensed under the MIT License.
-
-using System;
-using System.Runtime.CompilerServices;
-using Windows.Win32.Foundation;
-using Windows.Win32.System.Com;
-
-namespace Windows.Win32
-{
- ///
- /// Contains a COM pointer and a set of methods to work with the pointer safely.
- ///
- public unsafe struct ComPtr : IDisposable where T : unmanaged, IComIID
- {
- private T* _ptr;
-
- public readonly bool IsNull
- {
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- get => _ptr is null;
- }
-
- // Constructors
-
- public ComPtr(T* ptr)
- {
- _ptr = ptr;
-
- if (ptr is not null)
- ((IUnknown*)ptr)->AddRef();
- }
-
- // Methods
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void Attach(T* other)
- {
- if (_ptr is not null)
- ((IUnknown*)_ptr)->Release();
-
- _ptr = other;
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public T* Detach()
- {
- T* ptr = _ptr;
- _ptr = null;
- return ptr;
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public readonly T* Get()
- {
- return _ptr;
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public readonly T** GetAddressOf()
- {
- return (T**)Unsafe.AsPointer(ref Unsafe.AsRef(in this));
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public readonly HRESULT As(U** other) where U : unmanaged, IComIID
- {
- return ((IUnknown*)_ptr)->QueryInterface((Guid*)Unsafe.AsPointer(ref Unsafe.AsRef(in U.Guid)), (void**)other);
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public readonly HRESULT As(Guid* riid, IUnknown** other) where U : unmanaged, IComIID
- {
- return ((IUnknown*)_ptr)->QueryInterface(riid, (void**)other);
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public readonly HRESULT CoCreateInstance(Guid* rclsid, IUnknown* pUnkOuter = null, CLSCTX dwClsContext = CLSCTX.CLSCTX_LOCAL_SERVER)
- {
- return PInvoke.CoCreateInstance(rclsid, pUnkOuter, dwClsContext, (Guid*)Unsafe.AsPointer(ref Unsafe.AsRef(in T.Guid)), (void**)this.GetAddressOf());
- }
-
- // Disposer
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void Dispose()
- {
- T* ptr = _ptr;
- if (ptr is not null)
- {
- _ptr = null;
- ((IUnknown*)ptr)->Release();
- }
- }
- }
-}
diff --git a/src/Files.App.CsWin32/Extras.cs b/src/Files.App.CsWin32/Extras.cs
index 99fd57262dba..396aa7a1997e 100644
--- a/src/Files.App.CsWin32/Extras.cs
+++ b/src/Files.App.CsWin32/Extras.cs
@@ -11,13 +11,13 @@ namespace Windows.Win32
namespace Graphics.Gdi
{
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
- public unsafe delegate BOOL MONITORENUMPROC([In] HMONITOR param0, [In] HDC param1, [In][Out] RECT* param2, [In] LPARAM param3);
+ public unsafe delegate BOOL MonitorEnumProcDelegate([In] HMONITOR param0, [In] HDC param1, [In][Out] RECT* param2, [In] LPARAM param3);
}
namespace UI.WindowsAndMessaging
{
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
- public delegate LRESULT WNDPROC(HWND hWnd, uint msg, WPARAM wParam, LPARAM lParam);
+ public delegate LRESULT WndProcDelegate(HWND hWnd, uint uMsg, WPARAM wParam, LPARAM lParam);
}
public static partial class PInvoke
diff --git a/src/Files.App.CsWin32/Files.App.CsWin32.csproj b/src/Files.App.CsWin32/Files.App.CsWin32.csproj
index d3a5a5198de2..6533328aacb0 100644
--- a/src/Files.App.CsWin32/Files.App.CsWin32.csproj
+++ b/src/Files.App.CsWin32/Files.App.CsWin32.csproj
@@ -11,6 +11,7 @@
win-x86;win-x64;win-arm64
true
true
+ true
diff --git a/src/Files.App.CsWin32/IStorageProviderQuotaUI.cs b/src/Files.App.CsWin32/IStorageProviderQuotaUI.cs
index c7cd816b77fc..98d07bdd2c65 100644
--- a/src/Files.App.CsWin32/IStorageProviderQuotaUI.cs
+++ b/src/Files.App.CsWin32/IStorageProviderQuotaUI.cs
@@ -1,21 +1,44 @@
// Copyright (c) Files Community
// Licensed under the MIT License.
-using Files.Shared.Attributes;
using System;
+using System.Runtime.InteropServices;
+using System.Runtime.InteropServices.Marshalling;
using Windows.Win32.Foundation;
namespace Windows.Win32.System.WinRT
{
- public unsafe partial struct IStorageProviderQuotaUI : IComIID
+ [GeneratedComInterface, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("BA6295C3-312E-544F-9FD5-1F81B21F3649")]
+ public partial interface IStorageProviderQuotaUI
{
- [GeneratedVTableFunction(Index = 6)]
- public partial HRESULT GetQuotaTotalInBytes(ulong* value);
+ // Slot: 3
+ [PreserveSig]
+ [return: MarshalAs(UnmanagedType.Error)]
+ HRESULT GetIids(out uint iidCount, out nint iids);
- [GeneratedVTableFunction(Index = 8)]
- public partial HRESULT GetQuotaUsedInBytes(ulong* value);
+ // Slot: 4
+ [PreserveSig]
+ [return: MarshalAs(UnmanagedType.Error)]
+ HRESULT GetRuntimeClassName(out HSTRING className);
- [GuidRVAGen.Guid("BA6295C3-312E-544F-9FD5-1F81B21F3649")]
- public static partial ref readonly Guid Guid { get; }
+ // Slot: 5
+ [PreserveSig]
+ [return: MarshalAs(UnmanagedType.Error)]
+ HRESULT GetTrustLevel(out TrustLevel trustLevel);
+
+ // Slot: 6
+ [PreserveSig]
+ [return: MarshalAs(UnmanagedType.Error)]
+ HRESULT get_QuotaTotalInBytes(out ulong value);
+
+ // Slot: 7
+ [PreserveSig]
+ [return: MarshalAs(UnmanagedType.Error)]
+ HRESULT put_QuotaTotalInBytes(ulong value);
+
+ // Slot: 8
+ [PreserveSig]
+ [return: MarshalAs(UnmanagedType.Error)]
+ HRESULT get_QuotaUsedInBytes(out ulong value);
}
}
diff --git a/src/Files.App.CsWin32/IStorageProviderStatusUI.cs b/src/Files.App.CsWin32/IStorageProviderStatusUI.cs
index 3aa60c4255f9..1bb40406bfcc 100644
--- a/src/Files.App.CsWin32/IStorageProviderStatusUI.cs
+++ b/src/Files.App.CsWin32/IStorageProviderStatusUI.cs
@@ -1,18 +1,75 @@
// Copyright (c) Files Community
// Licensed under the MIT License.
-using Files.Shared.Attributes;
using System;
+using System.Runtime.InteropServices;
+using System.Runtime.InteropServices.Marshalling;
+using Windows.Storage.Provider;
using Windows.Win32.Foundation;
namespace Windows.Win32.System.WinRT
{
- public unsafe partial struct IStorageProviderStatusUI : IComIID
+ [GeneratedComInterface, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("D6B6A758-198D-5B80-977F-5FF73DA33118")]
+ public partial interface IStorageProviderStatusUI
{
- [GeneratedVTableFunction(Index = 14)]
- public partial HRESULT GetQuotaUI(IStorageProviderQuotaUI** result);
+ // Slot: 3
+ [PreserveSig]
+ [return: MarshalAs(UnmanagedType.Error)]
+ HRESULT GetIids(out uint iidCount, out nint iids);
- [GuidRVAGen.Guid("D6B6A758-198D-5B80-977F-5FF73DA33118")]
- public static partial ref readonly Guid Guid { get; }
+ // Slot: 4
+ [PreserveSig]
+ [return: MarshalAs(UnmanagedType.Error)]
+ HRESULT GetRuntimeClassName(out HSTRING className);
+
+ // Slot: 5
+ [PreserveSig]
+ [return: MarshalAs(UnmanagedType.Error)]
+ HRESULT GetTrustLevel(out TrustLevel trustLevel);
+
+ // Slot: 6
+ [PreserveSig]
+ [return: MarshalAs(UnmanagedType.Error)]
+ HRESULT get_ProviderState(out StorageProviderState value);
+
+ // Slot: 7
+ [PreserveSig]
+ [return: MarshalAs(UnmanagedType.Error)]
+ HRESULT put_ProviderState(StorageProviderState value);
+
+ // Slot: 8
+ [PreserveSig]
+ [return: MarshalAs(UnmanagedType.Error)]
+ HRESULT get_ProviderStateLabel(out HSTRING value);
+
+ // Slot: 9
+ [PreserveSig]
+ [return: MarshalAs(UnmanagedType.Error)]
+ HRESULT put_ProviderStateLabel(HSTRING value);
+
+ // Slot: 10
+ [PreserveSig]
+ [return: MarshalAs(UnmanagedType.Error)]
+ HRESULT get_ProviderStateIcon([MarshalAs(UnmanagedType.Interface)] out object /*IUriRuntimeClass*/ value);
+
+ // Slot: 11
+ [PreserveSig]
+ [return: MarshalAs(UnmanagedType.Error)]
+ HRESULT put_ProviderStateIcon([MarshalAs(UnmanagedType.Interface)] object /*IUriRuntimeClass*/ value);
+
+ // Slot: 12
+ [PreserveSig]
+ [return: MarshalAs(UnmanagedType.Error)]
+ HRESULT get_SyncStatusCommand([MarshalAs(UnmanagedType.Interface)] out IStorageProviderUICommand value);
+
+ // Slot: 13
+ [PreserveSig]
+ [return: MarshalAs(UnmanagedType.Error)]
+ HRESULT put_SyncStatusCommand([MarshalAs(UnmanagedType.Interface)] IStorageProviderUICommand value);
+
+ // Slot: 14
+ [PreserveSig]
+ [return: MarshalAs(UnmanagedType.Error)]
+ HRESULT get_QuotaUI([MarshalAs(UnmanagedType.Interface)] out IStorageProviderQuotaUI value);
}
}
diff --git a/src/Files.App.CsWin32/IStorageProviderStatusUISource.cs b/src/Files.App.CsWin32/IStorageProviderStatusUISource.cs
index 9f4ede28194f..064fffa9d06e 100644
--- a/src/Files.App.CsWin32/IStorageProviderStatusUISource.cs
+++ b/src/Files.App.CsWin32/IStorageProviderStatusUISource.cs
@@ -3,16 +3,33 @@
using Files.Shared.Attributes;
using System;
+using System.Runtime.InteropServices;
+using System.Runtime.InteropServices.Marshalling;
using Windows.Win32.Foundation;
namespace Windows.Win32.System.WinRT
{
- public unsafe partial struct IStorageProviderStatusUISource : IComIID
+ [GeneratedComInterface, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("A306C249-3D66-5E70-9007-E43DF96051FF")]
+ public partial interface IStorageProviderStatusUISource
{
- [GeneratedVTableFunction(Index = 6)]
- public partial HRESULT GetStatusUI(IStorageProviderStatusUI** result);
+ // Slot: 3
+ [PreserveSig]
+ [return: MarshalAs(UnmanagedType.Error)]
+ HRESULT GetIids(out uint iidCount, out nint iids);
- [GuidRVAGen.Guid("A306C249-3D66-5E70-9007-E43DF96051FF")]
- public static partial ref readonly Guid Guid { get; }
+ // Slot: 4
+ [PreserveSig]
+ [return: MarshalAs(UnmanagedType.Error)]
+ HRESULT GetRuntimeClassName(out HSTRING className);
+
+ // Slot: 5
+ [PreserveSig]
+ [return: MarshalAs(UnmanagedType.Error)]
+ HRESULT GetTrustLevel(out TrustLevel trustLevel);
+
+ // Slot: 6
+ [PreserveSig]
+ [return: MarshalAs(UnmanagedType.Error)]
+ HRESULT GetStatusUI([MarshalAs(UnmanagedType.Interface)] out IStorageProviderStatusUI value);
}
}
diff --git a/src/Files.App.CsWin32/IStorageProviderStatusUISourceFactory.cs b/src/Files.App.CsWin32/IStorageProviderStatusUISourceFactory.cs
index 4065c1800c10..016b375d1180 100644
--- a/src/Files.App.CsWin32/IStorageProviderStatusUISourceFactory.cs
+++ b/src/Files.App.CsWin32/IStorageProviderStatusUISourceFactory.cs
@@ -1,18 +1,34 @@
// Copyright (c) Files Community
// Licensed under the MIT License.
-using Files.Shared.Attributes;
using System;
+using System.Runtime.InteropServices;
+using System.Runtime.InteropServices.Marshalling;
using Windows.Win32.Foundation;
namespace Windows.Win32.System.WinRT
{
- public unsafe partial struct IStorageProviderStatusUISourceFactory : IComIID
+ [GeneratedComInterface, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("12E46B74-4E5A-58D1-A62F-0376E8EE7DD8")]
+ public partial interface IStorageProviderStatusUISourceFactory
{
- [GeneratedVTableFunction(Index = 6)]
- public partial HRESULT GetStatusUISource(nint syncRootId, IStorageProviderStatusUISource** result);
+ // Slot: 3
+ [PreserveSig]
+ [return: MarshalAs(UnmanagedType.Error)]
+ HRESULT GetIids(out uint iidCount, out nint iids);
- [GuidRVAGen.Guid("12E46B74-4E5A-58D1-A62F-0376E8EE7DD8")]
- public static partial ref readonly Guid Guid { get; }
+ // Slot: 4
+ [PreserveSig]
+ [return: MarshalAs(UnmanagedType.Error)]
+ HRESULT GetRuntimeClassName(out HSTRING className);
+
+ // Slot: 5
+ [PreserveSig]
+ [return: MarshalAs(UnmanagedType.Error)]
+ HRESULT GetTrustLevel(out TrustLevel trustLevel);
+
+ // Slot: 6
+ [PreserveSig]
+ [return: MarshalAs(UnmanagedType.Error)]
+ HRESULT GetStatusUISource([MarshalAs(UnmanagedType.LPWStr)] string syncRootId, [MarshalAs(UnmanagedType.Interface)] out IStorageProviderStatusUISource result);
}
}
diff --git a/src/Files.App.CsWin32/ManualGuid.cs b/src/Files.App.CsWin32/ManualGuid.cs
index f95973c45048..64cad9b16cae 100644
--- a/src/Files.App.CsWin32/ManualGuid.cs
+++ b/src/Files.App.CsWin32/ManualGuid.cs
@@ -9,9 +9,6 @@ namespace Windows.Win32
{
public static unsafe partial class IID
{
- public static Guid* IID_IStorageProviderStatusUISourceFactory
- => (Guid*)Unsafe.AsPointer(ref Unsafe.AsRef(in IStorageProviderStatusUISourceFactory.Guid));
-
[GuidRVAGen.Guid("000214E4-0000-0000-C000-000000000046")]
public static partial Guid* IID_IContextMenu { get; }
diff --git a/src/Files.App.CsWin32/NativeMethods.json b/src/Files.App.CsWin32/NativeMethods.json
index 2e32fa443533..af32e10fa478 100644
--- a/src/Files.App.CsWin32/NativeMethods.json
+++ b/src/Files.App.CsWin32/NativeMethods.json
@@ -1,8 +1,8 @@
{
"$schema": "https://aka.ms/CsWin32.schema.json",
- "allowMarshaling": false,
"public": true,
"comInterop": {
+ "useComSourceGenerators": true,
"preserveSigMethods": [
"*"
]
diff --git a/src/Files.App.CsWin32/NativeMethods.txt b/src/Files.App.CsWin32/NativeMethods.txt
index 9f10fdd3870b..f2af324c371f 100644
--- a/src/Files.App.CsWin32/NativeMethods.txt
+++ b/src/Files.App.CsWin32/NativeMethods.txt
@@ -1,6 +1,7 @@
// Copyright (c) Files Community
// Licensed under the MIT License.
+IActivationFactory
WNDPROC
WNDCLASSEXW
RegisterClassEx
@@ -125,6 +126,7 @@ SHQUERYRBINFO
SHQueryRecycleBin
FileOperation
IFileOperation
+IFileOperationProgressSink
IShellItem2
PSGetPropertyKeyFromName
ShellExecuteEx
diff --git a/src/Files.App.Server/Helpers.cs b/src/Files.App.Server/Helpers.cs
index 8ab3253540d5..f35a00f69afa 100644
--- a/src/Files.App.Server/Helpers.cs
+++ b/src/Files.App.Server/Helpers.cs
@@ -12,7 +12,7 @@ namespace Files.App.Server;
unsafe partial class Helpers
{
[UnmanagedCallersOnly(CallConvs = [typeof(CallConvStdcall)])]
- public static HRESULT GetActivationFactory(HSTRING activatableClassId, IActivationFactory** factory)
+ public static HRESULT GetActivationFactory(HSTRING activatableClassId, IActivationFactory_unmanaged** factory)
{
if (activatableClassId.IsNull || factory is null)
{
@@ -21,7 +21,7 @@ public static HRESULT GetActivationFactory(HSTRING activatableClassId, IActivati
try
{
- *factory = (IActivationFactory*)Module.GetActivationFactory(MarshalString.FromAbi((IntPtr)activatableClassId));
+ *factory = (IActivationFactory_unmanaged*)Module.GetActivationFactory(MarshalString.FromAbi((IntPtr)activatableClassId));
return *factory is null ? HRESULT.CLASS_E_CLASSNOTAVAILABLE : HRESULT.S_OK;
}
catch (Exception e)
diff --git a/src/Files.App.Server/Program.cs b/src/Files.App.Server/Program.cs
index b00061eaba85..ab497e73e5e7 100644
--- a/src/Files.App.Server/Program.cs
+++ b/src/Files.App.Server/Program.cs
@@ -42,13 +42,13 @@ static async Task Main()
unsafe
{
- delegate* unmanaged[Stdcall][] callbacks = new delegate* unmanaged[Stdcall][classIds.Length];
+ delegate* unmanaged[Stdcall][] callbacks = new delegate* unmanaged[Stdcall][classIds.Length];
for (int i = 0; i < callbacks.Length; i++)
{
callbacks[i] = &Helpers.GetActivationFactory;
}
- fixed (delegate* unmanaged[Stdcall]* pCallbacks = callbacks)
+ fixed (delegate* unmanaged[Stdcall]* pCallbacks = callbacks)
{
if (PInvoke.RoRegisterActivationFactories(classIds, pCallbacks, out cookie) is HRESULT hr && hr.Value != 0)
{
diff --git a/src/Files.App.Storage/Windows/Helpers/WindowsStorableHelpers.Icon.cs b/src/Files.App.Storage/Windows/Helpers/WindowsStorableHelpers.Icon.cs
index 01df95e5a916..2646b63be59f 100644
--- a/src/Files.App.Storage/Windows/Helpers/WindowsStorableHelpers.Icon.cs
+++ b/src/Files.App.Storage/Windows/Helpers/WindowsStorableHelpers.Icon.cs
@@ -44,14 +44,13 @@ public unsafe static HRESULT TryGetThumbnail(this IWindowsStorable storable, int
{
thumbnailData = null;
- using ComPtr pShellItemImageFactory = default;
- storable.ThisPtr->QueryInterface(IID.IID_IShellItemImageFactory, (void**)pShellItemImageFactory.GetAddressOf());
- if (pShellItemImageFactory.IsNull)
+ var shellItemImageFactory = (IShellItemImageFactory)storable.ThisPtr;
+ if (shellItemImageFactory is null)
return HRESULT.E_NOINTERFACE;
// Get HBITMAP
HBITMAP hBitmap = default;
- HRESULT hr = pShellItemImageFactory.Get()->GetImage(new(size, size), options, &hBitmap);
+ HRESULT hr = shellItemImageFactory.GetImage(new(size, size), options, &hBitmap);
if (hr.ThrowIfFailedOnDebug().Failed)
{
if (!hBitmap.IsNull) PInvoke.DeleteObject(hBitmap);
@@ -168,22 +167,21 @@ public unsafe static bool TryConvertGpBitmapToByteArray(GpBitmap* gpBitmap, out
encoder = GetEncoderClsid(format);
}
- using ComPtr pStream = default;
- HRESULT hr = PInvoke.CreateStreamOnHGlobal(HGLOBAL.Null, true, pStream.GetAddressOf());
+ HRESULT hr = PInvoke.CreateStreamOnHGlobal(HGLOBAL.Null, true, out var stream);
if (hr.ThrowIfFailedOnDebug().Failed)
{
if (gpBitmap is not null) PInvoke.GdipDisposeImage((GpImage*)gpBitmap);
return false;
}
- if (PInvoke.GdipSaveImageToStream((GpImage*)gpBitmap, pStream.Get(), &encoder, (EncoderParameters*)null) is not Status.Ok)
+ if (PInvoke.GdipSaveImageToStream((GpImage*)gpBitmap, stream, &encoder, (EncoderParameters*)null) is not Status.Ok)
{
if (gpBitmap is not null) PInvoke.GdipDisposeImage((GpImage*)gpBitmap);
return false;
}
STATSTG stat = default;
- hr = pStream.Get()->Stat(&stat, (uint)STATFLAG.STATFLAG_NONAME);
+ hr = stream.Stat(&stat, STATFLAG.STATFLAG_NONAME);
if (hr.ThrowIfFailedOnDebug().Failed)
{
if (gpBitmap is not null) PInvoke.GdipDisposeImage((GpImage*)gpBitmap);
@@ -193,8 +191,8 @@ public unsafe static bool TryConvertGpBitmapToByteArray(GpBitmap* gpBitmap, out
ulong statSize = stat.cbSize & 0xFFFFFFFF;
byte* RawThumbnailData = (byte*)NativeMemory.Alloc((nuint)statSize);
- pStream.Get()->Seek(0L, (SystemIO.SeekOrigin)STREAM_SEEK.STREAM_SEEK_SET, null);
- hr = pStream.Get()->Read(RawThumbnailData, (uint)statSize);
+ stream.Seek(0L, (SystemIO.SeekOrigin)STREAM_SEEK.STREAM_SEEK_SET, null);
+ hr = stream.Read(RawThumbnailData, (uint)statSize);
if (hr.ThrowIfFailedOnDebug().Failed)
{
if (gpBitmap is not null) PInvoke.GdipDisposeImage((GpImage*)gpBitmap);
@@ -266,14 +264,12 @@ public unsafe static HRESULT TrySetShortcutIcon(this IWindowsStorable storable,
if (iconFile.ToString() is not { } iconFilePath)
return HRESULT.E_INVALIDARG;
- using ComPtr pShellLink = default;
-
- HRESULT hr = storable.ThisPtr->BindToHandler(null, BHID.BHID_SFUIObject, IID.IID_IShellLinkW, (void**)pShellLink.GetAddressOf());
+ HRESULT hr = storable.ThisPtr.BindToHandler(null, BHID.BHID_SFUIObject, IID.IID_IShellLinkW, out var shellLinkObj);
+ var shellLink = (IShellLinkW)shellLinkObj;
if (hr.ThrowIfFailedOnDebug().Failed)
return hr;
- fixed (char* pszIconFilePath = iconFilePath)
- hr = pShellLink.Get()->SetIconLocation(iconFilePath, index);
+ hr = shellLink.SetIconLocation(iconFilePath, index);
if (hr.ThrowIfFailedOnDebug().Failed)
return hr;
diff --git a/src/Files.App.Storage/Windows/Helpers/WindowsStorableHelpers.Shell.cs b/src/Files.App.Storage/Windows/Helpers/WindowsStorableHelpers.Shell.cs
index 41eb10877af7..f80f3b33c242 100644
--- a/src/Files.App.Storage/Windows/Helpers/WindowsStorableHelpers.Shell.cs
+++ b/src/Files.App.Storage/Windows/Helpers/WindowsStorableHelpers.Shell.cs
@@ -19,8 +19,8 @@ public unsafe static partial class WindowsStorableHelpers
{
public static HRESULT GetPropertyValue(this IWindowsStorable storable, string propKey, out TValue value)
{
- using ComPtr pShellItem2 = default;
- HRESULT hr = storable.ThisPtr->QueryInterface(IID.IID_IShellItem2, (void**)pShellItem2.GetAddressOf());
+ HRESULT hr = default;
+ var shellItem2 = (IShellItem2)storable.ThisPtr;
PROPERTYKEY propertyKey = default;
fixed (char* pszPropertyKey = propKey)
@@ -29,7 +29,7 @@ public static HRESULT GetPropertyValue(this IWindowsStorable storable, s
if (typeof(TValue) == typeof(string))
{
ComHeapPtr szPropertyValue = default;
- hr = pShellItem2.Get()->GetString(&propertyKey, szPropertyValue.Get());
+ hr = shellItem2.GetString(&propertyKey, szPropertyValue.Get());
value = (TValue)(object)szPropertyValue.Get()->ToString();
return hr;
@@ -37,7 +37,7 @@ public static HRESULT GetPropertyValue(this IWindowsStorable storable, s
if (typeof(TValue) == typeof(bool))
{
bool fPropertyValue = false;
- hr = pShellItem2.Get()->GetBool(&propertyKey, (BOOL*)&fPropertyValue);
+ hr = shellItem2.GetBool(&propertyKey, (BOOL*)&fPropertyValue);
value = Unsafe.As(ref fPropertyValue);
return hr;
@@ -51,13 +51,13 @@ public static HRESULT GetPropertyValue(this IWindowsStorable storable, s
public static bool HasShellAttributes(this IWindowsStorable storable, SFGAO_FLAGS attributes)
{
- return storable.ThisPtr->GetAttributes(attributes, out var dwRetAttributes).Succeeded && dwRetAttributes == attributes;
+ return storable.ThisPtr.GetAttributes(attributes, out var dwRetAttributes).Succeeded && dwRetAttributes == attributes;
}
public static string GetDisplayName(this IWindowsStorable storable, SIGDN options = SIGDN.SIGDN_FILESYSPATH)
{
using ComHeapPtr pszName = default;
- HRESULT hr = storable.ThisPtr->GetDisplayName(options, (PWSTR*)pszName.GetAddressOf());
+ HRESULT hr = storable.ThisPtr.GetDisplayName(options, (PWSTR*)pszName.GetAddressOf());
return hr.ThrowIfFailedOnDebug().Succeeded
? new string((char*)pszName.Get()) // this is safe as it gets memcpy'd internally
@@ -68,10 +68,10 @@ public static HRESULT TryInvokeContextMenuVerb(this IWindowsStorable storable, s
{
Debug.Assert(Thread.CurrentThread.GetApartmentState() is ApartmentState.STA);
- using ComPtr pContextMenu = default;
- HRESULT hr = storable.ThisPtr->BindToHandler(null, BHID.BHID_SFUIObject, IID.IID_IContextMenu, (void**)pContextMenu.GetAddressOf());
+ HRESULT hr = storable.ThisPtr.BindToHandler(null, BHID.BHID_SFUIObject, IID.IID_IContextMenu, out var contextMenuObj);
+ var contextMenu = (IContextMenu)contextMenuObj;
HMENU hMenu = PInvoke.CreatePopupMenu();
- hr = pContextMenu.Get()->QueryContextMenu(hMenu, 0, 1, 0x7FFF, PInvoke.CMF_OPTIMIZEFORINVOKE);
+ hr = contextMenu.QueryContextMenu(hMenu, 0, 1, 0x7FFF, PInvoke.CMF_OPTIMIZEFORINVOKE);
CMINVOKECOMMANDINFO cmici = default;
cmici.cbSize = (uint)sizeof(CMINVOKECOMMANDINFO);
@@ -80,7 +80,7 @@ public static HRESULT TryInvokeContextMenuVerb(this IWindowsStorable storable, s
fixed (byte* pszVerbName = Encoding.ASCII.GetBytes(verbName))
{
cmici.lpVerb = new(pszVerbName);
- hr = pContextMenu.Get()->InvokeCommand(cmici);
+ hr = contextMenu.InvokeCommand(cmici);
if (!PInvoke.DestroyMenu(hMenu))
return HRESULT.E_FAIL;
@@ -93,10 +93,10 @@ public static HRESULT TryInvokeContextMenuVerbs(this IWindowsStorable storable,
{
Debug.Assert(Thread.CurrentThread.GetApartmentState() is ApartmentState.STA);
- using ComPtr pContextMenu = default;
- HRESULT hr = storable.ThisPtr->BindToHandler(null, BHID.BHID_SFUIObject, IID.IID_IContextMenu, (void**)pContextMenu.GetAddressOf());
+ HRESULT hr = storable.ThisPtr.BindToHandler(null, BHID.BHID_SFUIObject, IID.IID_IContextMenu, out var contextMenuObj);
+ var contextMenu = (IContextMenu)contextMenuObj;
HMENU hMenu = PInvoke.CreatePopupMenu();
- hr = pContextMenu.Get()->QueryContextMenu(hMenu, 0, 1, 0x7FFF, PInvoke.CMF_OPTIMIZEFORINVOKE);
+ hr = contextMenu.QueryContextMenu(hMenu, 0, 1, 0x7FFF, PInvoke.CMF_OPTIMIZEFORINVOKE);
CMINVOKECOMMANDINFO cmici = default;
cmici.cbSize = (uint)sizeof(CMINVOKECOMMANDINFO);
@@ -107,7 +107,7 @@ public static HRESULT TryInvokeContextMenuVerbs(this IWindowsStorable storable,
fixed (byte* pszVerbName = Encoding.ASCII.GetBytes(verbName))
{
cmici.lpVerb = new(pszVerbName);
- hr = pContextMenu.Get()->InvokeCommand(cmici);
+ hr = contextMenu.InvokeCommand(cmici);
if (!PInvoke.DestroyMenu(hMenu))
return HRESULT.E_FAIL;
@@ -124,12 +124,12 @@ public static HRESULT TryGetShellTooltip(this IWindowsStorable storable, out str
{
tooltip = null;
- using ComPtr pQueryInfo = default;
- HRESULT hr = storable.ThisPtr->BindToHandler(null, BHID.BHID_SFUIObject, IID.IID_IQueryInfo, (void**)pQueryInfo.GetAddressOf());
+ HRESULT hr = storable.ThisPtr.BindToHandler(null, BHID.BHID_SFUIObject, IID.IID_IQueryInfo, out var queryInfoObj);
+ var queryInfo = (IQueryInfo)queryInfoObj;
if (hr.ThrowIfFailedOnDebug().Failed)
return hr;
- pQueryInfo.Get()->GetInfoTip((uint)QITIPF_FLAGS.QITIPF_DEFAULT, out var pszTip);
+ queryInfo.GetInfoTip((uint)QITIPF_FLAGS.QITIPF_DEFAULT, out var pszTip);
if (hr.ThrowIfFailedOnDebug().Failed)
return hr;
@@ -143,27 +143,22 @@ public static HRESULT TryPinFolderToQuickAccess(this IWindowsFolder @this)
{
HRESULT hr = default;
- using ComPtr pExecuteCommand = default;
- using ComPtr pObjectWithSelection = default;
-
- hr = PInvoke.CoCreateInstance(CLSID.CLSID_PinToFrequentExecute, null, CLSCTX.CLSCTX_INPROC_SERVER, IID.IID_IExecuteCommand, (void**)pExecuteCommand.GetAddressOf());
+ hr = PInvoke.CoCreateInstance(*CLSID.CLSID_PinToFrequentExecute, null, CLSCTX.CLSCTX_INPROC_SERVER, out IExecuteCommand executeCommand);
if (hr.ThrowIfFailedOnDebug().Failed)
return hr;
- using ComPtr pShellItemArray = default;
- hr = PInvoke.SHCreateShellItemArrayFromShellItem(@this.ThisPtr, IID.IID_IShellItemArray, (void**)pShellItemArray.GetAddressOf());
+ hr = PInvoke.SHCreateShellItemArrayFromShellItem(@this.ThisPtr, *IID.IID_IShellItemArray, out var shellItemArrayObj);
+ var shellItemArray = (IShellItemArray)shellItemArrayObj;
if (hr.ThrowIfFailedOnDebug().Failed)
return hr;
- hr = pExecuteCommand.Get()->QueryInterface(IID.IID_IObjectWithSelection, (void**)pObjectWithSelection.GetAddressOf());
- if (hr.ThrowIfFailedOnDebug().Failed)
- return hr;
+ var objectWithSelection = (IObjectWithSelection)executeCommand;
- hr = pObjectWithSelection.Get()->SetSelection(pShellItemArray.Get());
+ hr = objectWithSelection.SetSelection(shellItemArray);
if (hr.ThrowIfFailedOnDebug().Failed)
return hr;
- hr = pExecuteCommand.Get()->Execute();
+ hr = executeCommand.Execute();
if (hr.ThrowIfFailedOnDebug().Failed)
return hr;
@@ -174,27 +169,22 @@ public static HRESULT TryUnpinFolderFromQuickAccess(this IWindowsFolder @this)
{
HRESULT hr = default;
- using ComPtr pExecuteCommand = default;
- using ComPtr pObjectWithSelection = default;
-
- hr = PInvoke.CoCreateInstance(CLSID.CLSID_UnPinFromFrequentExecute, null, CLSCTX.CLSCTX_INPROC_SERVER, IID.IID_IExecuteCommand, (void**)pExecuteCommand.GetAddressOf());
+ hr = PInvoke.CoCreateInstance(*CLSID.CLSID_UnPinFromFrequentExecute, null, CLSCTX.CLSCTX_INPROC_SERVER, out IExecuteCommand executeCommand);
if (hr.ThrowIfFailedOnDebug().Failed)
return hr;
- using ComPtr pShellItemArray = default;
- hr = PInvoke.SHCreateShellItemArrayFromShellItem(@this.ThisPtr, IID.IID_IShellItemArray, (void**)pShellItemArray.GetAddressOf());
+ hr = PInvoke.SHCreateShellItemArrayFromShellItem(@this.ThisPtr, *IID.IID_IShellItemArray, out var shellItemArrayObj);
+ var shellItemArray = (IShellItemArray)shellItemArrayObj;
if (hr.ThrowIfFailedOnDebug().Failed)
return hr;
- hr = pExecuteCommand.Get()->QueryInterface(IID.IID_IObjectWithSelection, (void**)pObjectWithSelection.GetAddressOf());
- if (hr.ThrowIfFailedOnDebug().Failed)
- return hr;
+ var objectWithSelection = (IObjectWithSelection)executeCommand;
- hr = pObjectWithSelection.Get()->SetSelection(pShellItemArray.Get());
+ hr = objectWithSelection.SetSelection(shellItemArray);
if (hr.ThrowIfFailedOnDebug().Failed)
return hr;
- hr = pExecuteCommand.Get()->Execute();
+ hr = executeCommand.Execute();
if (hr.ThrowIfFailedOnDebug().Failed)
return hr;
@@ -205,52 +195,43 @@ public static IEnumerable GetShellNewItems(this IWindows
{
HRESULT hr = default;
- IContextMenu* pNewMenu = default;
- using ComPtr pShellExtInit = default;
- using ComPtr pContextMenu2 = default;
-
- hr = PInvoke.CoCreateInstance(CLSID.CLSID_NewMenu, null, CLSCTX.CLSCTX_INPROC_SERVER, IID.IID_IContextMenu, (void**)&pNewMenu);
+ hr = PInvoke.CoCreateInstance(*CLSID.CLSID_NewMenu, null, CLSCTX.CLSCTX_INPROC_SERVER, out IContextMenu newMenu);
if (hr.ThrowIfFailedOnDebug().Failed)
return [];
- hr = pNewMenu->QueryInterface(IID.IID_IContextMenu2, (void**)pContextMenu2.GetAddressOf());
- if (hr.ThrowIfFailedOnDebug().Failed)
- return [];
+ var contextMenu2 = (IContextMenu2)newMenu;
+ var shellExtInit = (IShellExtInit)newMenu;
- hr = pNewMenu->QueryInterface(IID.IID_IShellExtInit, (void**)pShellExtInit.GetAddressOf());
- if (hr.ThrowIfFailedOnDebug().Failed)
- return [];
-
- @this.ShellNewMenu = pNewMenu;
+ @this.ShellNewMenu = newMenu;
- ITEMIDLIST* pFolderPidl = default;
- hr = PInvoke.SHGetIDListFromObject((IUnknown*)@this.ThisPtr, &pFolderPidl);
+ ITEMIDLIST* folderPidl = default;
+ hr = PInvoke.SHGetIDListFromObject(@this.ThisPtr, &folderPidl);
if (hr.ThrowIfFailedOnDebug().Failed)
return [];
- hr = pShellExtInit.Get()->Initialize(pFolderPidl, null, default);
+ hr = shellExtInit.Initialize(folderPidl, null, default);
if (hr.ThrowIfFailedOnDebug().Failed)
return [];
// Inserts "New (&W)"
HMENU hMenu = PInvoke.CreatePopupMenu();
- hr = pNewMenu->QueryContextMenu(hMenu, 0, 1, 256, 0);
+ hr = newMenu.QueryContextMenu(hMenu, 0, 1, 256, 0);
if (hr.ThrowIfFailedOnDebug().Failed)
return [];
// Invokes CNewMenu::_InitMenuPopup(), which populates the hSubMenu
HMENU hSubMenu = PInvoke.GetSubMenu(hMenu, 0);
- hr = pContextMenu2.Get()->HandleMenuMsg(PInvoke.WM_INITMENUPOPUP, (WPARAM)(nuint)hSubMenu.Value, 0);
+ hr = contextMenu2.HandleMenuMsg(PInvoke.WM_INITMENUPOPUP, (WPARAM)(nuint)hSubMenu.Value, 0);
if (hr.ThrowIfFailedOnDebug().Failed)
return [];
- uint dwCount = unchecked((uint)PInvoke.GetMenuItemCount(hSubMenu));
- if (dwCount is unchecked((uint)-1))
+ uint count = unchecked((uint)PInvoke.GetMenuItemCount(hSubMenu));
+ if (count is unchecked((uint)-1))
return [];
// Enumerates and populates the list
List shellNewItems = [];
- for (uint dwIndex = 0; dwIndex < dwCount; dwIndex++)
+ for (uint index = 0; index < count; index++)
{
MENUITEMINFOW mii = default;
mii.cbSize = (uint)sizeof(MENUITEMINFOW);
@@ -258,7 +239,7 @@ public static IEnumerable GetShellNewItems(this IWindows
mii.dwTypeData = (char*)NativeMemory.Alloc(256U);
mii.cch = 256;
- if (PInvoke.GetMenuItemInfo(hSubMenu, dwIndex, true, &mii))
+ if (PInvoke.GetMenuItemInfo(hSubMenu, index, true, &mii))
{
shellNewItems.Add(new()
{
@@ -280,13 +261,11 @@ public static bool InvokeShellNewItem(this IWindowsFolder @this, WindowsContextM
if (@this.ShellNewMenu is null)
{
- IContextMenu* pNewMenu = default;
-
- hr = PInvoke.CoCreateInstance(CLSID.CLSID_NewMenu, null, CLSCTX.CLSCTX_INPROC_SERVER, IID.IID_IContextMenu, (void**)&pNewMenu);
+ hr = PInvoke.CoCreateInstance(*CLSID.CLSID_NewMenu, null, CLSCTX.CLSCTX_INPROC_SERVER, out IContextMenu newMenu);
if (hr.ThrowIfFailedOnDebug().Failed)
return false;
- @this.ShellNewMenu = pNewMenu;
+ @this.ShellNewMenu = newMenu;
}
CMINVOKECOMMANDINFO cmici = default;
@@ -294,7 +273,7 @@ public static bool InvokeShellNewItem(this IWindowsFolder @this, WindowsContextM
cmici.lpVerb = (PCSTR)(byte*)item.Id;
cmici.nShow = (int)SHOW_WINDOW_CMD.SW_SHOWNORMAL;
- hr = @this.ShellNewMenu->InvokeCommand(&cmici);
+ hr = @this.ShellNewMenu.InvokeCommand(&cmici);
if (hr.ThrowIfFailedOnDebug().Failed)
return false;
diff --git a/src/Files.App.Storage/Windows/IWindowsFolder.cs b/src/Files.App.Storage/Windows/IWindowsFolder.cs
index 92160da97f48..641e4735c514 100644
--- a/src/Files.App.Storage/Windows/IWindowsFolder.cs
+++ b/src/Files.App.Storage/Windows/IWindowsFolder.cs
@@ -10,6 +10,6 @@ public unsafe interface IWindowsFolder : IWindowsStorable, IChildFolder
///
/// Gets or sets the cached for the ShellNew context menu.
///
- public IContextMenu* ShellNewMenu { get; set; }
+ public IContextMenu ShellNewMenu { get; set; }
}
}
diff --git a/src/Files.App.Storage/Windows/IWindowsStorable.cs b/src/Files.App.Storage/Windows/IWindowsStorable.cs
index c79ef3ba66cb..dd02fc950b80 100644
--- a/src/Files.App.Storage/Windows/IWindowsStorable.cs
+++ b/src/Files.App.Storage/Windows/IWindowsStorable.cs
@@ -7,8 +7,8 @@ namespace Files.App.Storage
{
public unsafe interface IWindowsStorable : IStorableChild, IEquatable, IDisposable
{
- IShellItem* ThisPtr { get; set; }
+ IShellItem ThisPtr { get; set; }
- IContextMenu* ContextMenu { get; set; }
+ IContextMenu ContextMenu { get; set; }
}
}
diff --git a/src/Files.App.Storage/Windows/Managers/SystemTrayManager.cs b/src/Files.App.Storage/Windows/Managers/SystemTrayManager.cs
index 6c861a097f74..1a838c101804 100644
--- a/src/Files.App.Storage/Windows/Managers/SystemTrayManager.cs
+++ b/src/Files.App.Storage/Windows/Managers/SystemTrayManager.cs
@@ -22,7 +22,7 @@ public unsafe partial class SystemTrayManager : IDisposable
Action _callback = null!;
private HWND _hWnd = default;
- private WNDPROC? _wndProc;
+ private WndProcDelegate? _wndProc;
private uint _dwTaskbarRestartMsgId;
private bool _isShown;
diff --git a/src/Files.App.Storage/Windows/Managers/TaskbarManager.cs b/src/Files.App.Storage/Windows/Managers/TaskbarManager.cs
deleted file mode 100644
index 1d8772239428..000000000000
--- a/src/Files.App.Storage/Windows/Managers/TaskbarManager.cs
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright (c) Files Community
-// Licensed under the MIT License.
-
-using Windows.Win32;
-using Windows.Win32.Foundation;
-using Windows.Win32.System.Com;
-using Windows.Win32.UI.Shell;
-
-namespace Files.App.Storage
-{
- public unsafe class TaskbarManager : IDisposable
- {
- private ComPtr pTaskbarList = default;
-
- private static TaskbarManager? _Default = null;
- public static TaskbarManager Default { get; } = _Default ??= new TaskbarManager();
-
- public TaskbarManager()
- {
- Guid CLSID_TaskbarList = typeof(TaskbarList).GUID;
- Guid IID_ITaskbarList3 = ITaskbarList3.IID_Guid;
- HRESULT hr = PInvoke.CoCreateInstance(
- &CLSID_TaskbarList,
- null,
- CLSCTX.CLSCTX_INPROC_SERVER,
- &IID_ITaskbarList3,
- (void**)pTaskbarList.GetAddressOf());
-
- if (hr.ThrowIfFailedOnDebug().Succeeded)
- hr = pTaskbarList.Get()->HrInit().ThrowIfFailedOnDebug();
- }
-
- public HRESULT SetProgressValue(HWND hwnd, ulong ullCompleted, ulong ullTotal)
- {
- return pTaskbarList.Get()->SetProgressValue(hwnd, ullCompleted, ullTotal);
- }
-
- public HRESULT SetProgressState(HWND hwnd, TBPFLAG tbpFlags)
- {
- return pTaskbarList.Get()->SetProgressState(hwnd, tbpFlags);
- }
-
- public void Dispose()
- {
- pTaskbarList.Dispose();
- }
- }
-}
diff --git a/src/Files.App.Storage/Windows/WindowsBulkOperations.cs b/src/Files.App.Storage/Windows/WindowsBulkOperations.cs
index d995d20ea71b..c48c2dbbf6a2 100644
--- a/src/Files.App.Storage/Windows/WindowsBulkOperations.cs
+++ b/src/Files.App.Storage/Windows/WindowsBulkOperations.cs
@@ -16,8 +16,8 @@ public unsafe partial class WindowsBulkOperations : IDisposable
{
// Fields
- private readonly IFileOperation* _pFileOperation;
- private readonly IFileOperationProgressSink* _pProgressSink;
+ private readonly IFileOperation _fileOperation;
+ private readonly IFileOperationProgressSink _pProgressSink;
private readonly uint _progressSinkCookie;
// Events
@@ -70,20 +70,18 @@ public unsafe partial class WindowsBulkOperations : IDisposable
/// Defines the behavior of the file operation, such as allowing undo and suppressing directory confirmation.
public unsafe WindowsBulkOperations(HWND ownerHWnd = default, FILEOPERATION_FLAGS flags = FILEOPERATION_FLAGS.FOF_ALLOWUNDO | FILEOPERATION_FLAGS.FOF_NOCONFIRMMKDIR)
{
- IFileOperation* pFileOperation = null;
- HRESULT hr = PInvoke.CoCreateInstance(CLSID.CLSID_FileOperation, null, CLSCTX.CLSCTX_LOCAL_SERVER, IID.IID_IFileOperation, (void**)&pFileOperation);
+ HRESULT hr = PInvoke.CoCreateInstance(CLSID.CLSID_FileOperation, null, CLSCTX.CLSCTX_LOCAL_SERVER, IID.IID_IFileOperation, out var fileOperationObj);
+ _fileOperation = (IFileOperation)fileOperationObj;
hr.ThrowIfFailedOnDebug();
- _pFileOperation = pFileOperation;
-
if (ownerHWnd != default)
- hr = _pFileOperation->SetOwnerWindow(ownerHWnd).ThrowIfFailedOnDebug();
+ hr = _fileOperation.SetOwnerWindow(ownerHWnd).ThrowIfFailedOnDebug();
- hr = _pFileOperation->SetOperationFlags(flags).ThrowIfFailedOnDebug();
+ hr = _fileOperation.SetOperationFlags(flags).ThrowIfFailedOnDebug();
- _pProgressSink = (IFileOperationProgressSink*)WindowsBulkOperationsSink.Create(this);
- hr = _pFileOperation->Advise(_pProgressSink, out var progressSinkCookie).ThrowIfFailedOnDebug();
+ _pProgressSink = new WindowsBulkOperationsSink(this);
+ hr = _fileOperation.Advise(_pProgressSink, out var progressSinkCookie).ThrowIfFailedOnDebug();
_progressSinkCookie = progressSinkCookie;
}
@@ -97,7 +95,7 @@ public unsafe WindowsBulkOperations(HWND ownerHWnd = default, FILEOPERATION_FLAG
public unsafe HRESULT QueueCopyOperation(WindowsStorable targetItem, WindowsFolder destinationFolder, string? copyName)
{
fixed (char* pszCopyName = copyName)
- return _pFileOperation->CopyItem(targetItem.ThisPtr, destinationFolder.ThisPtr, pszCopyName, _pProgressSink);
+ return _fileOperation.CopyItem(targetItem.ThisPtr, destinationFolder.ThisPtr, pszCopyName, _pProgressSink);
}
///
@@ -107,7 +105,7 @@ public unsafe HRESULT QueueCopyOperation(WindowsStorable targetItem, WindowsFold
/// If this method succeeds, it returns . Otherwise, it returns an error code.
public unsafe HRESULT QueueDeleteOperation(WindowsStorable targetItem)
{
- return _pFileOperation->DeleteItem(targetItem.ThisPtr, _pProgressSink);
+ return _fileOperation.DeleteItem(targetItem.ThisPtr, _pProgressSink);
}
///
@@ -120,7 +118,7 @@ public unsafe HRESULT QueueDeleteOperation(WindowsStorable targetItem)
public unsafe HRESULT QueueMoveOperation(WindowsStorable targetItem, WindowsFolder destinationFolder, string? newName)
{
fixed (char* pszNewName = newName)
- return _pFileOperation->MoveItem(targetItem.ThisPtr, destinationFolder.ThisPtr, pszNewName, null);
+ return _fileOperation.MoveItem(targetItem.ThisPtr, destinationFolder.ThisPtr, pszNewName, null);
}
///
@@ -134,7 +132,7 @@ public unsafe HRESULT QueueMoveOperation(WindowsStorable targetItem, WindowsFold
public unsafe HRESULT QueueCreateOperation(WindowsFolder destinationFolder, FILE_FLAGS_AND_ATTRIBUTES fileAttributes, string name, string? templateName)
{
fixed (char* pszName = name, pszTemplateName = templateName)
- return _pFileOperation->NewItem(destinationFolder.ThisPtr, (uint)fileAttributes, pszName, pszTemplateName, _pProgressSink);
+ return _fileOperation.NewItem(destinationFolder.ThisPtr, (uint)fileAttributes, pszName, pszTemplateName, _pProgressSink);
}
///
@@ -146,7 +144,7 @@ public unsafe HRESULT QueueCreateOperation(WindowsFolder destinationFolder, FILE
public unsafe HRESULT QueueRenameOperation(WindowsStorable targetItem, string newName)
{
fixed (char* pszNewName = newName)
- return _pFileOperation->RenameItem(targetItem.ThisPtr, pszNewName, _pProgressSink);
+ return _fileOperation.RenameItem(targetItem.ThisPtr, pszNewName, _pProgressSink);
}
///
@@ -155,7 +153,7 @@ public unsafe HRESULT QueueRenameOperation(WindowsStorable targetItem, string ne
/// If this method succeeds, it returns . Otherwise, it returns an error code.
public unsafe HRESULT PerformAllOperations()
{
- return _pFileOperation->PerformOperations();
+ return _fileOperation.PerformOperations();
}
// Disposer
@@ -164,10 +162,7 @@ public unsafe HRESULT PerformAllOperations()
public unsafe void Dispose()
{
if (_pProgressSink is not null)
- _pFileOperation->Unadvise(_progressSinkCookie);
-
- _pFileOperation->Release();
- _pProgressSink->Release();
+ _fileOperation.Unadvise(_progressSinkCookie);
}
}
}
diff --git a/src/Files.App.Storage/Windows/WindowsBulkOperationsSink.Methods.cs b/src/Files.App.Storage/Windows/WindowsBulkOperationsSink.Methods.cs
deleted file mode 100644
index f4b9f764b87c..000000000000
--- a/src/Files.App.Storage/Windows/WindowsBulkOperationsSink.Methods.cs
+++ /dev/null
@@ -1,173 +0,0 @@
-// Copyright (c) Files Community
-// Licensed under the MIT License.
-
-using Windows.Win32.Foundation;
-using Windows.Win32.UI.Shell;
-
-namespace Files.App.Storage
-{
- public sealed partial class WindowsBulkOperations : IDisposable
- {
- private unsafe partial struct WindowsBulkOperationsSink : IFileOperationProgressSink.Interface
- {
- public HRESULT StartOperations()
- {
- if (_operationsHandle.Target is WindowsBulkOperations operations)
- {
- operations.OperationsStarted?.Invoke(operations, EventArgs.Empty);
- return HRESULT.S_OK;
- }
-
- return HRESULT.E_FAIL;
- }
-
- public HRESULT FinishOperations(HRESULT hrResult)
- {
- if (_operationsHandle.Target is WindowsBulkOperations operations)
- {
- operations.OperationsFinished?.Invoke(operations, new(result: hrResult));
- return HRESULT.S_OK;
- }
-
- return HRESULT.E_FAIL;
- }
-
- public unsafe HRESULT PreRenameItem(uint dwFlags, IShellItem* pSource, PCWSTR pszNewName)
- {
- if (_operationsHandle.Target is WindowsBulkOperations operations)
- {
- operations.ItemRenaming?.Invoke(operations, new((_TRANSFER_SOURCE_FLAGS)dwFlags, WindowsStorable.TryParse(pSource), null, null, pszNewName.ToString(), null, default));
- return HRESULT.S_OK;
- }
-
- return HRESULT.E_FAIL;
- }
-
- public unsafe HRESULT PostRenameItem(uint dwFlags, IShellItem* pSource, PCWSTR pszNewName, HRESULT hrRename, IShellItem* psiNewlyCreated)
- {
- if (_operationsHandle.Target is WindowsBulkOperations operations)
- {
- operations.ItemRenamed?.Invoke(operations, new((_TRANSFER_SOURCE_FLAGS)dwFlags, WindowsStorable.TryParse(pSource), null, WindowsStorable.TryParse(psiNewlyCreated), pszNewName.ToString(), null, hrRename));
- return HRESULT.S_OK;
- }
-
- return HRESULT.E_FAIL;
- }
-
- public unsafe HRESULT PreMoveItem(uint dwFlags, IShellItem* pSource, IShellItem* psiDestinationFolder, PCWSTR pszNewName)
- {
- if (_operationsHandle.Target is WindowsBulkOperations operations)
- {
- operations.ItemMoving?.Invoke(operations, new((_TRANSFER_SOURCE_FLAGS)dwFlags, WindowsStorable.TryParse(pSource), new WindowsFolder(psiDestinationFolder), null, pszNewName.ToString(), null, default));
- return HRESULT.S_OK;
- }
-
- return HRESULT.E_FAIL;
- }
-
- public unsafe HRESULT PostMoveItem(uint dwFlags, IShellItem* pSource, IShellItem* psiDestinationFolder, PCWSTR pszNewName, HRESULT hrMove, IShellItem* psiNewlyCreated)
- {
- if (_operationsHandle.Target is WindowsBulkOperations operations)
- {
- operations.ItemMoved?.Invoke(operations, new((_TRANSFER_SOURCE_FLAGS)dwFlags, WindowsStorable.TryParse(pSource), new WindowsFolder(psiDestinationFolder), WindowsStorable.TryParse(psiNewlyCreated), pszNewName.ToString(), null, hrMove));
- return HRESULT.S_OK;
- }
-
- return HRESULT.E_FAIL;
- }
-
- public unsafe HRESULT PreCopyItem(uint dwFlags, IShellItem* pSource, IShellItem* psiDestinationFolder, PCWSTR pszNewName)
- {
- if (_operationsHandle.Target is WindowsBulkOperations operations)
- {
- operations.ItemCopying?.Invoke(operations, new((_TRANSFER_SOURCE_FLAGS)dwFlags, WindowsStorable.TryParse(pSource), new WindowsFolder(psiDestinationFolder), null, pszNewName.ToString(), null, default));
- return HRESULT.S_OK;
- }
-
- return HRESULT.E_FAIL;
- }
-
- public unsafe HRESULT PostCopyItem(uint dwFlags, IShellItem* pSource, IShellItem* psiDestinationFolder, PCWSTR pszNewName, HRESULT hrCopy, IShellItem* psiNewlyCreated)
- {
- if (_operationsHandle.Target is WindowsBulkOperations operations)
- {
- operations.ItemCopied?.Invoke(operations, new((_TRANSFER_SOURCE_FLAGS)dwFlags, WindowsStorable.TryParse(pSource), new WindowsFolder(psiDestinationFolder), WindowsStorable.TryParse(psiNewlyCreated), pszNewName.ToString(), null, hrCopy));
- return HRESULT.S_OK;
- }
-
- return HRESULT.E_FAIL;
- }
-
- public unsafe HRESULT PreDeleteItem(uint dwFlags, IShellItem* pSource)
- {
- if (_operationsHandle.Target is WindowsBulkOperations operations)
- {
- operations.ItemDeleting?.Invoke(operations, new((_TRANSFER_SOURCE_FLAGS)dwFlags, WindowsStorable.TryParse(pSource), null, null, null, null, default));
- return HRESULT.S_OK;
- }
-
- return HRESULT.E_FAIL;
- }
-
- public unsafe HRESULT PostDeleteItem(uint dwFlags, IShellItem* pSource, HRESULT hrDelete, IShellItem* psiNewlyCreated)
- {
- if (_operationsHandle.Target is WindowsBulkOperations operations)
- {
- operations.ItemDeleted?.Invoke(operations, new((_TRANSFER_SOURCE_FLAGS)dwFlags, WindowsStorable.TryParse(pSource), null, WindowsStorable.TryParse(psiNewlyCreated), null, null, hrDelete));
- return HRESULT.S_OK;
- }
-
- return HRESULT.E_FAIL;
- }
-
- public unsafe HRESULT PreNewItem(uint dwFlags, IShellItem* psiDestinationFolder, PCWSTR pszNewName)
- {
- if (_operationsHandle.Target is WindowsBulkOperations operations)
- {
- operations.ItemCreating?.Invoke(operations, new((_TRANSFER_SOURCE_FLAGS)dwFlags, null, new WindowsFolder(psiDestinationFolder), null, pszNewName.ToString(), null, default));
- return HRESULT.S_OK;
- }
-
- return HRESULT.E_FAIL;
- }
-
- public unsafe HRESULT PostNewItem(uint dwFlags, IShellItem* psiDestinationFolder, PCWSTR pszNewName, PCWSTR pszTemplateName, uint dwFileAttributes, HRESULT hrNew, IShellItem* psiNewItem)
- {
- if (_operationsHandle.Target is WindowsBulkOperations operations)
- {
- operations.ItemCreated?.Invoke(operations, new((_TRANSFER_SOURCE_FLAGS)dwFlags, null, new WindowsFolder(psiDestinationFolder), WindowsStorable.TryParse(psiNewItem), pszNewName.ToString(), pszTemplateName.ToString(), hrNew));
- return HRESULT.S_OK;
- }
-
- return HRESULT.E_FAIL;
- }
-
- public HRESULT UpdateProgress(uint iWorkTotal, uint iWorkSoFar)
- {
- if (_operationsHandle.Target is WindowsBulkOperations operations)
- {
- var percentage = iWorkTotal is 0 ? 0 : iWorkSoFar * 100.0 / iWorkTotal;
- operations.ProgressUpdated?.Invoke(operations, new((int)percentage, null));
- return HRESULT.S_OK;
- }
-
- return HRESULT.E_FAIL;
- }
-
- public HRESULT ResetTimer()
- {
- return HRESULT.E_NOTIMPL;
- }
-
- public HRESULT PauseTimer()
- {
- return HRESULT.E_NOTIMPL;
- }
-
- public HRESULT ResumeTimer()
- {
- return HRESULT.E_NOTIMPL;
- }
- }
- }
-}
diff --git a/src/Files.App.Storage/Windows/WindowsBulkOperationsSink.VTable.cs b/src/Files.App.Storage/Windows/WindowsBulkOperationsSink.VTable.cs
deleted file mode 100644
index 95c309023f76..000000000000
--- a/src/Files.App.Storage/Windows/WindowsBulkOperationsSink.VTable.cs
+++ /dev/null
@@ -1,161 +0,0 @@
-// Copyright (c) Files Community
-// Licensed under the MIT License.
-
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using Windows.Win32.Foundation;
-using Windows.Win32.UI.Shell;
-using WinRT.Interop;
-
-namespace Files.App.Storage
-{
- public sealed partial class WindowsBulkOperations : IDisposable
- {
- private unsafe partial struct WindowsBulkOperationsSink
- {
- private static readonly void** _lpPopulatedVtbl = PopulateVTable();
-
- private void** _lpVtbl;
- private volatile int _refCount;
- private GCHandle _operationsHandle;
-
- public static WindowsBulkOperationsSink* Create(WindowsBulkOperations operations)
- {
- WindowsBulkOperationsSink* operationsSink = (WindowsBulkOperationsSink*)NativeMemory.Alloc((nuint)sizeof(WindowsBulkOperationsSink));
- operationsSink->_lpVtbl = _lpPopulatedVtbl;
- operationsSink->_refCount = 1;
- operationsSink->_operationsHandle = GCHandle.Alloc(operations);
-
- return operationsSink;
- }
-
- private static void** PopulateVTable()
- {
- void** vtbl = (void**)RuntimeHelpers.AllocateTypeAssociatedMemory(typeof(WindowsBulkOperationsSink), sizeof(void*) * 19);
- vtbl[0] = (delegate* unmanaged)&Vtbl.QueryInterface;
- vtbl[1] = (delegate* unmanaged)&Vtbl.AddRef;
- vtbl[2] = (delegate* unmanaged)&Vtbl.Release;
- vtbl[3] = (delegate* unmanaged)&Vtbl.StartOperations;
- vtbl[4] = (delegate* unmanaged)&Vtbl.FinishOperations;
- vtbl[5] = (delegate* unmanaged)&Vtbl.PreRenameItem;
- vtbl[6] = (delegate* unmanaged)&Vtbl.PostRenameItem;
- vtbl[7] = (delegate* unmanaged)&Vtbl.PreMoveItem;
- vtbl[8] = (delegate* unmanaged)&Vtbl.PostMoveItem;
- vtbl[9] = (delegate* unmanaged)&Vtbl.PreCopyItem;
- vtbl[10] = (delegate* unmanaged)&Vtbl.PostCopyItem;
- vtbl[11] = (delegate* unmanaged)&Vtbl.PreDeleteItem;
- vtbl[12] = (delegate* unmanaged)&Vtbl.PostDeleteItem;
- vtbl[13] = (delegate* unmanaged)&Vtbl.PreNewItem;
- vtbl[14] = (delegate* unmanaged)&Vtbl.PostNewItem;
- vtbl[15] = (delegate* unmanaged)&Vtbl.UpdateProgress;
- vtbl[16] = (delegate* unmanaged)&Vtbl.ResetTimer;
- vtbl[17] = (delegate* unmanaged)&Vtbl.PauseTimer;
- vtbl[18] = (delegate* unmanaged)&Vtbl.ResumeTimer;
-
- return vtbl;
- }
-
- private static class Vtbl
- {
- [UnmanagedCallersOnly]
- public static HRESULT QueryInterface(WindowsBulkOperationsSink* @this, Guid* riid, void** ppv)
- {
- if (ppv is null)
- return HRESULT.E_POINTER;
-
- if (riid->Equals(IID.IID_IUnknown) || riid->Equals(IFileOperationProgressSink.IID_Guid))
- {
- Interlocked.Increment(ref @this->_refCount);
- *ppv = @this;
- return HRESULT.S_OK;
- }
-
- return HRESULT.E_NOINTERFACE;
- }
-
- [UnmanagedCallersOnly]
- public static int AddRef(WindowsBulkOperationsSink* @this)
- => Interlocked.Increment(ref @this->_refCount);
-
- [UnmanagedCallersOnly]
- public static int Release(WindowsBulkOperationsSink* @this)
- {
- int newRefCount = Interlocked.Decrement(ref @this->_refCount);
- if (newRefCount is 0)
- {
- if (@this->_operationsHandle.IsAllocated)
- @this->_operationsHandle.Free();
-
- NativeMemory.Free(@this);
- }
-
- return newRefCount;
- }
-
- [UnmanagedCallersOnly]
- public static HRESULT StartOperations(WindowsBulkOperationsSink* @this)
- => @this->StartOperations();
-
- [UnmanagedCallersOnly]
- public static HRESULT FinishOperations(WindowsBulkOperationsSink* @this, HRESULT hrResult)
- => @this->FinishOperations(hrResult);
-
- [UnmanagedCallersOnly]
- public static HRESULT PreRenameItem(WindowsBulkOperationsSink* @this, uint dwFlags, IShellItem* psiItem, PCWSTR pszNewName)
- => @this->PreRenameItem(dwFlags, psiItem, pszNewName);
-
- [UnmanagedCallersOnly]
- public static HRESULT PostRenameItem(WindowsBulkOperationsSink* @this, uint dwFlags, IShellItem* psiItem, PCWSTR pszNewName, HRESULT hrRename, IShellItem* psiNewlyCreated)
- => @this->PostRenameItem(dwFlags, psiItem, pszNewName, hrRename, psiNewlyCreated);
-
- [UnmanagedCallersOnly]
- public static HRESULT PreMoveItem(WindowsBulkOperationsSink* @this, uint dwFlags, IShellItem* psiItem, IShellItem* psiDestinationFolder, PCWSTR pszNewName)
- => @this->PreMoveItem(dwFlags, psiItem, psiDestinationFolder, pszNewName);
-
- [UnmanagedCallersOnly]
- public static HRESULT PostMoveItem(WindowsBulkOperationsSink* @this, uint dwFlags, IShellItem* psiItem, IShellItem* psiDestinationFolder, PCWSTR pszNewName, HRESULT hrMove, IShellItem* psiNewlyCreated)
- => @this->PostMoveItem(dwFlags, psiItem, psiDestinationFolder, pszNewName, hrMove, psiNewlyCreated);
-
- [UnmanagedCallersOnly]
- public static HRESULT PreCopyItem(WindowsBulkOperationsSink* @this, uint dwFlags, IShellItem* psiItem, IShellItem* psiDestinationFolder, PCWSTR pszNewName)
- => @this->PreCopyItem(dwFlags, psiItem, psiDestinationFolder, pszNewName);
-
- [UnmanagedCallersOnly]
- public static HRESULT PostCopyItem(WindowsBulkOperationsSink* @this, uint dwFlags, IShellItem* psiItem, IShellItem* psiDestinationFolder, PCWSTR pszNewName, HRESULT hrCopy, IShellItem* psiNewlyCreated)
- => @this->PostCopyItem(dwFlags, psiItem, psiDestinationFolder, pszNewName, hrCopy, psiNewlyCreated);
-
- [UnmanagedCallersOnly]
- public static HRESULT PreDeleteItem(WindowsBulkOperationsSink* @this, uint dwFlags, IShellItem* psiItem)
- => @this->PreDeleteItem(dwFlags, psiItem);
-
- [UnmanagedCallersOnly]
- public static HRESULT PostDeleteItem(WindowsBulkOperationsSink* @this, uint dwFlags, IShellItem* psiItem, HRESULT hrDelete, IShellItem* psiNewlyCreated)
- => @this->PostDeleteItem(dwFlags, psiItem, hrDelete, psiNewlyCreated);
-
- [UnmanagedCallersOnly]
- public static HRESULT PreNewItem(WindowsBulkOperationsSink* @this, uint dwFlags, IShellItem* psiDestinationFolder, PCWSTR pszNewName)
- => @this->PreNewItem(dwFlags, psiDestinationFolder, pszNewName);
-
- [UnmanagedCallersOnly]
- public static HRESULT PostNewItem(WindowsBulkOperationsSink* @this, uint dwFlags, IShellItem* psiDestinationFolder, PCWSTR pszNewName, PCWSTR pszTemplateName, uint dwFileAttributes, HRESULT hrNew, IShellItem* psiNewItem)
- => @this->PostNewItem(dwFlags, psiDestinationFolder, pszNewName, pszTemplateName, dwFileAttributes, hrNew, psiNewItem);
-
- [UnmanagedCallersOnly]
- public static HRESULT UpdateProgress(WindowsBulkOperationsSink* @this, uint iWorkTotal, uint iWorkSoFar)
- => @this->UpdateProgress(iWorkTotal, iWorkSoFar);
-
- [UnmanagedCallersOnly]
- public static HRESULT ResetTimer(WindowsBulkOperationsSink* @this)
- => @this->ResetTimer();
-
- [UnmanagedCallersOnly]
- public static HRESULT PauseTimer(WindowsBulkOperationsSink* @this)
- => @this->PauseTimer();
-
- [UnmanagedCallersOnly]
- public static HRESULT ResumeTimer(WindowsBulkOperationsSink* @this)
- => @this->ResumeTimer();
- }
- }
- }
-}
diff --git a/src/Files.App.Storage/Windows/WindowsBulkOperationsSink.cs b/src/Files.App.Storage/Windows/WindowsBulkOperationsSink.cs
new file mode 100644
index 000000000000..cfe74f49e126
--- /dev/null
+++ b/src/Files.App.Storage/Windows/WindowsBulkOperationsSink.cs
@@ -0,0 +1,131 @@
+// Copyright (c) Files Community
+// Licensed under the MIT License.
+
+using System.Runtime.InteropServices;
+using System.Runtime.InteropServices.Marshalling;
+using Windows.Win32.Foundation;
+using Windows.Win32.UI.Shell;
+
+namespace Files.App.Storage
+{
+ public sealed partial class WindowsBulkOperations : IDisposable
+ {
+ [GeneratedComClass]
+ private partial class WindowsBulkOperationsSink : IFileOperationProgressSink
+ {
+ private WindowsBulkOperations _operations;
+
+ public WindowsBulkOperationsSink(WindowsBulkOperations operations)
+ {
+ _operations = operations;
+ }
+
+ public HRESULT StartOperations()
+ {
+ _operations.OperationsStarted?.Invoke(_operations, EventArgs.Empty);
+
+ return HRESULT.S_OK;
+ }
+
+ public HRESULT FinishOperations(HRESULT hrResult)
+ {
+ _operations.OperationsFinished?.Invoke(_operations, new(result: hrResult));
+
+ return HRESULT.S_OK;
+ }
+
+ public HRESULT ResetTimer()
+ {
+ return HRESULT.E_NOTIMPL;
+ }
+
+ public HRESULT PauseTimer()
+ {
+ return HRESULT.E_NOTIMPL;
+ }
+
+ public HRESULT ResumeTimer()
+ {
+ return HRESULT.E_NOTIMPL;
+ }
+
+ [return: MarshalAs(UnmanagedType.Error)]
+ public HRESULT PreRenameItem(uint dwFlags, IShellItem psiItem, PCWSTR pszNewName)
+ {
+ _operations.ItemRenaming?.Invoke(_operations, new((_TRANSFER_SOURCE_FLAGS)dwFlags, WindowsStorable.TryParse(psiItem), null, null, pszNewName.ToString(), null, default));
+ return HRESULT.S_OK;
+ }
+
+ [return: MarshalAs(UnmanagedType.Error)]
+ public HRESULT PostRenameItem(uint dwFlags, IShellItem psiItem, PCWSTR pszNewName, HRESULT hrRename, IShellItem psiNewlyCreated)
+ {
+ _operations.ItemRenamed?.Invoke(_operations, new((_TRANSFER_SOURCE_FLAGS)dwFlags, WindowsStorable.TryParse(psiItem), null, WindowsStorable.TryParse(psiNewlyCreated), pszNewName.ToString(), null, hrRename));
+ return HRESULT.S_OK;
+ }
+
+ [return: MarshalAs(UnmanagedType.Error)]
+ public HRESULT PreMoveItem(uint dwFlags, IShellItem psiItem, IShellItem psiDestinationFolder, PCWSTR pszNewName)
+ {
+ _operations.ItemMoving?.Invoke(_operations, new((_TRANSFER_SOURCE_FLAGS)dwFlags, WindowsStorable.TryParse(psiItem), new WindowsFolder(psiDestinationFolder), null, pszNewName.ToString(), null, default));
+ return HRESULT.S_OK;
+ }
+
+ [return: MarshalAs(UnmanagedType.Error)]
+ public HRESULT PostMoveItem(uint dwFlags, IShellItem psiItem, IShellItem psiDestinationFolder, PCWSTR pszNewName, HRESULT hrMove, IShellItem psiNewlyCreated)
+ {
+ _operations.ItemMoved?.Invoke(_operations, new((_TRANSFER_SOURCE_FLAGS)dwFlags, WindowsStorable.TryParse(psiItem), new WindowsFolder(psiDestinationFolder), WindowsStorable.TryParse(psiNewlyCreated), pszNewName.ToString(), null, hrMove));
+ return HRESULT.S_OK;
+ }
+
+ [return: MarshalAs(UnmanagedType.Error)]
+ public HRESULT PreCopyItem(uint dwFlags, IShellItem psiItem, IShellItem psiDestinationFolder, PCWSTR pszNewName)
+ {
+ _operations.ItemCopying?.Invoke(_operations, new((_TRANSFER_SOURCE_FLAGS)dwFlags, WindowsStorable.TryParse(psiItem), new WindowsFolder(psiDestinationFolder), null, pszNewName.ToString(), null, default));
+ return HRESULT.S_OK;
+ }
+
+ [return: MarshalAs(UnmanagedType.Error)]
+ public HRESULT PostCopyItem(uint dwFlags, IShellItem psiItem, IShellItem psiDestinationFolder, PCWSTR pszNewName, HRESULT hrCopy, IShellItem psiNewlyCreated)
+ {
+ _operations.ItemCopied?.Invoke(_operations, new((_TRANSFER_SOURCE_FLAGS)dwFlags, WindowsStorable.TryParse(psiItem), new WindowsFolder(psiDestinationFolder), WindowsStorable.TryParse(psiNewlyCreated), pszNewName.ToString(), null, hrCopy));
+ return HRESULT.S_OK;
+ }
+
+ [return: MarshalAs(UnmanagedType.Error)]
+ public HRESULT PreDeleteItem(uint dwFlags, IShellItem psiItem)
+ {
+ _operations.ItemDeleting?.Invoke(_operations, new((_TRANSFER_SOURCE_FLAGS)dwFlags, WindowsStorable.TryParse(psiItem), null, null, null, null, default));
+ return HRESULT.S_OK;
+ }
+
+ [return: MarshalAs(UnmanagedType.Error)]
+ public HRESULT PostDeleteItem(uint dwFlags, IShellItem psiItem, HRESULT hrDelete, IShellItem psiNewlyCreated)
+ {
+ _operations.ItemDeleted?.Invoke(_operations, new((_TRANSFER_SOURCE_FLAGS)dwFlags, WindowsStorable.TryParse(psiItem), null, WindowsStorable.TryParse(psiNewlyCreated), null, null, hrDelete));
+ return HRESULT.S_OK;
+ }
+
+ [return: MarshalAs(UnmanagedType.Error)]
+ public HRESULT PreNewItem(uint dwFlags, IShellItem psiDestinationFolder, PCWSTR pszNewName)
+ {
+ _operations.ItemCreating?.Invoke(_operations, new((_TRANSFER_SOURCE_FLAGS)dwFlags, null, new WindowsFolder(psiDestinationFolder), null, pszNewName.ToString(), null, default));
+ return HRESULT.S_OK;
+ }
+
+ [return: MarshalAs(UnmanagedType.Error)]
+ public HRESULT PostNewItem(uint dwFlags, IShellItem psiDestinationFolder, PCWSTR pszNewName, PCWSTR pszTemplateName, uint dwFileAttributes, HRESULT hrNew, IShellItem psiNewItem)
+ {
+ _operations.ItemCreated?.Invoke(_operations, new((_TRANSFER_SOURCE_FLAGS)dwFlags, null, new WindowsFolder(psiDestinationFolder), WindowsStorable.TryParse(psiNewItem), pszNewName.ToString(), pszTemplateName.ToString(), hrNew));
+ return HRESULT.S_OK;
+ }
+
+ public HRESULT UpdateProgress(uint iWorkTotal, uint iWorkSoFar)
+ {
+ var percentage = iWorkTotal is 0 ? 0 : iWorkSoFar * 100.0 / iWorkTotal;
+ _operations.ProgressUpdated?.Invoke(_operations, new((int)percentage, null));
+ return HRESULT.S_OK;
+ }
+
+ }
+ }
+}
diff --git a/src/Files.App.Storage/Windows/WindowsFile.cs b/src/Files.App.Storage/Windows/WindowsFile.cs
index ef4b7d85d24b..1c4f71939176 100644
--- a/src/Files.App.Storage/Windows/WindowsFile.cs
+++ b/src/Files.App.Storage/Windows/WindowsFile.cs
@@ -9,9 +9,9 @@ namespace Files.App.Storage
[DebuggerDisplay("{" + nameof(ToString) + "()}")]
public unsafe class WindowsFile : WindowsStorable, IWindowsFile
{
- public WindowsFile(IShellItem* ptr)
+ public WindowsFile(IShellItem shellItem)
{
- ThisPtr = ptr;
+ ThisPtr = shellItem;
}
public Task OpenStreamAsync(FileAccess accessMode, CancellationToken cancellationToken = default)
diff --git a/src/Files.App.Storage/Windows/WindowsFolder.cs b/src/Files.App.Storage/Windows/WindowsFolder.cs
index 510300fa5f6d..14f754efe715 100644
--- a/src/Files.App.Storage/Windows/WindowsFolder.cs
+++ b/src/Files.App.Storage/Windows/WindowsFolder.cs
@@ -13,7 +13,7 @@ namespace Files.App.Storage
public unsafe class WindowsFolder : WindowsStorable, IWindowsFolder
{
///
- public IContextMenu* ShellNewMenu
+ public IContextMenu ShellNewMenu
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get;
@@ -22,50 +22,50 @@ public IContextMenu* ShellNewMenu
set;
}
- public WindowsFolder(IShellItem* ptr)
+ public WindowsFolder(IShellItem shellItem)
{
- ThisPtr = ptr;
+ ThisPtr = shellItem;
}
public WindowsFolder(Guid folderId)
{
- IShellItem* pShellItem = default;
-
- HRESULT hr = PInvoke.SHGetKnownFolderItem(&folderId, KNOWN_FOLDER_FLAG.KF_FLAG_DEFAULT, HANDLE.Null, IID.IID_IShellItem, (void**)&pShellItem);
+ HRESULT hr = PInvoke.SHGetKnownFolderItem(&folderId, KNOWN_FOLDER_FLAG.KF_FLAG_DEFAULT, HANDLE.Null, IID.IID_IShellItem, out var shellItemObj);
+ var shellItem = (IShellItem)shellItemObj;
if (hr.Failed)
{
- fixed (char* pszShellPath = $"Shell:::{folderId:B}")
- hr = PInvoke.SHCreateItemFromParsingName(pszShellPath, null, IID.IID_IShellItem, (void**)&pShellItem);
+ hr = PInvoke.SHCreateItemFromParsingName($"Shell:::{folderId:B}", null, typeof(IShellItem).GUID, out shellItemObj);
+ shellItem = (IShellItem)shellItemObj;
// Invalid FOLDERID; this should never happen.
hr.ThrowOnFailure();
}
- ThisPtr = pShellItem;
+ ThisPtr = shellItem;
}
public IAsyncEnumerable GetItemsAsync(StorableType type = StorableType.All, CancellationToken cancellationToken = default)
{
- using ComPtr pEnumShellItems = default;
-
- HRESULT hr = ThisPtr->BindToHandler(null, BHID.BHID_EnumItems, IID.IID_IEnumShellItems, (void**)pEnumShellItems.GetAddressOf());
+ HRESULT hr = ThisPtr.BindToHandler(null, BHID.BHID_EnumItems, IID.IID_IEnumShellItems, out var enumShellItemsObj);
+ var enumShellItems = (IEnumShellItems)enumShellItemsObj;
if (hr.ThrowIfFailedOnDebug().Failed)
return Enumerable.Empty().ToAsyncEnumerable();
List childItems = [];
- IShellItem* pChildShellItem = null;
- while ((hr = pEnumShellItems.Get()->Next(1, &pChildShellItem)) == HRESULT.S_OK)
+ var childItemArray = new IShellItem[1];
+ while ((hr = enumShellItems.Next(1, childItemArray)) == HRESULT.S_OK)
{
- bool isFolder = pChildShellItem->GetAttributes(SFGAO_FLAGS.SFGAO_FOLDER, out var dwAttributes).Succeeded && dwAttributes is SFGAO_FLAGS.SFGAO_FOLDER;
+ IShellItem childItem = childItemArray[0];
+
+ bool isFolder = childItem.GetAttributes(SFGAO_FLAGS.SFGAO_FOLDER, out var dwAttributes).Succeeded && dwAttributes is SFGAO_FLAGS.SFGAO_FOLDER;
if (type.HasFlag(StorableType.File) && !isFolder)
{
- childItems.Add(new WindowsFile(pChildShellItem));
+ childItems.Add(new WindowsFile(childItem));
}
else if (type.HasFlag(StorableType.Folder) && isFolder)
{
- childItems.Add(new WindowsFolder(pChildShellItem));
+ childItems.Add(new WindowsFolder(childItem));
}
}
@@ -74,12 +74,5 @@ public IAsyncEnumerable GetItemsAsync(StorableType type = Storab
return childItems.ToAsyncEnumerable();
}
-
- public override void Dispose()
- {
- base.Dispose();
-
- if (ShellNewMenu is not null) ShellNewMenu->Release();
- }
}
}
diff --git a/src/Files.App.Storage/Windows/WindowsStorable.cs b/src/Files.App.Storage/Windows/WindowsStorable.cs
index d7ed69cc2f31..016e0080e4bc 100644
--- a/src/Files.App.Storage/Windows/WindowsStorable.cs
+++ b/src/Files.App.Storage/Windows/WindowsStorable.cs
@@ -12,7 +12,7 @@ namespace Files.App.Storage
public unsafe abstract class WindowsStorable : IWindowsStorable
{
///
- public IShellItem* ThisPtr
+ public IShellItem ThisPtr
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get;
@@ -22,7 +22,7 @@ public IShellItem* ThisPtr
}
///
- public IContextMenu* ContextMenu
+ public IContextMenu ContextMenu
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get;
@@ -37,25 +37,21 @@ public IContextMenu* ContextMenu
///
public string Name => this.GetDisplayName(SIGDN.SIGDN_PARENTRELATIVEFORUI);
- public static WindowsStorable? TryParse(string szPath)
+ public static WindowsStorable? TryParse(string parseablePath)
{
- HRESULT hr = default;
- IShellItem* pShellItem = null;
-
- fixed (char* pszPath = szPath)
- hr = PInvoke.SHCreateItemFromParsingName(pszPath, null, IID.IID_IShellItem, (void**)&pShellItem);
-
- if (pShellItem is null)
+ HRESULT hr = PInvoke.SHCreateItemFromParsingName(parseablePath, null, typeof(IShellItem).GUID, out var shellItemObj);
+ var shellItem = (IShellItem)shellItemObj;
+ if (shellItem is null)
return null;
- return TryParse(pShellItem);
+ return TryParse(shellItem);
}
- public static WindowsStorable? TryParse(IShellItem* pShellItem)
+ public static WindowsStorable? TryParse(IShellItem shellItem)
{
- bool isFolder = pShellItem->GetAttributes(SFGAO_FLAGS.SFGAO_FOLDER, out var returnedAttributes).Succeeded && returnedAttributes is SFGAO_FLAGS.SFGAO_FOLDER;
+ bool isFolder = shellItem.GetAttributes(SFGAO_FLAGS.SFGAO_FOLDER, out var returnedAttributes).Succeeded && returnedAttributes is SFGAO_FLAGS.SFGAO_FOLDER;
- return isFolder ? new WindowsFolder(pShellItem) : new WindowsFile(pShellItem);
+ return isFolder ? new WindowsFolder(shellItem) : new WindowsFile(shellItem);
}
///
@@ -63,12 +59,11 @@ public IContextMenu* ContextMenu
{
cancellationToken.ThrowIfCancellationRequested();
- IShellItem* pParentFolder = default;
- HRESULT hr = ThisPtr->GetParent(&pParentFolder);
+ HRESULT hr = ThisPtr.GetParent(out var parentFolder);
if (hr.ThrowIfFailedOnDebug().Failed)
return Task.FromResult(null);
- return Task.FromResult(new WindowsFolder(pParentFolder));
+ return Task.FromResult(new WindowsFolder(parentFolder));
}
///
@@ -86,8 +81,6 @@ public override int GetHashCode()
///
public virtual void Dispose()
{
- if (ThisPtr is not null) ThisPtr->Release();
- if (ContextMenu is not null) ContextMenu->Release();
}
///
@@ -102,7 +95,7 @@ public unsafe bool Equals(IWindowsStorable? other)
if (other is null)
return false;
- return ThisPtr->Compare(other.ThisPtr, (uint)_SICHINTF.SICHINT_DISPLAY, out int order).Succeeded && order is 0;
+ return ThisPtr.Compare(other.ThisPtr, (uint)_SICHINTF.SICHINT_DISPLAY, out int order).Succeeded && order is 0;
}
public static bool operator ==(WindowsStorable left, WindowsStorable right)
diff --git a/src/Files.App/Data/Items/WidgetRecentItem.cs b/src/Files.App/Data/Items/WidgetRecentItem.cs
index ec26009caefb..80de5db469ee 100644
--- a/src/Files.App/Data/Items/WidgetRecentItem.cs
+++ b/src/Files.App/Data/Items/WidgetRecentItem.cs
@@ -10,7 +10,7 @@ namespace Files.App.Data.Items
///
/// Represents an item for recent item of File Explorer on Windows.
///
- public sealed partial class RecentItem : WidgetCardItem, IEquatable, IDisposable
+ public sealed partial class RecentItem : WidgetCardItem, IEquatable
{
private BitmapImage? _Icon;
///
@@ -38,7 +38,7 @@ public BitmapImage? Icon
///
/// This has to be removed in the future.
///
- public unsafe required ComPtr ShellItem { get; init; }
+ public required IShellItem ShellItem { get; init; }
///
/// Loads thumbnail icon of the recent item.
@@ -56,10 +56,5 @@ public async Task LoadRecentItemIconAsync()
public override int GetHashCode() => (Path, Name).GetHashCode();
public override bool Equals(object? other) => other is RecentItem item && Equals(item);
public bool Equals(RecentItem? other) => other is not null && other.Name == Name && other.Path == Path;
-
- public unsafe void Dispose()
- {
- ShellItem.Dispose();
- }
}
}
diff --git a/src/Files.App/Data/Items/WindowEx.cs b/src/Files.App/Data/Items/WindowEx.cs
index b00cb0565279..627a47f35dad 100644
--- a/src/Files.App/Data/Items/WindowEx.cs
+++ b/src/Files.App/Data/Items/WindowEx.cs
@@ -20,8 +20,8 @@ namespace Files.App.Data.Items
public unsafe partial class WindowEx : Window, IDisposable
{
private bool _isInitialized;
- private readonly WNDPROC _oldWndProc;
- private readonly WNDPROC _newWndProc;
+ private readonly WndProcDelegate _oldWndProc;
+ private readonly WndProcDelegate _newWndProc;
private readonly ApplicationDataContainer _applicationDataContainer = ApplicationData.Current.LocalSettings;
@@ -88,7 +88,7 @@ public unsafe WindowEx(int minWidth = 400, int minHeight = 300)
_newWndProc = new(NewWindowProc);
var pNewWndProc = Marshal.GetFunctionPointerForDelegate(_newWndProc);
var pOldWndProc = PInvoke.SetWindowLongPtr(new(WindowHandle), WINDOW_LONG_PTR_INDEX.GWL_WNDPROC, pNewWndProc);
- _oldWndProc = Marshal.GetDelegateForFunctionPointer(pOldWndProc);
+ _oldWndProc = Marshal.GetDelegateForFunctionPointer(pOldWndProc);
Closed += WindowEx_Closed;
}
@@ -223,7 +223,7 @@ private unsafe List> GetAllMonitorInfo()
{
List> monitors = [];
- MONITORENUMPROC monitorEnumProc = new((HMONITOR monitor, HDC deviceContext, RECT* rect, LPARAM data) =>
+ MonitorEnumProcDelegate monitorEnumProc = new((HMONITOR monitor, HDC deviceContext, RECT* rect, LPARAM data) =>
{
MONITORINFOEXW info = default;
info.monitorInfo.cbSize = (uint)Marshal.SizeOf();
diff --git a/src/Files.App/Extensions/ActionManager.cs b/src/Files.App/Extensions/ActionManager.cs
index 8928718ef6c9..6e77ae392afa 100644
--- a/src/Files.App/Extensions/ActionManager.cs
+++ b/src/Files.App/Extensions/ActionManager.cs
@@ -38,10 +38,10 @@ private ActionManager()
Guid classId = Guid.Parse(ActionRuntimeClsidStr);
Guid iid = IActionRuntimeIID;
- HRESULT hresult = PInvoke.CoCreateInstance(&classId, null, CLSCTX.CLSCTX_LOCAL_SERVER, &iid, (void**)&abiPtr);
+ HRESULT hresult = PInvoke.CoCreateInstance(&classId, null, CLSCTX.CLSCTX_LOCAL_SERVER, &iid, out var actionRuntimeObj);
Marshal.ThrowExceptionForHR((int)hresult);
- return MarshalInterface.FromAbi(abiPtr);
+ return (ActionRuntime)actionRuntimeObj;
}
catch
{
diff --git a/src/Files.App/Services/Storage/StorageTrashBinService.cs b/src/Files.App/Services/Storage/StorageTrashBinService.cs
index f2feafa3620f..253bf388ea32 100644
--- a/src/Files.App/Services/Storage/StorageTrashBinService.cs
+++ b/src/Files.App/Services/Storage/StorageTrashBinService.cs
@@ -101,38 +101,39 @@ public async Task RestoreAllTrashesAsync()
private unsafe bool RestoreAllTrashesInternal()
{
// Get IShellItem for Recycle Bin folder
- using ComPtr pRecycleBinFolderShellItem = default;
- HRESULT hr = PInvoke.SHGetKnownFolderItem(FOLDERID.FOLDERID_RecycleBinFolder, KNOWN_FOLDER_FLAG.KF_FLAG_DEFAULT, HANDLE.Null, IID.IID_IShellItem, (void**)pRecycleBinFolderShellItem.GetAddressOf());
+ HRESULT hr = PInvoke.SHGetKnownFolderItem(FOLDERID.FOLDERID_RecycleBinFolder, KNOWN_FOLDER_FLAG.KF_FLAG_DEFAULT, hToken: HANDLE.Null, IID.IID_IShellItem, out var recycleBinFolderObj);
+ var recycleBinFolder = (IShellItem)recycleBinFolderObj;
// Get IEnumShellItems for Recycle Bin folder
- using ComPtr pEnumShellItems = default;
- hr = pRecycleBinFolderShellItem.Get()->BindToHandler(null, BHID.BHID_EnumItems, IID.IID_IEnumShellItems, (void**)pEnumShellItems.GetAddressOf());
+ hr = recycleBinFolder.BindToHandler(null, BHID.BHID_EnumItems, IID.IID_IEnumShellItems, out var enumShellItemsObj);
+ var enumShellItems = (IEnumShellItems)enumShellItemsObj;
// Initialize how to perform the operation
- using ComPtr pFileOperation = default;
- hr = PInvoke.CoCreateInstance(CLSID.CLSID_FileOperation, null, CLSCTX.CLSCTX_LOCAL_SERVER, IID.IID_IFileOperation, (void**)pFileOperation.GetAddressOf());
- hr = pFileOperation.Get()->SetOperationFlags(FILEOPERATION_FLAGS.FOF_NO_UI);
- hr = pFileOperation.Get()->SetOwnerWindow(new(MainWindow.Instance.WindowHandle));
+ hr = PInvoke.CoCreateInstance(CLSID.CLSID_FileOperation, null, CLSCTX.CLSCTX_LOCAL_SERVER, IID.IID_IFileOperation, out var fileOperationObj);
+ var fileOperation = (IFileOperation)fileOperationObj;
+ hr = fileOperation.SetOperationFlags(FILEOPERATION_FLAGS.FOF_NO_UI);
+ hr = fileOperation.SetOwnerWindow(new(MainWindow.Instance.WindowHandle));
- using ComPtr pShellItem = default;
- while (pEnumShellItems.Get()->Next(1, pShellItem.GetAddressOf()) == HRESULT.S_OK)
+ var childItemArray = new IShellItem[1];
+ while (enumShellItems.Next(1, childItemArray) == HRESULT.S_OK)
{
+ IShellItem childItem = childItemArray[0];
+
// Get the original path
- using ComPtr pShellItem2 = default;
- hr = pShellItem.Get()->QueryInterface(IID.IID_IShellItem2, (void**)pShellItem2.GetAddressOf());
+ IShellItem2 childItem2 = (IShellItem2)childItem;
hr = PInvoke.PSGetPropertyKeyFromName("System.Recycle.DeletedFrom", out var originalPathPropertyKey);
- hr = pShellItem2.Get()->GetString(originalPathPropertyKey, out var szOriginalPath);
+ hr = childItem2.GetString(originalPathPropertyKey, out var originalPath);
// Get IShellItem of the original path
- hr = PInvoke.SHCreateItemFromParsingName(szOriginalPath.ToString(), null, typeof(IShellItem).GUID, out var pOriginalPathShellItemPtr);
- var pOriginalPathShellItem = (IShellItem*)pOriginalPathShellItemPtr;
+ hr = PInvoke.SHCreateItemFromParsingName(originalPath.ToString(), null, typeof(IShellItem).GUID, out var originalPathItemObj);
+ var originalPathItem = (IShellItem)originalPathItemObj;
// Define the shell item to restore
- hr = pFileOperation.Get()->MoveItem(pShellItem.Get(), pOriginalPathShellItem, default(PCWSTR), null);
+ hr = fileOperation.MoveItem(childItem, originalPathItem, default, null);
}
// Perform
- hr = pFileOperation.Get()->PerformOperations();
+ hr = fileOperation.PerformOperations();
// Reset the icon
PInvoke.SHUpdateRecycleBinIcon();
diff --git a/src/Files.App/Services/Windows/WindowsDialogService.cs b/src/Files.App/Services/Windows/WindowsDialogService.cs
index 20612523bd0a..0004d1c60743 100644
--- a/src/Files.App/Services/Windows/WindowsDialogService.cs
+++ b/src/Files.App/Services/Windows/WindowsDialogService.cs
@@ -22,9 +22,9 @@ public unsafe bool Open_FileOpenDialog(nint hWnd, bool pickFoldersOnly, string[]
try
{
- using ComPtr pDialog = default;
- HRESULT hr = pDialog.CoCreateInstance(CLSID.CLSID_FileOpenDialog, null, CLSCTX.CLSCTX_INPROC_SERVER);
-
+ HRESULT hr = PInvoke.CoCreateInstance(CLSID.CLSID_FileOpenDialog, null, CLSCTX.CLSCTX_INPROC_SERVER, IID.IID_IFileOpenDialog, out var dialogObj);
+ var dialog = (IFileOpenDialog)dialogObj;
+
// Handle COM creation failure gracefully
if (hr.Failed)
{
@@ -48,40 +48,37 @@ public unsafe bool Open_FileOpenDialog(nint hWnd, bool pickFoldersOnly, string[]
}
// Set the file type using the extension list
- pDialog.Get()->SetFileTypes(extensions.ToArray());
+ dialog.SetFileTypes(extensions.ToArray());
}
// Get the default shell folder (My Computer)
- using ComPtr pDefaultFolderShellItem = default;
- fixed (char* pszDefaultFolderPath = Environment.GetFolderPath(defaultFolder))
+ hr = PInvoke.SHCreateItemFromParsingName(
+ Environment.GetFolderPath(defaultFolder),
+ null,
+ typeof(IShellItem).GUID,
+ out var defaultFolderShellItemObj);
+ var defaultFolderShellItem = (IShellItem)defaultFolderShellItemObj;
+
+ // Handle shell item creation failure gracefully
+ if (hr.Failed)
{
- hr = PInvoke.SHCreateItemFromParsingName(
- pszDefaultFolderPath,
- null,
- IID.IID_IShellItem,
- (void**)pDefaultFolderShellItem.GetAddressOf());
-
- // Handle shell item creation failure gracefully
- if (hr.Failed)
- {
- App.Logger.LogWarning("Failed to create shell item for default folder '{0}'. HRESULT: 0x{1:X8}. Dialog will open without default folder.", Environment.GetFolderPath(defaultFolder), hr.Value);
- // Continue without setting default folder rather than failing completely
- }
+ App.Logger.LogWarning("Failed to create shell item for default folder '{0}'. HRESULT: 0x{1:X8}. Dialog will open without default folder.", Environment.GetFolderPath(defaultFolder), hr.Value);
+ // Continue without setting default folder rather than failing completely
}
// Folder picker
if (pickFoldersOnly)
- pDialog.Get()->SetOptions(FILEOPENDIALOGOPTIONS.FOS_PICKFOLDERS);
+ dialog.SetOptions(FILEOPENDIALOGOPTIONS.FOS_PICKFOLDERS);
// Set the default folder to open in the dialog (only if creation succeeded)
- if (pDefaultFolderShellItem.Get() is not null)
+ if (defaultFolderShellItem is not null)
{
- pDialog.Get()->SetFolder(pDefaultFolderShellItem.Get());
- pDialog.Get()->SetDefaultFolder(pDefaultFolderShellItem.Get());
+ dialog.SetFolder(defaultFolderShellItem);
+ dialog.SetDefaultFolder(defaultFolderShellItem);
}
// Show the dialog
- hr = pDialog.Get()->Show(new HWND(hWnd));
+ hr = dialog.Show(new HWND(hWnd));
if (hr.Value == unchecked((int)0x800704C7)) // HRESULT_FROM_WIN32(ERROR_CANCELLED)
return false;
@@ -93,12 +90,11 @@ public unsafe bool Open_FileOpenDialog(nint hWnd, bool pickFoldersOnly, string[]
}
// Get the file that user chose
- using ComPtr pResultShellItem = default;
- pDialog.Get()->GetResult(pResultShellItem.GetAddressOf());
- if (pResultShellItem.Get() is null)
+ dialog.GetResult(out var resultShellItem);
+ if (resultShellItem is null)
throw new COMException("FileOpenDialog returned invalid shell item.");
- pResultShellItem.Get()->GetDisplayName(SIGDN.SIGDN_FILESYSPATH, out var lpFilePath);
- filePath = lpFilePath.ToString();
+ resultShellItem.GetDisplayName(SIGDN.SIGDN_FILESYSPATH, out var resultFilePath);
+ filePath = resultFilePath.ToString();
return true;
}
@@ -121,9 +117,9 @@ public unsafe bool Open_FileSaveDialog(nint hWnd, bool pickFoldersOnly, string[]
try
{
- using ComPtr pDialog = default;
- HRESULT hr = pDialog.CoCreateInstance(CLSID.CLSID_FileSaveDialog, null, CLSCTX.CLSCTX_INPROC_SERVER);
-
+ HRESULT hr = PInvoke.CoCreateInstance(CLSID.CLSID_FileSaveDialog, null, CLSCTX.CLSCTX_INPROC_SERVER, IID.IID_IFileSaveDialog, out var dialogObj);
+ var dialog = (IFileSaveDialog)dialogObj;
+
// Handle COM creation failure gracefully
if (hr.Failed)
{
@@ -147,40 +143,37 @@ public unsafe bool Open_FileSaveDialog(nint hWnd, bool pickFoldersOnly, string[]
}
// Set the file type using the extension list
- pDialog.Get()->SetFileTypes(extensions.ToArray());
+ dialog.SetFileTypes(extensions.ToArray());
}
// Get the default shell folder (My Computer)
- using ComPtr pDefaultFolderShellItem = default;
- fixed (char* pszDefaultFolderPath = Environment.GetFolderPath(defaultFolder))
+ hr = PInvoke.SHCreateItemFromParsingName(
+ Environment.GetFolderPath(defaultFolder),
+ null,
+ typeof(IShellItem).GUID,
+ out var defaultFolderShellItemObj);
+ var defaultFolderShellItem = (IShellItem)defaultFolderShellItemObj;
+
+ // Handle shell item creation failure gracefully
+ if (hr.Failed)
{
- hr = PInvoke.SHCreateItemFromParsingName(
- pszDefaultFolderPath,
- null,
- IID.IID_IShellItem,
- (void**)pDefaultFolderShellItem.GetAddressOf());
-
- // Handle shell item creation failure gracefully
- if (hr.Failed)
- {
- App.Logger.LogWarning("Failed to create shell item for default folder '{0}'. HRESULT: 0x{1:X8}. Dialog will open without default folder.", Environment.GetFolderPath(defaultFolder), hr.Value);
- // Continue without setting default folder rather than failing completely
- }
+ App.Logger.LogWarning("Failed to create shell item for default folder '{0}'. HRESULT: 0x{1:X8}. Dialog will open without default folder.", Environment.GetFolderPath(defaultFolder), hr.Value);
+ // Continue without setting default folder rather than failing completely
}
// Folder picker
if (pickFoldersOnly)
- pDialog.Get()->SetOptions(FILEOPENDIALOGOPTIONS.FOS_PICKFOLDERS);
+ dialog.SetOptions(FILEOPENDIALOGOPTIONS.FOS_PICKFOLDERS);
// Set the default folder to open in the dialog (only if creation succeeded)
- if (pDefaultFolderShellItem.Get() is not null)
+ if (defaultFolderShellItem is not null)
{
- pDialog.Get()->SetFolder(pDefaultFolderShellItem.Get());
- pDialog.Get()->SetDefaultFolder(pDefaultFolderShellItem.Get());
+ dialog.SetFolder(defaultFolderShellItem);
+ dialog.SetDefaultFolder(defaultFolderShellItem);
}
// Show the dialog
- hr = pDialog.Get()->Show(new HWND(hWnd));
+ hr = dialog.Show(new HWND(hWnd));
if (hr.Value == unchecked((int)0x800704C7)) // HRESULT_FROM_WIN32(ERROR_CANCELLED)
return false;
@@ -192,12 +185,11 @@ public unsafe bool Open_FileSaveDialog(nint hWnd, bool pickFoldersOnly, string[]
}
// Get the file that user chose
- using ComPtr pResultShellItem = default;
- pDialog.Get()->GetResult(pResultShellItem.GetAddressOf());
- if (pResultShellItem.Get() is null)
+ dialog.GetResult(out var resultShellItem);
+ if (resultShellItem is null)
throw new COMException("FileSaveDialog returned invalid shell item.");
- pResultShellItem.Get()->GetDisplayName(SIGDN.SIGDN_FILESYSPATH, out var lpFilePath);
- filePath = lpFilePath.ToString();
+ resultShellItem.GetDisplayName(SIGDN.SIGDN_FILESYSPATH, out var resultFilePath);
+ filePath = resultFilePath.ToString();
return true;
}
diff --git a/src/Files.App/Services/Windows/WindowsRecentItemsService.cs b/src/Files.App/Services/Windows/WindowsRecentItemsService.cs
index 7668078bd408..55b86a0ea968 100644
--- a/src/Files.App/Services/Windows/WindowsRecentItemsService.cs
+++ b/src/Files.App/Services/Windows/WindowsRecentItemsService.cs
@@ -121,10 +121,10 @@ public unsafe bool Remove(RecentItem item)
{
try
{
- using ComPtr pContextMenu = default;
- HRESULT hr = item.ShellItem.Get()->BindToHandler(null, BHID.BHID_SFUIObject, IID.IID_IContextMenu, (void**)pContextMenu.GetAddressOf());
+ HRESULT hr = item.ShellItem.BindToHandler(null, BHID.BHID_SFUIObject, IID.IID_IContextMenu, out var contextMenuObj);
+ var contextMenu = (IContextMenu)contextMenuObj;
HMENU hMenu = PInvoke.CreatePopupMenu();
- hr = pContextMenu.Get()->QueryContextMenu(hMenu, 0, 1, 0x7FFF, PInvoke.CMF_OPTIMIZEFORINVOKE);
+ hr = contextMenu.QueryContextMenu(hMenu, 0, 1, 0x7FFF, PInvoke.CMF_OPTIMIZEFORINVOKE);
// Initialize invocation info
CMINVOKECOMMANDINFO cmi = default;
@@ -132,19 +132,19 @@ public unsafe bool Remove(RecentItem item)
cmi.nShow = (int)SHOW_WINDOW_CMD.SW_HIDE;
// Unpin the item
- fixed (byte* pVerb1 = Encoding.ASCII.GetBytes("remove"),
- pVerb2 = Encoding.ASCII.GetBytes("unpinfromhome"),
- pVerb3 = Encoding.ASCII.GetBytes("removefromhome"))
+ fixed (byte* verb1 = Encoding.ASCII.GetBytes("remove"),
+ verb2 = Encoding.ASCII.GetBytes("unpinfromhome"),
+ verb3 = Encoding.ASCII.GetBytes("removefromhome"))
{
// Try unpin files
- cmi.lpVerb = new(pVerb1);
- hr = pContextMenu.Get()->InvokeCommand(cmi);
+ cmi.lpVerb = new(verb1);
+ hr = contextMenu.InvokeCommand(cmi);
if (hr == HRESULT.S_OK)
return true;
// Try unpin folders
- cmi.lpVerb = new(pVerb2);
- hr = pContextMenu.Get()->InvokeCommand(cmi);
+ cmi.lpVerb = new(verb2);
+ hr = contextMenu.InvokeCommand(cmi);
if (hr == HRESULT.S_OK)
return true;
@@ -152,8 +152,8 @@ public unsafe bool Remove(RecentItem item)
// There seems to be an issue with unpinfromhome where some shell folders
// won't be removed via unpinfromhome verb.
// Try unpin folders again
- cmi.lpVerb = new(pVerb3);
- hr = pContextMenu.Get()->InvokeCommand(cmi);
+ cmi.lpVerb = new(verb3);
+ hr = contextMenu.InvokeCommand(cmi);
if (hr == HRESULT.S_OK)
return true;
}
@@ -189,44 +189,45 @@ private unsafe bool UpdateRecentItems(bool isFolder)
{
HRESULT hr = default;
- string szFolderShellPath =
+ string folderShellPath =
isFolder
? "Shell:::{22877A6D-37A1-461A-91B0-DBDA5AAEBC99}" // Recent Places folder (recent folders)
: "Shell:::{679F85CB-0220-4080-B29B-5540CC05AAB6}"; // Quick Access folder (recent files)
// Get IShellItem of the shell folder
- using ComPtr pFolderShellItem = default;
- fixed (char* pszFolderShellPath = szFolderShellPath)
- hr = PInvoke.SHCreateItemFromParsingName(pszFolderShellPath, null, IID.IID_IShellItem, (void**)pFolderShellItem.GetAddressOf());
+ hr = PInvoke.SHCreateItemFromParsingName(folderShellPath, null, typeof(IShellItem).GUID, out var folderShellItemObj);
+ var folderShellItem = (IShellItem)folderShellItemObj;
// Get IEnumShellItems of the quick access shell folder
- using ComPtr pEnumShellItems = default;
- hr = pFolderShellItem.Get()->BindToHandler(null, BHID.BHID_EnumItems, IID.IID_IEnumShellItems, (void**)pEnumShellItems.GetAddressOf());
+ hr = folderShellItem.BindToHandler(null, BHID.BHID_EnumItems, IID.IID_IEnumShellItems, out var enumShellItemsObj);
+ var enumShellItems = (IEnumShellItems)enumShellItemsObj;
// Enumerate recent items and populate the list
int index = 0;
List recentItems = [];
- ComPtr pShellItem = default; // Do not dispose in this method to use later to prepare for its deletion
- while (pEnumShellItems.Get()->Next(1, pShellItem.GetAddressOf()) == HRESULT.S_OK)
+ var shellItemArray = new IShellItem[1];
+ while (enumShellItems.Next(1, shellItemArray) == HRESULT.S_OK)
{
+ var shellItem = shellItemArray[0];
+
// Get top 20 items
if (index is 20)
break;
// Exclude folders
- if (pShellItem.Get()->GetAttributes(SFGAO_FLAGS.SFGAO_FOLDER, out var attribute) == HRESULT.S_OK &&
+ if (shellItem.GetAttributes(SFGAO_FLAGS.SFGAO_FOLDER, out var attribute) == HRESULT.S_OK &&
(attribute & SFGAO_FLAGS.SFGAO_FOLDER) == SFGAO_FLAGS.SFGAO_FOLDER)
continue;
// Get the target path
- pShellItem.Get()->GetDisplayName(SIGDN.SIGDN_DESKTOPABSOLUTEEDITING, out var szDisplayName);
- var targetPath = szDisplayName.ToString();
- PInvoke.CoTaskMemFree(szDisplayName.Value);
+ shellItem.GetDisplayName(SIGDN.SIGDN_DESKTOPABSOLUTEEDITING, out var displayName);
+ var targetPath = displayName.ToString();
+ PInvoke.CoTaskMemFree(displayName.Value);
// Get the display name
- pShellItem.Get()->GetDisplayName(SIGDN.SIGDN_NORMALDISPLAY, out szDisplayName);
- var fileName = szDisplayName.ToString();
- PInvoke.CoTaskMemFree(szDisplayName.Value);
+ shellItem.GetDisplayName(SIGDN.SIGDN_NORMALDISPLAY, out displayName);
+ var fileName = displayName.ToString();
+ PInvoke.CoTaskMemFree(displayName.Value);
// Strip the file extension except when the file name only contains extension (e.g. ".gitignore")
if (!FoldersSettingsService.ShowFileExtensions &&
@@ -234,18 +235,17 @@ private unsafe bool UpdateRecentItems(bool isFolder)
fileName = string.IsNullOrEmpty(fileNameWithoutExtension) ? SystemIO.Path.GetFileName(fileName) : fileNameWithoutExtension;
// Get the date last modified
- using ComPtr pShellItem2 = default;
- hr = pShellItem.Get()->QueryInterface(IID.IID_IShellItem2, (void**)pShellItem2.GetAddressOf());
+ var shellItem2 = (IShellItem2)shellItem;
hr = PInvoke.PSGetPropertyKeyFromName("System.DateModified", out var propertyKey);
- hr = pShellItem2.Get()->GetString(propertyKey, out var szPropertyValue);
- if (DateTime.TryParse(szPropertyValue.ToString(), out var lastModified))
+ hr = shellItem2.GetString(propertyKey, out var propertyValue);
+ if (DateTime.TryParse(propertyValue.ToString(), out var lastModified))
lastModified = DateTime.MinValue;
recentItems.Add(new()
{
Path = targetPath,
Name = fileName,
- ShellItem = pShellItem,
+ ShellItem = shellItem,
LastModified = lastModified,
});
diff --git a/src/Files.App/Services/Windows/WindowsWallpaperService.cs b/src/Files.App/Services/Windows/WindowsWallpaperService.cs
index be2f18069759..4c196d689a9a 100644
--- a/src/Files.App/Services/Windows/WindowsWallpaperService.cs
+++ b/src/Files.App/Services/Windows/WindowsWallpaperService.cs
@@ -14,62 +14,61 @@ namespace Files.App.Services
public sealed class WindowsWallpaperService : IWindowsWallpaperService
{
///
- public unsafe void SetDesktopWallpaper(string szPath)
+ public unsafe void SetDesktopWallpaper(string path)
{
// Instantiate IDesktopWallpaper
- using ComPtr pDesktopWallpaper = default;
- HRESULT hr = pDesktopWallpaper.CoCreateInstance(CLSID.CLSID_DesktopWallpaper);
+ HRESULT hr = PInvoke.CoCreateInstance(CLSID.CLSID_DesktopWallpaper, null, Windows.Win32.System.Com.CLSCTX.CLSCTX_ALL, IID.IID_IDesktopWallpaper, out var desktopWallpaperObj);
+ var desktopWallpaper = (IDesktopWallpaper)desktopWallpaperObj;
// Get total count of all available monitors
- hr = pDesktopWallpaper.Get()->GetMonitorDevicePathCount(out var dwMonitorCount);
+ hr = desktopWallpaper.GetMonitorDevicePathCount(out var monitorCount);
- fixed (char* pszPath = szPath)
+ fixed (char* pathPtr = path)
{
- PWSTR pMonitorId = default;
+ PWSTR monitorId = default;
// Set the selected image file as wallpaper for all available monitors
- for (uint dwIndex = 0u; dwIndex < dwMonitorCount; dwIndex++)
+ for (uint index = 0u; index < monitorCount; index++)
{
// Set the wallpaper
- hr = pDesktopWallpaper.Get()->GetMonitorDevicePathAt(dwIndex, &pMonitorId);
- hr = pDesktopWallpaper.Get()->SetWallpaper(pMonitorId, pszPath);
+ hr = desktopWallpaper.GetMonitorDevicePathAt(index, &monitorId);
+ hr = desktopWallpaper.SetWallpaper(monitorId, pathPtr);
- pMonitorId = default;
+ monitorId = default;
}
}
}
///
- public unsafe void SetDesktopSlideshow(string[] aszPaths)
+ public unsafe void SetDesktopSlideshow(string[] paths)
{
// Instantiate IDesktopWallpaper
- using ComPtr pDesktopWallpaper = default;
- HRESULT hr = pDesktopWallpaper.CoCreateInstance(CLSID.CLSID_DesktopWallpaper);
+ HRESULT hr = PInvoke.CoCreateInstance(CLSID.CLSID_DesktopWallpaper, null, Windows.Win32.System.Com.CLSCTX.CLSCTX_ALL, IID.IID_IDesktopWallpaper, out var desktopWallpaperObj);
+ var desktopWallpaper = (IDesktopWallpaper)desktopWallpaperObj;
- uint dwCount = (uint)aszPaths.Length;
- ITEMIDLIST** ppItemIdList = stackalloc ITEMIDLIST*[aszPaths.Length];
+ uint count = (uint)paths.Length;
+ ITEMIDLIST** itemIdList = stackalloc ITEMIDLIST*[paths.Length];
// Get an array of PIDL from the selected image files
- for (uint dwIndex = 0u; dwIndex < dwCount; dwIndex++)
- ppItemIdList[dwIndex] = PInvoke.ILCreateFromPath(aszPaths[dwIndex]);
+ for (uint index = 0u; index < count; index++)
+ itemIdList[index] = PInvoke.ILCreateFromPath(paths[index]);
// Get an IShellItemArray from the array of the PIDL
- using ComPtr pShellItemArray = default;
- hr = PInvoke.SHCreateShellItemArrayFromIDLists(dwCount, ppItemIdList, pShellItemArray.GetAddressOf());
+ hr = PInvoke.SHCreateShellItemArrayFromIDLists(count, itemIdList, out var shellItemArray);
// Release the allocated PIDL
- for (uint dwIndex = 0u; dwIndex < dwCount; dwIndex++)
- PInvoke.CoTaskMemFree((void*)ppItemIdList[dwIndex]);
+ for (uint index = 0u; index < count; index++)
+ PInvoke.CoTaskMemFree((void*)itemIdList[index]);
// Set the slideshow and its position
- hr = pDesktopWallpaper.Get()->SetSlideshow(pShellItemArray.Get());
- hr = pDesktopWallpaper.Get()->SetPosition(DESKTOP_WALLPAPER_POSITION.DWPOS_FILL);
+ hr = desktopWallpaper.SetSlideshow(shellItemArray);
+ hr = desktopWallpaper.SetPosition(DESKTOP_WALLPAPER_POSITION.DWPOS_FILL);
}
///
- public async Task SetLockScreenWallpaper(string szPath)
+ public async Task SetLockScreenWallpaper(string path)
{
- IStorageFile sourceFile = await StorageFile.GetFileFromPathAsync(szPath);
+ IStorageFile sourceFile = await StorageFile.GetFileFromPathAsync(path);
await LockScreen.SetImageFileAsync(sourceFile);
}
}
diff --git a/src/Files.App/Utils/Shell/LaunchHelper.cs b/src/Files.App/Utils/Shell/LaunchHelper.cs
index 634b326a2f4c..6edbc346e0e9 100644
--- a/src/Files.App/Utils/Shell/LaunchHelper.cs
+++ b/src/Files.App/Utils/Shell/LaunchHelper.cs
@@ -18,10 +18,10 @@ public static class LaunchHelper
{
public unsafe static void LaunchSettings(string page)
{
- using ComPtr pApplicationActivationManager = default;
- pApplicationActivationManager.CoCreateInstance(CLSID.CLSID_ApplicationActivationManager);
+ Windows.Win32.Foundation.HRESULT hr = PInvoke.CoCreateInstance(CLSID.CLSID_ApplicationActivationManager, null, Windows.Win32.System.Com.CLSCTX.CLSCTX_ALL, IID.IID_IApplicationActivationManager, out var pApplicationActivationManagerObj);
+ var pApplicationActivationManager = (IApplicationActivationManager)pApplicationActivationManagerObj;
- pApplicationActivationManager.Get()->ActivateApplication(
+ pApplicationActivationManager.ActivateApplication(
"windows.immersivecontrolpanel_cw5n1h2txyewy!microsoft.windows.immersivecontrolpanel",
page,
ACTIVATEOPTIONS.AO_NONE,
diff --git a/src/Files.App/Utils/Storage/Helpers/SyncRootHelpers.cs b/src/Files.App/Utils/Storage/Helpers/SyncRootHelpers.cs
index 042fb8564e1a..62e9646983b3 100644
--- a/src/Files.App/Utils/Storage/Helpers/SyncRootHelpers.cs
+++ b/src/Files.App/Utils/Storage/Helpers/SyncRootHelpers.cs
@@ -5,45 +5,35 @@
using Windows.Win32;
using Windows.Win32.System.Com;
using Windows.Win32.System.WinRT;
-using WinRT;
namespace Files.App.Utils.Storage
{
internal static class SyncRootHelpers
{
- private static unsafe (bool Success, ulong Capacity, ulong Used) GetSyncRootQuotaFromSyncRootId(string syncRootId)
+ private static (bool Success, ulong Capacity, ulong Used) GetSyncRootQuotaFromSyncRootId(string syncRootId)
{
using var key = Registry.LocalMachine.OpenSubKey($"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\SyncRootManager\\{syncRootId}");
if (key?.GetValue("StorageProviderStatusUISourceFactory") is not string factoryClsidString ||
!Guid.TryParse(factoryClsidString, out var factoryClsid))
return (false, 0, 0);
- ulong ulTotalSize = 0ul, ulUsedSize = 0ul;
- using ComPtr pStorageProviderStatusUISourceFactory = default;
- using ComPtr pStorageProviderStatusUISource = default;
- using ComPtr pStorageProviderStatusUI = default;
- using ComPtr pStorageProviderQuotaUI = default;
+ ulong totalSize = 0ul, usedSize = 0ul;
if (PInvoke.CoCreateInstance(
- &factoryClsid,
+ factoryClsid,
null,
CLSCTX.CLSCTX_LOCAL_SERVER,
- IID.IID_IStorageProviderStatusUISourceFactory,
- (void**)pStorageProviderStatusUISourceFactory.GetAddressOf()).ThrowIfFailedOnDebug().Failed)
+ out IStorageProviderStatusUISourceFactory statusUISourceFactory).ThrowIfFailedOnDebug().Failed)
return (false, 0, 0);
- var syncRootIdHString = new MarshalString.Pinnable(syncRootId);
- fixed (char* pSyncRootIdHString = syncRootIdHString)
- {
- if (pStorageProviderStatusUISourceFactory.Get()->GetStatusUISource(syncRootIdHString.GetAbi(), pStorageProviderStatusUISource.GetAddressOf()).ThrowIfFailedOnDebug().Failed ||
- pStorageProviderStatusUISource.Get()->GetStatusUI(pStorageProviderStatusUI.GetAddressOf()).ThrowIfFailedOnDebug().Failed ||
- pStorageProviderStatusUI.Get()->GetQuotaUI(pStorageProviderQuotaUI.GetAddressOf()).ThrowIfFailedOnDebug().Failed ||
- pStorageProviderQuotaUI.Get()->GetQuotaTotalInBytes(&ulTotalSize).ThrowIfFailedOnDebug().Failed ||
- pStorageProviderQuotaUI.Get()->GetQuotaUsedInBytes(&ulUsedSize).ThrowIfFailedOnDebug().Failed)
- return (false, 0, 0);
- }
+ if (statusUISourceFactory.GetStatusUISource(syncRootId, out var statusUISource).ThrowIfFailedOnDebug().Failed ||
+ statusUISource.GetStatusUI(out var statusUI).ThrowIfFailedOnDebug().Failed ||
+ statusUI.get_QuotaUI(out var quotaUI).ThrowIfFailedOnDebug().Failed ||
+ quotaUI.get_QuotaTotalInBytes(out totalSize).ThrowIfFailedOnDebug().Failed ||
+ quotaUI.get_QuotaUsedInBytes(out usedSize).ThrowIfFailedOnDebug().Failed)
+ return (false, 0, 0);
- return (true, ulTotalSize, ulUsedSize);
+ return (true, totalSize, usedSize);
}
public static async Task<(bool Success, ulong Capacity, ulong Used)> GetSyncRootQuotaAsync(string path)
diff --git a/src/Files.App/Utils/Taskbar/SystemTrayIconWindow.cs b/src/Files.App/Utils/Taskbar/SystemTrayIconWindow.cs
index 532ed33baf5f..0caec4cf75a4 100644
--- a/src/Files.App/Utils/Taskbar/SystemTrayIconWindow.cs
+++ b/src/Files.App/Utils/Taskbar/SystemTrayIconWindow.cs
@@ -17,7 +17,7 @@ public sealed partial class SystemTrayIconWindow : IDisposable
{
private SystemTrayIcon _trayIcon;
- private readonly WNDPROC _windowProcedure;
+ private readonly WndProcDelegate _windowProcedure;
private HWND _windowHandle;
internal HWND WindowHandle
diff --git a/src/Files.App/ViewModels/UserControls/Previews/ShellPreviewViewModel.cs b/src/Files.App/ViewModels/UserControls/Previews/ShellPreviewViewModel.cs
index 5c550e0d1c80..9c97bcb104c2 100644
--- a/src/Files.App/ViewModels/UserControls/Previews/ShellPreviewViewModel.cs
+++ b/src/Files.App/ViewModels/UserControls/Previews/ShellPreviewViewModel.cs
@@ -31,7 +31,7 @@ public sealed partial class ShellPreviewViewModel : BasePreviewModel
ContentExternalOutputLink? _contentExternalOutputLink;
PreviewHandler? _previewHandler;
WNDCLASSEXW _windowClass;
- WNDPROC _windProc = null!;
+ WndProcDelegate _windProc = null!;
HWND _hWnd = HWND.Null;
bool _isOfficePreview = false;
@@ -186,13 +186,10 @@ private unsafe bool ChildWindowToXaml(nint parent, UIElement presenter)
];
HRESULT hr = default;
- Guid IID_IDCompositionDevice = typeof(IDCompositionDevice).GUID;
- using ComPtr pD3D11Device = default;
- using ComPtr pD3D11DeviceContext = default;
- using ComPtr pDXGIDevice = default;
- using ComPtr pDCompositionDevice = default;
- using ComPtr pControlSurface = default;
- ComPtr pChildVisual = default; // Don't dispose this one, it's used by the compositor
+ ID3D11Device d3d11Device = null;
+ ID3D11DeviceContext d3d11DeviceContext = null;
+ IDCompositionVisual childVisual = null; // Don't dispose this one, it's used by the compositor
+ object controlSurface = null;
// Create the D3D11 device
foreach (var driverType in driverTypes)
@@ -201,30 +198,31 @@ private unsafe bool ChildWindowToXaml(nint parent, UIElement presenter)
null, driverType, new(nint.Zero),
D3D11_CREATE_DEVICE_FLAG.D3D11_CREATE_DEVICE_BGRA_SUPPORT,
null, /* FeatureLevels */ 0, /* SDKVersion */ 7,
- pD3D11Device.GetAddressOf(), null,
- pD3D11DeviceContext.GetAddressOf());
+ out d3d11Device, null,
+ out d3d11DeviceContext);
if (hr.Succeeded)
break;
}
- if (pD3D11Device.IsNull)
+ if (d3d11Device is null)
return false;
// Create the DComp device
- pDXGIDevice.Attach((IDXGIDevice*)pD3D11Device.Get());
+ Guid IID_IDCompositionDevice = typeof(IDCompositionDevice).GUID;
hr = PInvoke.DCompositionCreateDevice(
- pDXGIDevice.Get(),
- &IID_IDCompositionDevice,
- (void**)pDCompositionDevice.GetAddressOf());
+ (IDXGIDevice)d3d11Device,
+ in IID_IDCompositionDevice,
+ out var compositionDeviceObj);
+ var compositionDevice = (IDCompositionDevice)compositionDeviceObj;
if (hr.Failed)
return false;
// Create the visual
- hr = pDCompositionDevice.Get()->CreateVisual(pChildVisual.GetAddressOf());
- hr = pDCompositionDevice.Get()->CreateSurfaceFromHwnd(_hWnd, pControlSurface.GetAddressOf());
- hr = pChildVisual.Get()->SetContent(pControlSurface.Get());
- if (pChildVisual.IsNull || pControlSurface.IsNull)
+ hr = compositionDevice.CreateVisual(out childVisual);
+ hr = compositionDevice.CreateSurfaceFromHwnd(_hWnd, out controlSurface);
+ hr = childVisual.SetContent(controlSurface);
+ if (childVisual is null || controlSurface is null)
return false;
// Get the compositor and set the visual on it
@@ -232,14 +230,14 @@ private unsafe bool ChildWindowToXaml(nint parent, UIElement presenter)
_contentExternalOutputLink = ContentExternalOutputLink.Create(compositor);
var target = _contentExternalOutputLink.As();
- target.SetRoot((nint)pChildVisual.Get());
+ target.SetRoot(Marshal.GetIUnknownForObject(childVisual));
_contentExternalOutputLink.PlacementVisual.Size = new(0, 0);
_contentExternalOutputLink.PlacementVisual.Scale = new(1 / (float)presenter.XamlRoot.RasterizationScale);
ElementCompositionPreview.SetElementChildVisual(presenter, _contentExternalOutputLink.PlacementVisual);
// Commit the all pending DComp commands
- pDCompositionDevice.Get()->Commit();
+ compositionDevice.Commit();
var dwAttrib = Convert.ToUInt32(true);
diff --git a/src/Files.App/ViewModels/UserControls/Widgets/QuickAccessWidgetViewModel.cs b/src/Files.App/ViewModels/UserControls/Widgets/QuickAccessWidgetViewModel.cs
index 34978feb89f1..35a09d8fc31e 100644
--- a/src/Files.App/ViewModels/UserControls/Widgets/QuickAccessWidgetViewModel.cs
+++ b/src/Files.App/ViewModels/UserControls/Widgets/QuickAccessWidgetViewModel.cs
@@ -204,11 +204,11 @@ public override async Task ExecutePinToSidebarCommand(WidgetCardItem? item)
return;
HRESULT hr = default;
- using ComPtr pAgileReference = default;
+ IAgileReference agileReference;
unsafe
{
- hr = PInvoke.RoGetAgileReference(AgileReferenceOptions.AGILEREFERENCE_DEFAULT, IID.IID_IShellItem, (IUnknown*)folderCardItem.Item.ThisPtr, pAgileReference.GetAddressOf());
+ hr = PInvoke.RoGetAgileReference(AgileReferenceOptions.AGILEREFERENCE_DEFAULT, IID.IID_IShellItem, folderCardItem.Item.ThisPtr, out agileReference);
}
// Pin to Quick Access on Windows
@@ -216,9 +216,10 @@ public override async Task ExecutePinToSidebarCommand(WidgetCardItem? item)
{
unsafe
{
- IShellItem* pShellItem = null;
- hr = pAgileReference.Get()->Resolve(IID.IID_IShellItem, (void**)&pShellItem);
- using var windowsFile = new WindowsFile(pShellItem);
+ hr = agileReference.Resolve(IID.IID_IShellItem, out var itemObj);
+ var item = (IShellItem)itemObj;
+ using var windowsFile = new WindowsFile(item);
+
// NOTE: "pintohome" is an undocumented verb, which calls an undocumented COM class, windows.storage.dll!CPinToFrequentExecute : public IExecuteCommand, ...
return windowsFile.TryInvokeContextMenuVerb("pintohome");
}
@@ -233,11 +234,11 @@ public override async Task ExecuteUnpinFromSidebarCommand(WidgetCardItem? item)
return;
HRESULT hr = default;
- using ComPtr pAgileReference = default;
+ IAgileReference agileReference;
unsafe
{
- hr = PInvoke.RoGetAgileReference(AgileReferenceOptions.AGILEREFERENCE_DEFAULT, IID.IID_IShellItem, (IUnknown*)folderCardItem.Item.ThisPtr, pAgileReference.GetAddressOf());
+ hr = PInvoke.RoGetAgileReference(AgileReferenceOptions.AGILEREFERENCE_DEFAULT, IID.IID_IShellItem, folderCardItem.Item.ThisPtr, out agileReference);
}
// Unpin from Quick Access on Windows
@@ -245,9 +246,9 @@ public override async Task ExecuteUnpinFromSidebarCommand(WidgetCardItem? item)
{
unsafe
{
- IShellItem* pShellItem = null;
- hr = pAgileReference.Get()->Resolve(IID.IID_IShellItem, (void**)&pShellItem);
- using var windowsFile = new WindowsFile(pShellItem);
+ hr = agileReference.Resolve(IID.IID_IShellItem, out var itemObj);
+ var item = (IShellItem)itemObj;
+ using var windowsFile = new WindowsFile(item);
// NOTE: "unpinfromhome" is an undocumented verb, which calls an undocumented COM class, windows.storage.dll!CRemoveFromFrequentPlacesExecute : public IExecuteCommand, ...
// NOTE: "remove" is for some shell folders where the "unpinfromhome" may not work
diff --git a/src/Files.App/ViewModels/UserControls/Widgets/RecentFilesWidgetViewModel.cs b/src/Files.App/ViewModels/UserControls/Widgets/RecentFilesWidgetViewModel.cs
index 4d7b7bc8e2d3..fa91fa94cc51 100644
--- a/src/Files.App/ViewModels/UserControls/Widgets/RecentFilesWidgetViewModel.cs
+++ b/src/Files.App/ViewModels/UserControls/Widgets/RecentFilesWidgetViewModel.cs
@@ -363,9 +363,6 @@ private void ExecuteOpenPropertiesCommand(RecentItem? item)
public void Dispose()
{
WindowsRecentItemsService.RecentFilesChanged -= Manager_RecentFilesChanged;
-
- foreach (var item in Items)
- item.Dispose();
}
}
}