diff --git a/src/modules/previewpane/MarkdownPreviewHandler/MarkdownPreviewHandler.cs b/src/modules/previewpane/MarkdownPreviewHandler/MarkdownPreviewHandler.cs
index 156e635f54..6e9504831b 100644
--- a/src/modules/previewpane/MarkdownPreviewHandler/MarkdownPreviewHandler.cs
+++ b/src/modules/previewpane/MarkdownPreviewHandler/MarkdownPreviewHandler.cs
@@ -20,6 +20,14 @@ namespace Microsoft.PowerToys.PreviewHandler.Markdown
private MarkdownPreviewHandlerControl _markdownPreviewHandlerControl;
private bool disposedValue;
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public MarkdownPreviewHandler()
+ {
+ Initialize();
+ }
+
///
public override void DoPreview()
{
diff --git a/src/modules/previewpane/SvgPreviewHandler/SvgPreviewControl.cs b/src/modules/previewpane/SvgPreviewHandler/SvgPreviewControl.cs
index 9a78ae7a98..21db1eda68 100644
--- a/src/modules/previewpane/SvgPreviewHandler/SvgPreviewControl.cs
+++ b/src/modules/previewpane/SvgPreviewHandler/SvgPreviewControl.cs
@@ -48,7 +48,7 @@ namespace Microsoft.PowerToys.PreviewHandler.Svg
{
_infoBarAdded = false;
string svgData = null;
- using (var stream = new StreamWrapper(dataSource as IStream))
+ using (var stream = new ReadonlyStream(dataSource as IStream))
{
using (var reader = new StreamReader(stream))
{
diff --git a/src/modules/previewpane/SvgPreviewHandler/SvgPreviewHandler.cs b/src/modules/previewpane/SvgPreviewHandler/SvgPreviewHandler.cs
index 08d6519d73..dbf0a340ad 100644
--- a/src/modules/previewpane/SvgPreviewHandler/SvgPreviewHandler.cs
+++ b/src/modules/previewpane/SvgPreviewHandler/SvgPreviewHandler.cs
@@ -20,6 +20,14 @@ namespace Microsoft.PowerToys.PreviewHandler.Svg
private SvgPreviewControl _svgPreviewControl;
private bool disposedValue;
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public SvgPreviewHandler()
+ {
+ Initialize();
+ }
+
///
public override void DoPreview()
{
diff --git a/src/modules/previewpane/SvgThumbnailProvider/SvgThumbnailProvider.cs b/src/modules/previewpane/SvgThumbnailProvider/SvgThumbnailProvider.cs
index 925091ae7b..52f52aa00c 100644
--- a/src/modules/previewpane/SvgThumbnailProvider/SvgThumbnailProvider.cs
+++ b/src/modules/previewpane/SvgThumbnailProvider/SvgThumbnailProvider.cs
@@ -225,7 +225,7 @@ namespace Microsoft.PowerToys.ThumbnailHandler.Svg
}
string svgData = null;
- using (var stream = new StreamWrapper(this.Stream as IStream))
+ using (var stream = new ReadonlyStream(this.Stream as IStream))
{
using (var reader = new StreamReader(stream))
{
diff --git a/src/modules/previewpane/UnitTests-PreviewHandlerCommon/FormHandlerControlTests.cs b/src/modules/previewpane/UnitTests-PreviewHandlerCommon/FormHandlerControlTests.cs
index e539d9e43b..5fbde64d1f 100644
--- a/src/modules/previewpane/UnitTests-PreviewHandlerCommon/FormHandlerControlTests.cs
+++ b/src/modules/previewpane/UnitTests-PreviewHandlerCommon/FormHandlerControlTests.cs
@@ -58,7 +58,7 @@ namespace UnitTests_PreviewHandlerCommon
using (var testFormHandlerControl = new TestFormControl())
{
// Act
- var handle = testFormHandlerControl.GetHandle();
+ var handle = testFormHandlerControl.Handle;
// Assert
Assert.AreEqual(testFormHandlerControl.Handle, handle);
diff --git a/src/modules/previewpane/UnitTests-PreviewHandlerCommon/PreviewHandlerBaseTests.cs b/src/modules/previewpane/UnitTests-PreviewHandlerCommon/PreviewHandlerBaseTests.cs
index 6dba4ffa19..b7105b13c5 100644
--- a/src/modules/previewpane/UnitTests-PreviewHandlerCommon/PreviewHandlerBaseTests.cs
+++ b/src/modules/previewpane/UnitTests-PreviewHandlerCommon/PreviewHandlerBaseTests.cs
@@ -19,6 +19,11 @@ namespace UnitTests_PreviewHandlerCommon
public class TestPreviewHandler : PreviewHandlerBase
{
+ public TestPreviewHandler()
+ {
+ Initialize();
+ }
+
public override void DoPreview()
{
throw new NotImplementedException();
@@ -291,7 +296,7 @@ namespace UnitTests_PreviewHandlerCommon
// Arrange
var previewControlHandle = new IntPtr(5);
var mockPreviewControl = new Mock();
- mockPreviewControl.Setup(x => x.GetHandle())
+ mockPreviewControl.Setup(x => x.GetWindowHandle())
.Returns(previewControlHandle);
previewHandlerControl = mockPreviewControl.Object;
diff --git a/src/modules/previewpane/UnitTests-PreviewHandlerCommon/StreamWrapperTests.cs b/src/modules/previewpane/UnitTests-PreviewHandlerCommon/StreamWrapperTests.cs
index db7d13deba..5b9395a7e0 100644
--- a/src/modules/previewpane/UnitTests-PreviewHandlerCommon/StreamWrapperTests.cs
+++ b/src/modules/previewpane/UnitTests-PreviewHandlerCommon/StreamWrapperTests.cs
@@ -26,7 +26,7 @@ namespace UnitTests_PreviewHandlerCommon
// Act
try
{
- var streamWrapper = new StreamWrapper(stream);
+ var streamWrapper = new ReadonlyStream(stream);
}
catch (ArgumentNullException ex)
{
@@ -44,7 +44,7 @@ namespace UnitTests_PreviewHandlerCommon
var streamMock = new Mock();
// Act
- var streamWrapper = new StreamWrapper(streamMock.Object);
+ var streamWrapper = new ReadonlyStream(streamMock.Object);
// Assert
Assert.AreEqual(streamWrapper.CanRead, true);
@@ -57,7 +57,7 @@ namespace UnitTests_PreviewHandlerCommon
var streamMock = new Mock();
// Act
- var streamWrapper = new StreamWrapper(streamMock.Object);
+ var streamWrapper = new ReadonlyStream(streamMock.Object);
// Assert
Assert.AreEqual(streamWrapper.CanSeek, true);
@@ -70,7 +70,7 @@ namespace UnitTests_PreviewHandlerCommon
var streamMock = new Mock();
// Act
- var streamWrapper = new StreamWrapper(streamMock.Object);
+ var streamWrapper = new ReadonlyStream(streamMock.Object);
// Assert
Assert.AreEqual(streamWrapper.CanWrite, false);
@@ -89,7 +89,7 @@ namespace UnitTests_PreviewHandlerCommon
stremMock
.Setup(x => x.Stat(out stat, It.IsAny()));
- var streamWrapper = new StreamWrapper(stremMock.Object);
+ var streamWrapper = new ReadonlyStream(stremMock.Object);
// Act
var actualLength = streamWrapper.Length;
@@ -113,7 +113,7 @@ namespace UnitTests_PreviewHandlerCommon
{
Marshal.WriteInt64(plibNewPosition, currPosition);
});
- var streamWrapper = new StreamWrapper(stremMock.Object);
+ var streamWrapper = new ReadonlyStream(stremMock.Object);
// Act
var actualPosition = streamWrapper.Position;
@@ -131,7 +131,7 @@ namespace UnitTests_PreviewHandlerCommon
int expectedDwOrigin = 0; // STREAM_SEEK_SET
var stremMock = new Mock();
- var streamWrapper = new StreamWrapper(stremMock.Object)
+ var streamWrapper = new ReadonlyStream(stremMock.Object)
{
// Act
Position = positionToSet,
@@ -168,7 +168,7 @@ namespace UnitTests_PreviewHandlerCommon
}
var stremMock = new Mock();
- var streamWrapper = new StreamWrapper(stremMock.Object);
+ var streamWrapper = new ReadonlyStream(stremMock.Object);
// Act
streamWrapper.Seek(offset, origin);
@@ -191,7 +191,7 @@ namespace UnitTests_PreviewHandlerCommon
Marshal.WriteInt64(plibNewPosition, position);
});
- var streamWrapper = new StreamWrapper(stremMock.Object);
+ var streamWrapper = new ReadonlyStream(stremMock.Object);
// Act
var actualPosition = streamWrapper.Seek(0, SeekOrigin.Begin);
@@ -212,7 +212,7 @@ namespace UnitTests_PreviewHandlerCommon
var stremMock = new Mock();
ArgumentOutOfRangeException exception = null;
- var streamWrapper = new StreamWrapper(stremMock.Object);
+ var streamWrapper = new ReadonlyStream(stremMock.Object);
// Act
try
@@ -252,7 +252,7 @@ namespace UnitTests_PreviewHandlerCommon
Marshal.WriteInt32(bytesReadPtr, count);
});
- var streamWrapper = new StreamWrapper(stremMock.Object);
+ var streamWrapper = new ReadonlyStream(stremMock.Object);
// Act
var bytesRead = streamWrapper.Read(inputBuffer, offset, count);
@@ -267,7 +267,7 @@ namespace UnitTests_PreviewHandlerCommon
{
// Arrange
var stremMock = new Mock();
- var streamWrapper = new StreamWrapper(stremMock.Object);
+ var streamWrapper = new ReadonlyStream(stremMock.Object);
NotImplementedException exception = null;
// Act
@@ -289,7 +289,7 @@ namespace UnitTests_PreviewHandlerCommon
{
// Arrange
var stremMock = new Mock();
- var streamWrapper = new StreamWrapper(stremMock.Object);
+ var streamWrapper = new ReadonlyStream(stremMock.Object);
NotImplementedException exception = null;
// Act
@@ -311,7 +311,7 @@ namespace UnitTests_PreviewHandlerCommon
{
// Arrange
var stremMock = new Mock();
- var streamWrapper = new StreamWrapper(stremMock.Object);
+ var streamWrapper = new ReadonlyStream(stremMock.Object);
NotImplementedException exception = null;
// Act
diff --git a/src/modules/previewpane/common/PreviewHandlerCommon.csproj b/src/modules/previewpane/common/PreviewHandlerCommon.csproj
index f8adb7a9a3..eae65aae56 100644
--- a/src/modules/previewpane/common/PreviewHandlerCommon.csproj
+++ b/src/modules/previewpane/common/PreviewHandlerCommon.csproj
@@ -110,6 +110,7 @@
+
@@ -129,7 +130,7 @@
-
+
@@ -137,6 +138,11 @@
+
+ 3.3.0
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
1.1.118
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/src/modules/previewpane/common/Utilities/StreamWrapper.cs b/src/modules/previewpane/common/Utilities/ReadonlyStream.cs
similarity index 83%
rename from src/modules/previewpane/common/Utilities/StreamWrapper.cs
rename to src/modules/previewpane/common/Utilities/ReadonlyStream.cs
index c1f8eb6acd..a9ae949181 100644
--- a/src/modules/previewpane/common/Utilities/StreamWrapper.cs
+++ b/src/modules/previewpane/common/Utilities/ReadonlyStream.cs
@@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
using System;
+using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
@@ -15,17 +16,17 @@ namespace Common.Utilities
///
/// Implements only read from the stream functionality.
///
- public class StreamWrapper : Stream
+ public class ReadonlyStream : Stream
{
- private IStream stream;
+ private IStream _stream;
///
- /// Initializes a new instance of the class.
+ /// Initializes a new instance of the class.
///
/// A pointer to an interface that represents the stream source.
- public StreamWrapper(IStream stream)
+ public ReadonlyStream(IStream stream)
{
- this.stream = stream ?? throw new ArgumentNullException(nameof(stream));
+ _stream = stream ?? throw new ArgumentNullException(nameof(stream));
}
///
@@ -68,11 +69,11 @@ namespace Common.Utilities
{
get
{
- this.CheckDisposed();
+ CheckDisposed();
System.Runtime.InteropServices.ComTypes.STATSTG stat;
// Stat called with STATFLAG_NONAME. The pwcsName is not required more details https://docs.microsoft.com/en-us/windows/win32/api/wtypes/ne-wtypes-statflag
- this.stream.Stat(out stat, 1); // STATFLAG_NONAME
+ _stream.Stat(out stat, 1); // STATFLAG_NONAME
return stat.cbSize;
}
@@ -85,12 +86,12 @@ namespace Common.Utilities
{
get
{
- return this.Seek(0, SeekOrigin.Current);
+ return Seek(0, SeekOrigin.Current);
}
set
{
- this.Seek(value, SeekOrigin.Begin);
+ Seek(value, SeekOrigin.Begin);
}
}
@@ -103,11 +104,16 @@ namespace Common.Utilities
/// The total number of bytes read into the buffer. This can be less than the number of bytes requested if that many bytes are not currently available, or zero if the end of the stream has been reached.
public override int Read(byte[] buffer, int offset, int count)
{
- this.CheckDisposed();
+ CheckDisposed();
- if (offset < 0 || count < 0 || offset + count > buffer.Length)
+ if (buffer == null)
{
- throw new ArgumentOutOfRangeException();
+ throw new NullReferenceException("buffer is null");
+ }
+
+ if (offset < 0 || count < 0 || (offset + count) > buffer.Length)
+ {
+ throw new ArgumentOutOfRangeException(nameof(buffer), "Out of range for buffer");
}
byte[] localBuffer = buffer;
@@ -121,7 +127,7 @@ namespace Common.Utilities
try
{
- this.stream.Read(localBuffer, count, bytesReadPtr);
+ _stream.Read(localBuffer, count, bytesReadPtr);
int bytesRead = Marshal.ReadInt32(bytesReadPtr);
if (offset > 0)
@@ -145,7 +151,7 @@ namespace Common.Utilities
/// The new position within the current stream.
public override long Seek(long offset, SeekOrigin origin)
{
- this.CheckDisposed();
+ CheckDisposed();
int dwOrigin;
// Maps the SeekOrigin with dworigin more details: https://docs.microsoft.com/en-us/windows/win32/api/objidl/ne-objidl-stream_seek
@@ -164,14 +170,14 @@ namespace Common.Utilities
break;
default:
- throw new ArgumentOutOfRangeException();
+ throw new ArgumentOutOfRangeException(nameof(origin));
}
IntPtr posPtr = Marshal.AllocCoTaskMem(sizeof(long));
try
{
- this.stream.Seek(offset, dwOrigin, posPtr);
+ _stream.Seek(offset, dwOrigin, posPtr);
return Marshal.ReadInt64(posPtr);
}
finally
@@ -220,22 +226,24 @@ namespace Common.Utilities
///
protected override void Dispose(bool disposing)
{
- if (this.stream != null)
+ base.Dispose(true);
+
+ if (_stream != null)
{
- if (Marshal.IsComObject(this.stream))
+ if (Marshal.IsComObject(_stream))
{
- Marshal.ReleaseComObject(this.stream);
+ Marshal.ReleaseComObject(_stream);
}
- this.stream = null;
+ _stream = null;
}
}
private void CheckDisposed()
{
- if (this.stream == null)
+ if (_stream == null)
{
- throw new ObjectDisposedException(nameof(StreamWrapper));
+ throw new ObjectDisposedException(nameof(ReadonlyStream));
}
}
}
diff --git a/src/modules/previewpane/common/cominterop/COLORREF.cs b/src/modules/previewpane/common/cominterop/COLORREF.cs
index 65d1216973..0edf457f0f 100644
--- a/src/modules/previewpane/common/cominterop/COLORREF.cs
+++ b/src/modules/previewpane/common/cominterop/COLORREF.cs
@@ -11,12 +11,13 @@ namespace Common.ComInterlop
/// The COLORREF value is used to specify an RGB color.
///
[StructLayout(LayoutKind.Sequential)]
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1815:Override equals and operator equals on value types", Justification = "Interop")]
public struct COLORREF
{
///
- /// Stores an RGB color value in a 32 bit integer.
+ /// Gets or sets stores an RGB color value in a 32 bit integer.
///
- public uint Dword;
+ public uint Dword { get; set; }
///
/// Gets RGB value stored in in structure.
@@ -26,9 +27,9 @@ namespace Common.ComInterlop
get
{
return Color.FromArgb(
- (int)(0x000000FFU & this.Dword),
- (int)(0x0000FF00U & this.Dword) >> 8,
- (int)(0x00FF0000U & this.Dword) >> 16);
+ (int)(0x000000FFU & Dword),
+ (int)(0x0000FF00U & Dword) >> 8,
+ (int)(0x00FF0000U & Dword) >> 16);
}
}
}
diff --git a/src/modules/previewpane/common/cominterop/IThumbnailProvider.cs b/src/modules/previewpane/common/cominterop/IThumbnailProvider.cs
index 758d231c51..78a6a866ff 100644
--- a/src/modules/previewpane/common/cominterop/IThumbnailProvider.cs
+++ b/src/modules/previewpane/common/cominterop/IThumbnailProvider.cs
@@ -10,10 +10,11 @@ namespace Common.ComInterlop
///
/// Specifies the alpha type of the image.
///
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1707:Identifiers should not contain underscores", Justification = "Interop")]
public enum WTS_ALPHATYPE : int
{
///
- /// he bitmap is an unknown format. The Shell tries nonetheless to detect whether the image has an alpha channel.
+ /// The bitmap is an unknown format. The Shell tries nonetheless to detect whether the image has an alpha channel.
///
WTSAT_UNKNOWN = 0,
diff --git a/src/modules/previewpane/common/cominterop/LOGFONT.cs b/src/modules/previewpane/common/cominterop/LOGFONT.cs
index e3b1e88d51..a20cedf11b 100644
--- a/src/modules/previewpane/common/cominterop/LOGFONT.cs
+++ b/src/modules/previewpane/common/cominterop/LOGFONT.cs
@@ -10,79 +10,86 @@ namespace Common.ComInterlop
/// Defines the attributes of a font.
///
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1815:Override equals and operator equals on value types", Justification = "Interop")]
public struct LOGFONT
{
///
- /// Value of type INT that specifies the height, in logical units, of the font's character cell or character.
+ /// Gets or sets value of type INT that specifies the height, in logical units, of the font's character cell or character.
///
- public int LfHeight;
+ public int LfHeight { get; set; }
///
- /// Value of type INT that specifies the width, in logical units, of characters in the font.
+ /// Gets or sets value of type INT that specifies the width, in logical units, of characters in the font.
///
- public int LfWidth;
+ public int LfWidth { get; set; }
///
- /// Value of type INT that contains the angle, in tenths of degrees, between the escapement vector and the x-axis of the device. The escapement
+ /// Gets or sets value of type INT that contains the angle, in tenths of degrees, between the escapement vector and the x-axis of the device. The escapement
/// vector is parallel to the base line of a row of text.
///
- public int LfEscapement;
+ public int LfEscapement { get; set; }
///
- /// Value of type INT that specifies the angle, in tenths of degrees, between each character's base line and the x-axis of the device.
+ /// Gets or sets value of type INT that specifies the angle, in tenths of degrees, between each character's base line and the x-axis of the device.
///
- public int LfOrientation;
+ public int LfOrientation { get; set; }
///
- /// Value of type INT that specifies the weight of the font in the range from 0 through 1000.
+ /// Gets or sets value of type INT that specifies the weight of the font in the range from 0 through 1000.
///
- public int LfWeight;
+ public int LfWeight { get; set; }
///
- /// Value of type BYTE that specifies an italic font if set to TRUE.
+ /// Gets or sets value of type BYTE that specifies an italic font if set to TRUE.
///
- public byte LfItalic;
+ public byte LfItalic { get; set; }
///
- /// Value of type BYTE that specifies an underlined font if set to TRUE.
+ /// Gets or sets value of type BYTE that specifies an underlined font if set to TRUE.
///
- public byte LfUnderline;
+ public byte LfUnderline { get; set; }
///
- /// Value of type BYTE that specifies a strikeout font if set to TRUE.
+ /// Gets or sets value of type BYTE that specifies a strikeout font if set to TRUE.
///
- public byte LfStrikeOut;
+ public byte LfStrikeOut { get; set; }
///
- /// Value of type BYTE that specifies the character set.
+ /// Gets or sets value of type BYTE that specifies the character set.
///
- public byte LfCharSet;
+ public byte LfCharSet { get; set; }
///
- /// Value of type BYTE that specifies the output precision. The output precision defines how closely the output must match the requested
+ /// Gets or sets value of type BYTE that specifies the output precision. The output precision defines how closely the output must match the requested
/// font's height, width, character orientation, escapement, pitch, and font type.
///
- public byte LfOutPrecision;
+ public byte LfOutPrecision { get; set; }
///
- /// Value of type BYTE that specifies the clipping precision. The clipping precision defines how to clip characters that are partially outside the clipping region.
+ /// Gets or sets value of type BYTE that specifies the clipping precision. The clipping precision defines how to clip characters that are partially outside the clipping region.
///
- public byte LfClipPrecision;
+ public byte LfClipPrecision { get; set; }
///
- /// Value of type BYTE that specifies the output quality. The output quality defines how carefully the GDI must attempt to match the logical-font attributes to those of an actual physical font.
+ /// Gets or sets value of type BYTE that specifies the output quality. The output quality defines how carefully the GDI must attempt to match the logical-font attributes to those of an actual physical font.
///
- public byte LfQuality;
+ public byte LfQuality { get; set; }
///
- /// Value of type BYTE that specifies the pitch and family of the font.
+ /// Gets or sets value of type BYTE that specifies the pitch and family of the font.
///
- public byte LfPitchAndFamily;
+ public byte LfPitchAndFamily { get; set; }
///
- /// Array of wide characters that contains a null-terminated string that specifies the typeface name of the font. The length of the string must not exceed 32 characters, including the NULL terminator.
+ /// Gets or sets array of wide characters that contains a null-terminated string that specifies the typeface name of the font. The length of the string must not exceed 32 characters, including the NULL terminator.
///
+ public string LfFaceName
+ {
+ get { return _lfFaceName; }
+ set { _lfFaceName = value; }
+ }
+
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
- public string LfFaceName;
+ private string _lfFaceName;
}
}
diff --git a/src/modules/previewpane/common/cominterop/MSG.cs b/src/modules/previewpane/common/cominterop/MSG.cs
index 58d5fedaa7..c1ec5ccca5 100644
--- a/src/modules/previewpane/common/cominterop/MSG.cs
+++ b/src/modules/previewpane/common/cominterop/MSG.cs
@@ -11,41 +11,42 @@ namespace Common.ComInterlop
/// Contains message information from a thread's message queue.
///
[StructLayout(LayoutKind.Sequential)]
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1815:Override equals and operator equals on value types", Justification = "Interop")]
public struct MSG
{
///
- /// A handle to the window whose window procedure receives the message. This member is NULL when the message is a thread message.
+ /// Gets or sets a handle to the window whose window procedure receives the message. This member is NULL when the message is a thread message.
///
- public IntPtr Hwnd;
+ public IntPtr Hwnd { get; set; }
///
- /// The message identifier. Applications can only use the low word; the high word is reserved by the system.
+ /// Gets or sets the message identifier. Applications can only use the low word; the high word is reserved by the system.
///
- public int Message;
+ public int Message { get; set; }
///
- /// Additional information about the message. The exact meaning depends on the value of the message member.
+ /// Gets or sets additional information about the message. The exact meaning depends on the value of the message member.
///
- public IntPtr WParam;
+ public IntPtr WParam { get; set; }
///
- /// Additional information about the message. The exact meaning depends on the value of the message member.
+ /// Gets or sets additional information about the message. The exact meaning depends on the value of the message member.
///
- public IntPtr LParam;
+ public IntPtr LParam { get; set; }
///
- /// The time at which the message was posted.
+ /// Gets or sets the time at which the message was posted.
///
- public int Time;
+ public int Time { get; set; }
///
- /// The x coordinate of cursor position, in screen coordinates, when the message was posted.
+ /// Gets or sets the x coordinate of cursor position, in screen coordinates, when the message was posted.
///
- public int PtX;
+ public int PtX { get; set; }
///
- /// The y coordinate of cursor position, in screen coordinates, when the message was posted.
+ /// Gets or sets the y coordinate of cursor position, in screen coordinates, when the message was posted.
///
- public int PtY;
+ public int PtY { get; set; }
}
}
diff --git a/src/modules/previewpane/common/cominterop/NativeMethods.cs b/src/modules/previewpane/common/cominterop/NativeMethods.cs
new file mode 100644
index 0000000000..2a23adaed3
--- /dev/null
+++ b/src/modules/previewpane/common/cominterop/NativeMethods.cs
@@ -0,0 +1,37 @@
+// Copyright (c) Microsoft Corporation
+// The Microsoft Corporation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace PreviewHandlerCommon.ComInterop
+{
+ ///
+ /// Interop methods
+ ///
+ internal class NativeMethods
+ {
+ ///
+ /// Changes the parent window of the specified child window.
+ ///
+ /// A handle to the child window.
+ /// A handle to the new parent window.
+ /// If the function succeeds, the return value is a handle to the previous parent window and NULL in case of failure.
+ [DllImport("user32.dll")]
+ public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
+
+ ///
+ /// Retrieves the handle to the window that has the keyboard focus, if the window is attached to the calling thread's message queue.
+ ///
+ /// The return value is the handle to the window with the keyboard focus. If the calling thread's message queue does not have an associated window with the keyboard focus, the return value is NULL.
+ [DllImport("user32.dll", CharSet = CharSet.Auto)]
+ public static extern IntPtr GetFocus();
+
+ [DllImport("user32.dll", SetLastError = true)]
+ public static extern int GetWindowLong(IntPtr hWnd, int nIndex);
+
+ [DllImport("user32.dll", SetLastError = true)]
+ public static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
+ }
+}
diff --git a/src/modules/previewpane/common/cominterop/RECT.cs b/src/modules/previewpane/common/cominterop/RECT.cs
index 2d47937c39..25eca98b09 100644
--- a/src/modules/previewpane/common/cominterop/RECT.cs
+++ b/src/modules/previewpane/common/cominterop/RECT.cs
@@ -11,27 +11,28 @@ namespace Common.ComInterlop
/// The RECT structure defines a rectangle by the coordinates of its upper-left and lower-right corners.
///
[StructLayout(LayoutKind.Sequential)]
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1815:Override equals and operator equals on value types", Justification = "Interop")]
public struct RECT
{
///
- /// Specifies the x-coordinate of the upper-left corner of the rectangle.
+ /// Gets or sets specifies the x-coordinate of the upper-left corner of the rectangle.
///
- public int Left;
+ public int Left { get; set; }
///
- /// Specifies the y-coordinate of the upper-left corner of the rectangle.
+ /// Gets or sets specifies the y-coordinate of the upper-left corner of the rectangle.
///
- public int Top;
+ public int Top { get; set; }
///
- /// Specifies the x-coordinate of the lower-right corner of the rectangle.
+ /// Gets or sets specifies the x-coordinate of the lower-right corner of the rectangle.
///
- public int Right;
+ public int Right { get; set; }
///
- /// Specifies the y-coordinate of the lower-right corner of the rectangle.
+ /// Gets or sets specifies the y-coordinate of the lower-right corner of the rectangle.
///
- public int Bottom;
+ public int Bottom { get; set; }
///
/// Creates a structure with the edge locations specified in the struct.
@@ -39,7 +40,7 @@ namespace Common.ComInterlop
/// Return a .
public Rectangle ToRectangle()
{
- return Rectangle.FromLTRB(this.Left, this.Top, this.Right, this.Bottom);
+ return Rectangle.FromLTRB(Left, Top, Right, Bottom);
}
}
}
diff --git a/src/modules/previewpane/common/controls/FormHandlerControl.cs b/src/modules/previewpane/common/controls/FormHandlerControl.cs
index 901b42dc3f..b3696044fc 100644
--- a/src/modules/previewpane/common/controls/FormHandlerControl.cs
+++ b/src/modules/previewpane/common/controls/FormHandlerControl.cs
@@ -6,6 +6,7 @@ using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
+using PreviewHandlerCommon.ComInterop;
namespace Common
{
@@ -34,12 +35,13 @@ namespace Common
// This is important, because the thread that instantiates the preview handler component and calls its constructor is a single-threaded apartment (STA) thread, but the thread that calls into the interface members later on is a multithreaded apartment (MTA) thread. Windows Forms controls are meant to run on STA threads.
// More details: https://docs.microsoft.com/en-us/archive/msdn-magazine/2007/january/windows-vista-and-office-writing-your-own-preview-handlers.
var forceCreation = this.Handle;
+
this.FormBorderStyle = FormBorderStyle.None;
this.Visible = false;
}
///
- public IntPtr GetHandle()
+ public IntPtr GetWindowHandle()
{
return this.Handle;
}
@@ -50,7 +52,7 @@ namespace Common
var getResult = IntPtr.Zero;
this.InvokeOnControlThread(() =>
{
- getResult = GetFocus();
+ getResult = NativeMethods.GetFocus();
});
result = getResult;
}
@@ -140,28 +142,6 @@ namespace Common
this.Invoke(func);
}
- ///
- /// Changes the parent window of the specified child window.
- ///
- /// A handle to the child window.
- /// A handle to the new parent window.
- /// If the function succeeds, the return value is a handle to the previous parent window and NULL in case of failure.
- [DllImport("user32.dll")]
- private static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
-
- ///
- /// Retrieves the handle to the window that has the keyboard focus, if the window is attached to the calling thread's message queue.
- ///
- /// The return value is the handle to the window with the keyboard focus. If the calling thread's message queue does not have an associated window with the keyboard focus, the return value is NULL.
- [DllImport("user32.dll", CharSet = CharSet.Auto)]
- private static extern IntPtr GetFocus();
-
- [DllImport("user32.dll", SetLastError = true)]
- private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
-
- [DllImport("user32.dll", SetLastError = true)]
- private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
-
///
/// Update the Form Control window with the passed rectangle.
///
@@ -171,14 +151,14 @@ namespace Common
this.InvokeOnControlThread(() =>
{
// We must set the WS_CHILD style to change the form to a control within the Explorer preview pane
- int windowStyle = GetWindowLong(this.Handle, gwlStyle);
+ int windowStyle = NativeMethods.GetWindowLong(Handle, gwlStyle);
if ((windowStyle & wsChild) == 0)
{
- SetWindowLong(this.Handle, gwlStyle, windowStyle | wsChild);
+ _ = NativeMethods.SetWindowLong(Handle, gwlStyle, windowStyle | wsChild);
}
- SetParent(this.Handle, this.parentHwnd);
- this.Bounds = windowBounds;
+ NativeMethods.SetParent(Handle, parentHwnd);
+ Bounds = windowBounds;
});
}
}
diff --git a/src/modules/previewpane/common/controls/IPreviewHandlerControl.cs b/src/modules/previewpane/common/controls/IPreviewHandlerControl.cs
index 20271da6da..eb91c28207 100644
--- a/src/modules/previewpane/common/controls/IPreviewHandlerControl.cs
+++ b/src/modules/previewpane/common/controls/IPreviewHandlerControl.cs
@@ -47,7 +47,7 @@ namespace Common
/// Gets the HWND of the control window.
///
/// Pointer to the window handle.
- IntPtr GetHandle();
+ IntPtr GetWindowHandle();
///
/// Hide the preview and free any resource used for the preview.
diff --git a/src/modules/previewpane/common/controls/WebBrowserDownloadControlFlags.cs b/src/modules/previewpane/common/controls/WebBrowserDownloadControlFlags.cs
index 6023950f8f..bf4743a0e9 100644
--- a/src/modules/previewpane/common/controls/WebBrowserDownloadControlFlags.cs
+++ b/src/modules/previewpane/common/controls/WebBrowserDownloadControlFlags.cs
@@ -9,6 +9,7 @@ using System;
/// Values of flags are defined in mshtmdid.h in distributed Windows Sdk.
///
[Flags]
+[System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1707:Identifiers should not contain underscores", Justification = "Interop, keeping stuff in sync")]
public enum WebBrowserDownloadControlFlags : int
{
///
diff --git a/src/modules/previewpane/common/controls/WebBrowserExt.cs b/src/modules/previewpane/common/controls/WebBrowserExt.cs
index c62eb6e389..5dcd44772a 100644
--- a/src/modules/previewpane/common/controls/WebBrowserExt.cs
+++ b/src/modules/previewpane/common/controls/WebBrowserExt.cs
@@ -51,7 +51,8 @@ namespace PreviewHandlerCommon
public object InvokeMember(string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] namedParameters)
{
object result;
- if (name.Equals(DISPIDAMBIENTDLCONTROL))
+
+ if (name != null && name.Equals(DISPIDAMBIENTDLCONTROL, StringComparison.CurrentCulture))
{
result = Convert.ToInt32(
WebBrowserDownloadControlFlags.DLIMAGES |
@@ -65,11 +66,11 @@ namespace PreviewHandlerCommon
WebBrowserDownloadControlFlags.NO_DLACTIVEXCTLS |
WebBrowserDownloadControlFlags.NO_RUNACTIVEXCTLS |
WebBrowserDownloadControlFlags.NO_BEHAVIORS |
- WebBrowserDownloadControlFlags.SILENT);
+ WebBrowserDownloadControlFlags.SILENT, CultureInfo.CurrentCulture);
}
else
{
- result = this.GetType().InvokeMember(name, invokeAttr, binder, target, args, modifiers, culture, namedParameters);
+ result = GetType().InvokeMember(name, invokeAttr, binder, target, args, modifiers, culture, namedParameters);
}
return result;
diff --git a/src/modules/previewpane/common/examplehandler/CustomControlTest.cs b/src/modules/previewpane/common/examplehandler/CustomControlTest.cs
index d9e6e68c25..52fc860e54 100644
--- a/src/modules/previewpane/common/examplehandler/CustomControlTest.cs
+++ b/src/modules/previewpane/common/examplehandler/CustomControlTest.cs
@@ -2,6 +2,7 @@
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using System;
using System.IO;
using System.Windows.Forms;
@@ -24,7 +25,7 @@ namespace Common
WebBrowser browser = new WebBrowser();
browser.DocumentText = "Test";
- browser.Navigate(filePath);
+ browser.Navigate(new Uri(filePath));
browser.Dock = DockStyle.Fill;
browser.IsWebBrowserContextMenuEnabled = false;
this.Controls.Add(browser);
diff --git a/src/modules/previewpane/common/examplehandler/TestCustomHandler.cs b/src/modules/previewpane/common/examplehandler/TestCustomHandler.cs
index f5d783020d..2e6828daae 100644
--- a/src/modules/previewpane/common/examplehandler/TestCustomHandler.cs
+++ b/src/modules/previewpane/common/examplehandler/TestCustomHandler.cs
@@ -2,6 +2,7 @@
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using System;
using System.Runtime.InteropServices;
namespace Common
@@ -12,21 +13,50 @@ namespace Common
[Guid("22a1a8e8-e929-4732-90ce-91eaff38b614")]
[ClassInterface(ClassInterfaceType.None)]
[ComVisible(true)]
- public class TestCustomHandler : FileBasedPreviewHandler
+ public class TestCustomHandler : FileBasedPreviewHandler, IDisposable
{
- private CustomControlTest previewHandlerControl;
+ private CustomControlTest _previewHandlerControl;
+ private bool disposedValue;
///
public override void DoPreview()
{
- this.previewHandlerControl.DoPreview(this.FilePath);
+ _previewHandlerControl.DoPreview(FilePath);
}
///
protected override IPreviewHandlerControl CreatePreviewHandlerControl()
{
- this.previewHandlerControl = new CustomControlTest();
- return this.previewHandlerControl;
+ _previewHandlerControl = new CustomControlTest();
+
+ return _previewHandlerControl;
+ }
+
+ ///
+ /// Disposes objects
+ ///
+ /// Is Disposing
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!disposedValue)
+ {
+ if (disposing)
+ {
+ _previewHandlerControl.Dispose();
+ }
+
+ // TODO: free unmanaged resources (unmanaged objects) and override finalizer
+ // TODO: set large fields to null
+ disposedValue = true;
+ }
+ }
+
+ ///
+ public void Dispose()
+ {
+ // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
+ Dispose(disposing: true);
+ GC.SuppressFinalize(this);
}
}
}
diff --git a/src/modules/previewpane/common/handlers/PreviewHandlerBase.cs b/src/modules/previewpane/common/handlers/PreviewHandlerBase.cs
index 6d47cc348d..3eaff72502 100644
--- a/src/modules/previewpane/common/handlers/PreviewHandlerBase.cs
+++ b/src/modules/previewpane/common/handlers/PreviewHandlerBase.cs
@@ -46,7 +46,14 @@ namespace Common
///
public PreviewHandlerBase()
{
- this.previewControl = this.CreatePreviewHandlerControl();
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public void Initialize()
+ {
+ previewControl = CreatePreviewHandlerControl();
}
///
@@ -107,7 +114,7 @@ namespace Common
///
public void GetWindow(out IntPtr phwnd)
{
- phwnd = this.previewControl.GetHandle();
+ phwnd = this.previewControl.GetWindowHandle();
}
///