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(); }