mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-15 11:17:53 +01:00
[fxcop] preview handler common (#6762)
* FxCop adjustments * initing due to change for abstract
This commit is contained in:
@@ -20,6 +20,14 @@ namespace Microsoft.PowerToys.PreviewHandler.Markdown
|
||||
private MarkdownPreviewHandlerControl _markdownPreviewHandlerControl;
|
||||
private bool disposedValue;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MarkdownPreviewHandler"/> class.
|
||||
/// </summary>
|
||||
public MarkdownPreviewHandler()
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void DoPreview()
|
||||
{
|
||||
|
||||
@@ -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))
|
||||
{
|
||||
|
||||
@@ -20,6 +20,14 @@ namespace Microsoft.PowerToys.PreviewHandler.Svg
|
||||
private SvgPreviewControl _svgPreviewControl;
|
||||
private bool disposedValue;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SvgPreviewHandler"/> class.
|
||||
/// </summary>
|
||||
public SvgPreviewHandler()
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void DoPreview()
|
||||
{
|
||||
|
||||
@@ -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))
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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<IPreviewHandlerControl>();
|
||||
mockPreviewControl.Setup(x => x.GetHandle())
|
||||
mockPreviewControl.Setup(x => x.GetWindowHandle())
|
||||
.Returns(previewControlHandle);
|
||||
|
||||
previewHandlerControl = mockPreviewControl.Object;
|
||||
|
||||
@@ -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<IStream>();
|
||||
|
||||
// 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<IStream>();
|
||||
|
||||
// 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<IStream>();
|
||||
|
||||
// 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<int>()));
|
||||
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<IStream>();
|
||||
|
||||
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<IStream>();
|
||||
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<IStream>();
|
||||
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<IStream>();
|
||||
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<IStream>();
|
||||
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<IStream>();
|
||||
var streamWrapper = new StreamWrapper(stremMock.Object);
|
||||
var streamWrapper = new ReadonlyStream(stremMock.Object);
|
||||
NotImplementedException exception = null;
|
||||
|
||||
// Act
|
||||
|
||||
@@ -110,6 +110,7 @@
|
||||
<Compile Include="cominterop\IViewObject.cs" />
|
||||
<Compile Include="cominterop\LOGFONT.cs" />
|
||||
<Compile Include="cominterop\MSG.cs" />
|
||||
<Compile Include="cominterop\NativeMethods.cs" />
|
||||
<Compile Include="cominterop\RECT.cs" />
|
||||
<Compile Include="controls\WebBrowserDownloadControlFlags.cs" />
|
||||
<Compile Include="controls\WebBrowserExt.cs">
|
||||
@@ -129,7 +130,7 @@
|
||||
<Compile Include="handlers\PreviewHandlerBase.cs" />
|
||||
<Compile Include="handlers\StreamBasedPreviewHandler.cs" />
|
||||
<Compile Include="examplehandler\TestCustomHandler.cs" />
|
||||
<Compile Include="Utilities\StreamWrapper.cs" />
|
||||
<Compile Include="Utilities\ReadonlyStream.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AdditionalFiles Include="..\..\..\codeAnalysis\StyleCop.json">
|
||||
@@ -137,6 +138,11 @@
|
||||
</AdditionalFiles>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers">
|
||||
<Version>3.3.0</Version>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="StyleCop.Analyzers">
|
||||
<Version>1.1.118</Version>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
|
||||
@@ -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
|
||||
/// <remarks>
|
||||
/// Implements only read from the stream functionality.
|
||||
/// </remarks>
|
||||
public class StreamWrapper : Stream
|
||||
public class ReadonlyStream : Stream
|
||||
{
|
||||
private IStream stream;
|
||||
private IStream _stream;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="StreamWrapper"/> class.
|
||||
/// Initializes a new instance of the <see cref="ReadonlyStream"/> class.
|
||||
/// </summary>
|
||||
/// <param name="stream">A pointer to an <see cref="IStream" /> interface that represents the stream source.</param>
|
||||
public StreamWrapper(IStream stream)
|
||||
public ReadonlyStream(IStream stream)
|
||||
{
|
||||
this.stream = stream ?? throw new ArgumentNullException(nameof(stream));
|
||||
_stream = stream ?? throw new ArgumentNullException(nameof(stream));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -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
|
||||
/// <returns>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.</returns>
|
||||
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
|
||||
/// <returns>The new position within the current stream.</returns>
|
||||
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
|
||||
/// <inheritdoc/>
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,12 +11,13 @@ namespace Common.ComInterlop
|
||||
/// The COLORREF value is used to specify an RGB color.
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1815:Override equals and operator equals on value types", Justification = "Interop")]
|
||||
public struct COLORREF
|
||||
{
|
||||
/// <summary>
|
||||
/// Stores an RGB color value in a 32 bit integer.
|
||||
/// Gets or sets stores an RGB color value in a 32 bit integer.
|
||||
/// </summary>
|
||||
public uint Dword;
|
||||
public uint Dword { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets RGB value stored in <see cref="Dword"/> in <see cref="Color"/> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,10 +10,11 @@ namespace Common.ComInterlop
|
||||
/// <summary>
|
||||
/// Specifies the alpha type of the image.
|
||||
/// </summary>
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1707:Identifiers should not contain underscores", Justification = "Interop")]
|
||||
public enum WTS_ALPHATYPE : int
|
||||
{
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
WTSAT_UNKNOWN = 0,
|
||||
|
||||
|
||||
@@ -10,79 +10,86 @@ namespace Common.ComInterlop
|
||||
/// Defines the attributes of a font.
|
||||
/// </summary>
|
||||
[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
|
||||
{
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
public int LfHeight;
|
||||
public int LfHeight { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
public int LfWidth;
|
||||
public int LfWidth { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
public int LfEscapement;
|
||||
public int LfEscapement { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
public int LfOrientation;
|
||||
public int LfOrientation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
public int LfWeight;
|
||||
public int LfWeight { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
public byte LfItalic;
|
||||
public byte LfItalic { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
public byte LfUnderline;
|
||||
public byte LfUnderline { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
public byte LfStrikeOut;
|
||||
public byte LfStrikeOut { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Value of type BYTE that specifies the character set.
|
||||
/// Gets or sets value of type BYTE that specifies the character set.
|
||||
/// </summary>
|
||||
public byte LfCharSet;
|
||||
public byte LfCharSet { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
public byte LfOutPrecision;
|
||||
public byte LfOutPrecision { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
public byte LfClipPrecision;
|
||||
public byte LfClipPrecision { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
public byte LfQuality;
|
||||
public byte LfQuality { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
public byte LfPitchAndFamily;
|
||||
public byte LfPitchAndFamily { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
public string LfFaceName
|
||||
{
|
||||
get { return _lfFaceName; }
|
||||
set { _lfFaceName = value; }
|
||||
}
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
|
||||
public string LfFaceName;
|
||||
private string _lfFaceName;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,41 +11,42 @@ namespace Common.ComInterlop
|
||||
/// Contains message information from a thread's message queue.
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1815:Override equals and operator equals on value types", Justification = "Interop")]
|
||||
public struct MSG
|
||||
{
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
public IntPtr Hwnd;
|
||||
public IntPtr Hwnd { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
public int Message;
|
||||
public int Message { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
public IntPtr WParam;
|
||||
public IntPtr WParam { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
public IntPtr LParam;
|
||||
public IntPtr LParam { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The time at which the message was posted.
|
||||
/// Gets or sets the time at which the message was posted.
|
||||
/// </summary>
|
||||
public int Time;
|
||||
public int Time { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
public int PtX;
|
||||
public int PtX { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
public int PtY;
|
||||
public int PtY { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
37
src/modules/previewpane/common/cominterop/NativeMethods.cs
Normal file
37
src/modules/previewpane/common/cominterop/NativeMethods.cs
Normal file
@@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// Interop methods
|
||||
/// </summary>
|
||||
internal class NativeMethods
|
||||
{
|
||||
/// <summary>
|
||||
/// Changes the parent window of the specified child window.
|
||||
/// </summary>
|
||||
/// <param name="hWndChild">A handle to the child window.</param>
|
||||
/// <param name="hWndNewParent">A handle to the new parent window.</param>
|
||||
/// <returns>If the function succeeds, the return value is a handle to the previous parent window and NULL in case of failure.</returns>
|
||||
[DllImport("user32.dll")]
|
||||
public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the handle to the window that has the keyboard focus, if the window is attached to the calling thread's message queue.
|
||||
/// </summary>
|
||||
/// <returns>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.</returns>
|
||||
[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);
|
||||
}
|
||||
}
|
||||
@@ -11,27 +11,28 @@ namespace Common.ComInterlop
|
||||
/// The RECT structure defines a rectangle by the coordinates of its upper-left and lower-right corners.
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1815:Override equals and operator equals on value types", Justification = "Interop")]
|
||||
public struct RECT
|
||||
{
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
public int Left;
|
||||
public int Left { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
public int Top;
|
||||
public int Top { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
public int Right;
|
||||
public int Right { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
public int Bottom;
|
||||
public int Bottom { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a <see cref="Rectangle" /> structure with the edge locations specified in the struct.
|
||||
@@ -39,7 +40,7 @@ namespace Common.ComInterlop
|
||||
/// <returns>Return a <see cref="Rectangle"/>.</returns>
|
||||
public Rectangle ToRectangle()
|
||||
{
|
||||
return Rectangle.FromLTRB(this.Left, this.Top, this.Right, this.Bottom);
|
||||
return Rectangle.FromLTRB(Left, Top, Right, Bottom);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Changes the parent window of the specified child window.
|
||||
/// </summary>
|
||||
/// <param name="hWndChild">A handle to the child window.</param>
|
||||
/// <param name="hWndNewParent">A handle to the new parent window.</param>
|
||||
/// <returns>If the function succeeds, the return value is a handle to the previous parent window and NULL in case of failure.</returns>
|
||||
[DllImport("user32.dll")]
|
||||
private static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the handle to the window that has the keyboard focus, if the window is attached to the calling thread's message queue.
|
||||
/// </summary>
|
||||
/// <returns>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.</returns>
|
||||
[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);
|
||||
|
||||
/// <summary>
|
||||
/// Update the Form Control window with the passed rectangle.
|
||||
/// </summary>
|
||||
@@ -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;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace Common
|
||||
/// Gets the HWND of the control window.
|
||||
/// </summary>
|
||||
/// <returns>Pointer to the window handle.</returns>
|
||||
IntPtr GetHandle();
|
||||
IntPtr GetWindowHandle();
|
||||
|
||||
/// <summary>
|
||||
/// Hide the preview and free any resource used for the preview.
|
||||
|
||||
@@ -9,6 +9,7 @@ using System;
|
||||
/// Values of flags are defined in mshtmdid.h in distributed Windows Sdk.
|
||||
/// </summary>
|
||||
[Flags]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1707:Identifiers should not contain underscores", Justification = "Interop, keeping stuff in sync")]
|
||||
public enum WebBrowserDownloadControlFlags : int
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void DoPreview()
|
||||
{
|
||||
this.previewHandlerControl.DoPreview(this.FilePath);
|
||||
_previewHandlerControl.DoPreview(FilePath);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override IPreviewHandlerControl CreatePreviewHandlerControl()
|
||||
{
|
||||
this.previewHandlerControl = new CustomControlTest();
|
||||
return this.previewHandlerControl;
|
||||
_previewHandlerControl = new CustomControlTest();
|
||||
|
||||
return _previewHandlerControl;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposes objects
|
||||
/// </summary>
|
||||
/// <param name="disposing">Is Disposing</param>
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Dispose()
|
||||
{
|
||||
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
|
||||
Dispose(disposing: true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,14 @@ namespace Common
|
||||
/// </summary>
|
||||
public PreviewHandlerBase()
|
||||
{
|
||||
this.previewControl = this.CreatePreviewHandlerControl();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PreviewHandlerBase"/> class.
|
||||
/// </summary>
|
||||
public void Initialize()
|
||||
{
|
||||
previewControl = CreatePreviewHandlerControl();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -107,7 +114,7 @@ namespace Common
|
||||
/// <inheritdoc />
|
||||
public void GetWindow(out IntPtr phwnd)
|
||||
{
|
||||
phwnd = this.previewControl.GetHandle();
|
||||
phwnd = this.previewControl.GetWindowHandle();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
Reference in New Issue
Block a user