diff --git a/src/Files.App.CsWin32/NativeMethods.json b/src/Files.App.CsWin32/NativeMethods.json
index 40ae5356353c..1b33355d8286 100644
--- a/src/Files.App.CsWin32/NativeMethods.json
+++ b/src/Files.App.CsWin32/NativeMethods.json
@@ -1,5 +1,20 @@
{
"$schema": "https://aka.ms/CsWin32.schema.json",
"allowMarshaling": false,
- "public": true
+ "public": true,
+ "comInterop": {
+ "preserveSigMethods": [
+ "IEnumShellItems.Next",
+ "IInitializeWithFile.Initialize",
+ "IInitializeWithItem.Initialize",
+ "IInitializeWithStream.Initialize",
+ "IPreviewHandler.QueryFocus",
+ "IPreviewHandler.SetRect",
+ "IObjectWithSite.SetSite",
+ "IPreviewHandler.SetWindow",
+ "IPreviewHandlerVisuals.SetBackgroundColor",
+ "IPreviewHandlerVisuals.SetFont",
+ "IPreviewHandlerVisuals.SetTextColor",
+ ]
+ }
}
diff --git a/src/Files.App.CsWin32/NativeMethods.txt b/src/Files.App.CsWin32/NativeMethods.txt
index 84d10caa634d..18453c0c6898 100644
--- a/src/Files.App.CsWin32/NativeMethods.txt
+++ b/src/Files.App.CsWin32/NativeMethods.txt
@@ -135,3 +135,10 @@ GetModuleHandle
RegisterClassEx
CREATESTRUCTW
AssocQueryString
+IPreviewHandlerFrame
+IPreviewHandlerVisuals
+IObjectWithSite
+IInitializeWithStream
+IInitializeWithStreamNative
+IInitializeWithFile
+IInitializeWithItem
diff --git a/src/Files.App/Utils/Shell/PreviewHandler.cs b/src/Files.App/Utils/Shell/PreviewHandler.cs
index 06160b4c2a21..dec86f96bbf4 100644
--- a/src/Files.App/Utils/Shell/PreviewHandler.cs
+++ b/src/Files.App/Utils/Shell/PreviewHandler.cs
@@ -7,153 +7,52 @@
using Windows.Win32.Foundation;
using Windows.Win32.Graphics.Gdi;
using Windows.Win32.System.Com;
-using Windows.Win32.UI.WindowsAndMessaging;
+using Windows.Win32.System.Ole;
+using Windows.Win32.UI.Shell;
+using Windows.Win32.UI.Shell.PropertiesSystem;
namespace Files.App.Utils.Shell
{
///
/// Credits: https://github.com/GeeLaw/PreviewHost/
///
- public sealed class PreviewHandler : IDisposable
+ public unsafe sealed class PreviewHandler : IDisposable
{
// Fields
- private static readonly Guid IPreviewHandlerIid = Guid.ParseExact("8895b1c6-b41f-4c1c-a562-0d564250836f", "d");
-
- #region IPreviewHandlerFrame support
-
- [StructLayout(LayoutKind.Sequential)]
- public struct PreviewHandlerFrameInfo
- {
- public nint AcceleratorTableHandle;
- public uint AcceleratorEntryCount;
- }
-
- [ComImport, Guid("fec87aaf-35f9-447a-adb7-20234491401a"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
- public interface IPreviewHandlerFrame
- {
- [PreserveSig]
- HRESULT GetWindowContext(out PreviewHandlerFrameInfo pinfo);
- [PreserveSig]
- HRESULT TranslateAccelerator(ref MSG pmsg);
- }
-
- public sealed class PreviewHandlerFrame : IPreviewHandlerFrame, IDisposable
- {
- bool disposed;
- nint hwnd;
-
- public PreviewHandlerFrame(nint frame)
- {
- disposed = true;
- disposed = false;
- hwnd = frame;
- }
-
- public void Dispose()
- {
- disposed = true;
- }
-
- public HRESULT GetWindowContext(out PreviewHandlerFrameInfo pinfo)
- {
- pinfo.AcceleratorTableHandle = nint.Zero;
- pinfo.AcceleratorEntryCount = 0;
- if (disposed)
- return HRESULT.E_FAIL;
- return HRESULT.S_OK;
- }
-
- public HRESULT TranslateAccelerator(ref MSG pmsg)
- {
- if (disposed)
- return HRESULT.E_FAIL;
- return HRESULT.S_FALSE;
- }
- }
-
- #endregion IPreviewHandlerFrame support
-
- #region IPreviewHandler major interfaces
-
- [ComImport, Guid("8895b1c6-b41f-4c1c-a562-0d564250836f"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
- interface IPreviewHandler
- {
- [PreserveSig]
- HRESULT SetWindow(nint hwnd, ref RECT prc);
- [PreserveSig]
- HRESULT SetRect(ref RECT prc);
- [PreserveSig]
- HRESULT DoPreview();
- [PreserveSig]
- HRESULT Unload();
- [PreserveSig]
- HRESULT SetFocus();
- [PreserveSig]
- HRESULT QueryFocus(out nint phwnd);
- // TranslateAccelerator is not used here.
- }
-
- [ComImport, Guid("196bf9a5-b346-4ef0-aa1e-5dcdb76768b1"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
- interface IPreviewHandlerVisuals
- {
- [PreserveSig]
- HRESULT SetBackgroundColor(uint color);
- [PreserveSig]
- HRESULT SetFont(ref LOGFONTW plf);
- [PreserveSig]
- HRESULT SetTextColor(uint color);
- }
-
- static uint ColorRefFromColor(Color color)
- {
- return (((uint)color.B) << 16) | (((uint)color.G) << 8) | ((uint)color.R);
- }
-
- [ComImport, Guid("fc4801a3-2ba9-11cf-a229-00aa003d7352"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
- interface IObjectWithSite
- {
- [PreserveSig]
- HRESULT SetSite([In, MarshalAs(UnmanagedType.IUnknown)] object pUnkSite);
- // GetSite is not used.
- }
-
- #endregion IPreviewHandler major interfaces
-
- bool disposed;
- bool init;
+ IPreviewHandler* _pPreviewHandler;
+ IPreviewHandlerFrame* _pPreviewHandlerFrame;
+ IPreviewHandlerVisuals* _previewHandlerVisuals;
+ HWND _hWnd;
+ bool _disposed;
+ bool _initialized;
bool shown;
- PreviewHandlerFrame comSite;
- nint hwnd;
- IPreviewHandler previewHandler;
- IPreviewHandlerVisuals visuals;
- nint pPreviewHandler;
// Initializer
- public PreviewHandler(Guid clsid, nint frame)
+ public PreviewHandler(Guid clsid, HWND frame)
{
- disposed = true;
- init = false;
+ _disposed = true;
+ _initialized = false;
shown = false;
- comSite = new PreviewHandlerFrame(frame);
- hwnd = frame;
+ _hWnd = frame;
try
{
SetupHandler(clsid);
- disposed = false;
+ _disposed = false;
}
catch
{
- if (previewHandler != null)
- Marshal.ReleaseComObject(previewHandler);
- previewHandler = null;
- if (pPreviewHandler != nint.Zero)
- Marshal.Release(pPreviewHandler);
- pPreviewHandler = nint.Zero;
- comSite.Dispose();
- comSite = null;
+ if (_pPreviewHandler is not null)
+ _pPreviewHandler->Release();
+
+ if (_pPreviewHandlerFrame is not null)
+ _pPreviewHandlerFrame->Release();
+
+ _pPreviewHandler = null;
+ _pPreviewHandlerFrame = null;
+
throw;
}
}
@@ -162,24 +61,11 @@ public PreviewHandler(Guid clsid, nint frame)
unsafe void SetupHandler(Guid clsid)
{
- nint pph;
- var iid = IPreviewHandlerIid;
- var cannotCreate = "Cannot create class " + clsid.ToString() + " as IPreviewHandler.";
- var cannotCast = "Cannot cast class " + clsid.ToString() + " as IObjectWithSite.";
- var cannotSetSite = "Cannot set site to the preview handler object.";
-
- // Important: manually calling CoCreateInstance is necessary.
- // If we use Activator.CreateInstance(Type.GetTypeFromCLSID(...)),
- // CLR will allow in-process server, which defeats isolation and
- // creates strange bugs.
HRESULT hr = PInvoke.CoCreateInstance(
clsid,
null,
CLSCTX.CLSCTX_LOCAL_SERVER,
- ref iid,
- out void* previewHandlerPtr);
-
- object previewHandlerObject = *(IPreviewHandler*)previewHandlerPtr;
+ out _pPreviewHandler);
// See https://blogs.msdn.microsoft.com/adioltean/2005/06/24/when-cocreateinstance-returns-0x80080005-co_e_server_exec_failure/
// CO_E_SERVER_EXEC_FAILURE also tends to happen when debugging in Visual Studio.
@@ -187,67 +73,34 @@ unsafe void SetupHandler(Guid clsid)
// to use another thread with low mandatory label. We keep it simple by creating
// a same-integrity object.
//if (hr == HRESULT.CO_E_SERVER_EXEC_FAILURE)
- // hr = CoCreateInstance(ref clsid, nint.Zero, ClassContext.LocalServer, ref iid, out pph);
- if ((int)hr < 0)
- throw new COMException(cannotCreate, (int)hr);
-
- pPreviewHandler = new(previewHandlerPtr);
- previewHandler = (IPreviewHandler)previewHandlerObject;
- if (previewHandler == null)
- {
- Marshal.ReleaseComObject(previewHandlerObject);
- throw new COMException(cannotCreate);
- }
-
- var objectWithSite = previewHandlerObject as IObjectWithSite;
- if (objectWithSite == null)
- throw new COMException(cannotCast);
-
- hr = objectWithSite.SetSite(comSite);
- if ((int)hr < 0)
- throw new COMException(cannotSetSite, (int)hr);
-
- visuals = previewHandlerObject as IPreviewHandlerVisuals;
- }
+ // hr = CoCreateInstance(clsid, null, CLSCTX.CLSCTX_LOCAL_SERVER, typeof(IPreviewHandler).GUID, out var pph);
+ if (hr.Value < 0)
+ throw new COMException("Cannot create class " + clsid.ToString() + " as IPreviewHandler.", hr.Value);
+ else if (_pPreviewHandler is null)
+ throw new COMException("Cannot create class " + clsid.ToString() + " as IPreviewHandler.");
- #region Initialization interfaces
+ _pPreviewHandler->QueryInterface(typeof(IPreviewHandlerFrame).GUID, out var ppPreviewHandlerFrame);
+ if (ppPreviewHandlerFrame == null)
+ throw new COMException("Cannot cast class " + clsid.ToString() + " as IObjectWithSite.");
- [ComImport, Guid("b824b49d-22ac-4161-ac8a-9916e8fa3f7f"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
- interface IInitializeWithStream
- {
- [PreserveSig]
- HRESULT Initialize(IStream psi, STGM grfMode);
- }
-
- [ComImport, Guid("b824b49d-22ac-4161-ac8a-9916e8fa3f7f"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
- interface IInitializeWithStreamNative
- {
- [PreserveSig]
- HRESULT Initialize(nint psi, STGM grfMode);
- }
+ _pPreviewHandlerFrame = (IPreviewHandlerFrame*)ppPreviewHandlerFrame;
- static readonly Guid IInitializeWithStreamIid = Guid.ParseExact("b824b49d-22ac-4161-ac8a-9916e8fa3f7f", "d");
+ _pPreviewHandler->QueryInterface(typeof(IObjectWithSite).GUID, out var ppObjectWithSite);
+ if (ppObjectWithSite == null)
+ throw new COMException("Cannot cast class " + clsid.ToString() + " as IObjectWithSite.");
- [ComImport, Guid("b7d14566-0509-4cce-a71f-0a554233bd9b"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
- interface IInitializeWithFile
- {
- [PreserveSig]
- HRESULT Initialize([MarshalAs(UnmanagedType.LPWStr)] string pszFilePath, STGM grfMode);
- }
+ var pObjectWithSite = (IObjectWithSite*)ppObjectWithSite;
+ hr = pObjectWithSite->SetSite((IUnknown*)_pPreviewHandlerFrame);
+ if (hr.Value < 0)
+ throw new COMException("Cannot set site to the preview handler object.", hr.Value);
- static readonly Guid IInitializeWithFileIid = Guid.ParseExact("b7d14566-0509-4cce-a71f-0a554233bd9b", "d");
+ _pPreviewHandler->QueryInterface(typeof(IPreviewHandlerVisuals).GUID, out var ppPreviewHandlerVisuals);
+ if (ppObjectWithSite == null)
+ throw new COMException("Cannot cast class " + clsid.ToString() + " as IObjectWithSite.");
- [ComImport, Guid("7f73be3f-fb79-493c-a6c7-7ee14e245841"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
- interface IInitializeWithItem
- {
- [PreserveSig]
- HRESULT Initialize(nint psi, STGM grfMode);
+ _previewHandlerVisuals = (IPreviewHandlerVisuals*)ppPreviewHandlerVisuals;
}
- static readonly Guid IInitializeWithItemIid = Guid.ParseExact("7f73be3f-fb79-493c-a6c7-7ee14e245841", "d");
-
- #endregion
-
///
/// Tries to initialize the preview handler with an IStream.
///
@@ -261,17 +114,20 @@ public bool InitWithStream(IStream stream, STGM mode)
if (mode != STGM.STGM_READ && mode != STGM.STGM_READWRITE)
throw new ArgumentOutOfRangeException("mode", mode, "The argument mode must be Read or ReadWrite.");
- var iws = previewHandler as IInitializeWithStream;
- if (iws == null)
+ IInitializeWithStream* pInitializeWithStream = default;
+ _pPreviewHandlerFrame->QueryInterface(typeof(IInitializeWithStream).GUID, out void* ppInitializeWithStream);
+ if (ppInitializeWithStream is null)
return false;
- var hr = iws.Initialize(stream, mode);
+ pInitializeWithStream = (IInitializeWithStream*)ppInitializeWithStream;
+
+ HRESULT hr = pInitializeWithStream->Initialize(&stream, (uint)mode);
if (hr == HRESULT.E_NOTIMPL)
return false;
- if ((int)hr < 0)
+ else if ((int)hr < 0)
throw new COMException("IInitializeWithStream.Initialize failed.", (int)hr);
- init = true;
+ _initialized = true;
return true;
}
@@ -292,17 +148,20 @@ public bool InitWithStream(nint pStream, STGM mode)
if (mode != STGM.STGM_READ && mode != STGM.STGM_READWRITE)
throw new ArgumentOutOfRangeException("mode", mode, "The argument mode must be Read or ReadWrite.");
- var iws = previewHandler as IInitializeWithStreamNative;
- if (iws == null)
+ IInitializeWithStream* pInitializeWithStream = default;
+ _pPreviewHandlerFrame->QueryInterface(typeof(IInitializeWithStream).GUID, out void* ppInitializeWithStream);
+ if (ppInitializeWithStream is null)
return false;
- var hr = iws.Initialize(pStream, mode);
+ pInitializeWithStream = (IInitializeWithStream*)ppInitializeWithStream;
+
+ HRESULT hr = pInitializeWithStream->Initialize((IStream*)pStream, (uint)mode);
if (hr == HRESULT.E_NOTIMPL)
return false;
- if ((int)hr < 0)
+ else if ((int)hr < 0)
throw new COMException("IInitializeWithStream.Initialize failed.", (int)hr);
- init = true;
+ _initialized = true;
return true;
}
@@ -323,17 +182,20 @@ public bool InitWithItem(nint psi, STGM mode)
if (mode != STGM.STGM_READ && mode != STGM.STGM_READWRITE)
throw new ArgumentOutOfRangeException("mode", mode, "The argument mode must be Read or ReadWrite.");
- var iwi = previewHandler as IInitializeWithItem;
- if (iwi == null)
+ IInitializeWithItem* pInitializeWithStream = default;
+ _pPreviewHandlerFrame->QueryInterface(typeof(IInitializeWithItem).GUID, out void* ppInitializeWithStream);
+ if (ppInitializeWithStream is null)
return false;
- var hr = iwi.Initialize(psi, mode);
+ pInitializeWithStream = (IInitializeWithItem*)ppInitializeWithStream;
+
+ HRESULT hr = pInitializeWithStream->Initialize((IShellItem*)psi, (uint)mode);
if (hr == HRESULT.E_NOTIMPL)
return false;
- if ((int)hr < 0)
- throw new COMException("IInitializeWithItem.Initialize failed.", (int)hr);
+ else if ((int)hr < 0)
+ throw new COMException("IInitializeWithStream.Initialize failed.", (int)hr);
- init = true;
+ _initialized = true;
return true;
}
@@ -354,17 +216,20 @@ public bool InitWithFile(string path, STGM mode)
if (mode != STGM.STGM_READ && mode != STGM.STGM_READWRITE)
throw new ArgumentOutOfRangeException("mode", mode, "The argument mode must be Read or ReadWrite.");
- var iwf = previewHandler as IInitializeWithFile;
- if (iwf == null)
+ IInitializeWithFile* pInitializeWithStream = default;
+ _pPreviewHandlerFrame->QueryInterface(typeof(IInitializeWithFile).GUID, out void* ppInitializeWithStream);
+ if (ppInitializeWithStream is null)
return false;
- var hr = iwf.Initialize(path, mode);
+ pInitializeWithStream = (IInitializeWithFile*)ppInitializeWithStream;
+
+ HRESULT hr = pInitializeWithStream->Initialize(path, (uint)mode);
if (hr == HRESULT.E_NOTIMPL)
return false;
- if ((int)hr < 0)
- throw new COMException("IInitializeWithFile.Initialize failed.", (int)hr);
+ else if ((int)hr < 0)
+ throw new COMException("IInitializeWithStream.Initialize failed.", (int)hr);
- init = true;
+ _initialized = true;
return true;
}
@@ -377,19 +242,16 @@ public bool InitWithFile(string path, STGM mode)
public bool InitWithFileWithEveryWay(string path)
{
var exceptions = new List();
- var pobj = nint.Zero;
-
- // Why should we try IStream first?
- // Because that gives us the best security.
- // If we initialize with string or IShellItem,
- // we have no control over how the preview handler
- // opens the file, which might decide to open the
- // file for read/write exclusively.
+ var pObject = nint.Zero;
+
+ // We try IStream first so that this gives us the best security.
+ // If we initialize with string or IShellItem, we have no control over how the preview handler
+ // opens the file, which might decide to open the file for read/write exclusively.
try
{
- pobj = ItemStreamHelper.IStreamFromPath(path);
- if (pobj != nint.Zero
- && InitWithStream(pobj, STGM.STGM_READ))
+ pObject = ItemStreamHelper.IStreamFromPath(path);
+ if (pObject != nint.Zero
+ && InitWithStream(pObject, STGM.STGM_READ))
return true;
}
catch (Exception ex)
@@ -398,10 +260,10 @@ public bool InitWithFileWithEveryWay(string path)
}
finally
{
- if (pobj != nint.Zero)
- ItemStreamHelper.ReleaseObject(pobj);
+ if (pObject != nint.Zero)
+ ItemStreamHelper.ReleaseObject(pObject);
- pobj = nint.Zero;
+ pObject = nint.Zero;
}
// Next try file because that could save us some P/Invokes.
@@ -417,9 +279,9 @@ public bool InitWithFileWithEveryWay(string path)
try
{
- pobj = ItemStreamHelper.IShellItemFromPath(path);
- if (pobj != nint.Zero
- && InitWithItem(pobj, STGM.STGM_READ))
+ pObject = ItemStreamHelper.IShellItemFromPath(path);
+ if (pObject != nint.Zero
+ && InitWithItem(pObject, STGM.STGM_READ))
return true;
if (exceptions.Count == 0)
@@ -431,10 +293,10 @@ public bool InitWithFileWithEveryWay(string path)
}
finally
{
- if (pobj != nint.Zero)
- ItemStreamHelper.ReleaseObject(pobj);
+ if (pObject != nint.Zero)
+ ItemStreamHelper.ReleaseObject(pObject);
- pobj = nint.Zero;
+ pObject = nint.Zero;
}
throw new AggregateException(exceptions);
@@ -446,14 +308,13 @@ public bool InitWithFileWithEveryWay(string path)
public bool ResetWindow()
{
EnsureNotDisposed();
-
//EnsureInitialized();
- if (!init)
+ if (!_initialized)
return false;
- var hr = previewHandler.SetWindow(hwnd, new());
- return (int)hr >= 0;
+ HRESULT hr = _pPreviewHandler->SetWindow(_hWnd, new RECT());
+ return hr.Value >= 0;
}
///
@@ -465,10 +326,10 @@ public bool ResetBounds(RECT previewerBounds)
//EnsureInitialized();
- if (!init)
+ if (!_initialized)
return false;
- var hr = previewHandler.SetRect(previewerBounds);
+ HRESULT hr = _pPreviewHandler->SetRect(previewerBounds);
return (int)hr >= 0;
}
@@ -479,8 +340,8 @@ public bool ResetBounds(RECT previewerBounds)
/// Whether the call succeeds.
public bool SetBackground(Color color)
{
- var hr = visuals?.SetBackgroundColor(ColorRefFromColor(color));
- return hr.HasValue && (int)hr.Value >= 0;
+ HRESULT hr = _previewHandlerVisuals->SetBackgroundColor(new(ColorRefFromColor(color)));
+ return hr.Value >= 0;
}
///
@@ -490,8 +351,8 @@ public bool SetBackground(Color color)
/// Whether the call succeeds.
public bool SetForeground(Color color)
{
- var hr = visuals?.SetTextColor(ColorRefFromColor(color));
- return hr.HasValue && (int)hr.Value >= 0;
+ HRESULT hr = _previewHandlerVisuals->SetTextColor(new(ColorRefFromColor(color)));
+ return hr.Value >= 0;
}
///
@@ -501,8 +362,8 @@ public bool SetForeground(Color color)
/// Whether the call succeeds.
public bool SetFont(ref LOGFONTW font)
{
- var hr = visuals?.SetFont(ref font);
- return hr.HasValue && (int)hr.Value >= 0;
+ HRESULT hr = _previewHandlerVisuals->SetFont(font);
+ return hr.Value >= 0;
}
///
@@ -511,17 +372,16 @@ public bool SetFont(ref LOGFONTW font)
public void DoPreview()
{
EnsureNotDisposed();
-
//EnsureInitialized();
- if (!init)
+ if (!_initialized)
return;
EnsureNotShown();
ResetWindow();
- previewHandler.DoPreview();
+ _pPreviewHandler->DoPreview();
shown = true;
}
@@ -535,11 +395,12 @@ public void Focus()
//EnsureInitialized();
- if (!init)
+ if (!_initialized)
return;
EnsureShown();
- previewHandler.SetFocus();
+
+ _pPreviewHandler->SetFocus();
}
///
@@ -552,18 +413,18 @@ public nint QueryFocus()
//EnsureInitialized();
- if (!init)
+ if (!_initialized)
return nint.Zero;
EnsureShown();
nint result;
- var hr = previewHandler.QueryFocus(out result);
- if ((int)hr < 0)
+ HRESULT hr = _pPreviewHandler->QueryFocus(out HWND hWnd);
+ if (hr.Value < 0)
return nint.Zero;
- return result;
+ return hWnd.Value;
}
///
@@ -574,62 +435,72 @@ public void UnloadPreview()
Dispose(true);
}
- void EnsureNotDisposed()
+ private void EnsureNotDisposed()
{
- if (disposed)
+ if (_disposed)
throw new ObjectDisposedException("PreviewHandler");
}
- void EnsureInitialized()
+ private void EnsureInitialized()
{
- if (!init)
+ if (!_initialized)
throw new InvalidOperationException("Object must be initialized before calling this method.");
}
- void EnsureNotInitialized()
+ private void EnsureNotInitialized()
{
- if (init)
+ if (_initialized)
throw new InvalidOperationException("Object is already initialized and cannot be initialized again.");
}
- void EnsureShown()
+ private void EnsureShown()
{
if (!shown)
throw new InvalidOperationException("The preview handler must be shown to call this method.");
}
- void EnsureNotShown()
+ private void EnsureNotShown()
{
if (shown)
throw new InvalidOperationException("The preview handler must not be shown to call this method.");
}
- // Dispose
+ private uint ColorRefFromColor(Color color)
+ {
+ return (((uint)color.B) << 16) | (((uint)color.G) << 8) | ((uint)color.R);
+ }
+
+ // Disposers
void Dispose(bool disposing)
{
- if (disposed)
+ if (_disposed)
return;
- disposed = true;
- init = false;
+
+ _disposed = true;
+ _initialized = false;
+
if (disposing)
{
- previewHandler.Unload();
- comSite.Dispose();
- Marshal.ReleaseComObject(previewHandler);
+ _pPreviewHandler->Unload();
+ _pPreviewHandlerFrame->Release();
+ _pPreviewHandler->Release();
}
else
{
// We're in the finalizer.
// Field previewHandler might have been finalized at this point.
// Get a new RCW.
- var phObject = Marshal.GetUniqueObjectForIUnknown(pPreviewHandler);
- var ph = phObject as IPreviewHandler;
- if (ph != null)
- ph.Unload();
- Marshal.ReleaseComObject(phObject);
+
+ //var phObject = Marshal.GetUniqueObjectForIUnknown(_pPreviewHandler);
+ //var ph = phObject as IPreviewHandler;
+ //if (ph != null)
+ // ph.Unload();
+
+ //Marshal.ReleaseComObject(phObject);
}
- Marshal.Release(pPreviewHandler);
+
+ _pPreviewHandler->Release();
}
~PreviewHandler()
diff --git a/src/Files.App/ViewModels/UserControls/Previews/ShellPreviewViewModel.cs b/src/Files.App/ViewModels/UserControls/Previews/ShellPreviewViewModel.cs
index 3062e47e9669..5b9152879eea 100644
--- a/src/Files.App/ViewModels/UserControls/Previews/ShellPreviewViewModel.cs
+++ b/src/Files.App/ViewModels/UserControls/Previews/ShellPreviewViewModel.cs
@@ -103,7 +103,7 @@ private unsafe LRESULT WndProc(HWND hwnd, uint msg, WPARAM wParam, LPARAM lParam
try
{
- _currentPreviewHandler = new PreviewHandler(clsid.Value, hwnd.Value);
+ _currentPreviewHandler = new PreviewHandler(clsid.Value, hwnd);
_currentPreviewHandler.InitWithFileWithEveryWay(Item.ItemPath);
_currentPreviewHandler.DoPreview();
}