mirror of
https://github.com/QL-Win/QuickLook.git
synced 2025-09-13 11:09:06 +00:00
fix Exif rotation in ImageViewer; WIP on archive viewer
This commit is contained in:
85
QuickLook.Plugin.ArchiveViewer/Plugin.cs
Normal file
85
QuickLook.Plugin.ArchiveViewer/Plugin.cs
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Windows;
|
||||||
|
using SharpCompress.Archives.SevenZip;
|
||||||
|
using SharpCompress.Common;
|
||||||
|
using SharpCompress.Readers;
|
||||||
|
|
||||||
|
namespace QuickLook.Plugin.ArchiveViewer
|
||||||
|
{
|
||||||
|
public class Plugin : IViewer
|
||||||
|
{
|
||||||
|
public int Priority => 0;
|
||||||
|
|
||||||
|
public bool CanHandle(string path)
|
||||||
|
{
|
||||||
|
if (Directory.Exists(path))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
using (var s = File.OpenRead(path))
|
||||||
|
{
|
||||||
|
// The 7Zip format doesn't allow for reading as a forward-only stream so
|
||||||
|
// 7Zip is only supported through the Archive API.
|
||||||
|
if (SevenZipArchive.IsSevenZipFile(s))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
s.Seek(0, SeekOrigin.Begin);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ReaderFactory.Open(s);
|
||||||
|
}
|
||||||
|
catch (InvalidOperationException)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Prepare(string path, ViewContentContainer container)
|
||||||
|
{
|
||||||
|
container.PreferedSize = new Size {Width = 800, Height = 600};
|
||||||
|
}
|
||||||
|
|
||||||
|
public void View(string path, ViewContentContainer container)
|
||||||
|
{
|
||||||
|
var files = new List<IEntry>();
|
||||||
|
|
||||||
|
if (SevenZipArchive.IsSevenZipFile(path))
|
||||||
|
GetItemsFromSevenZip(path, files);
|
||||||
|
else
|
||||||
|
GetItemsFromIReader(path, files);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Close()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GetItemsFromSevenZip(string path, List<IEntry> files)
|
||||||
|
{
|
||||||
|
using (var s = File.OpenRead(path))
|
||||||
|
{
|
||||||
|
using (var reader = SevenZipArchive.Open(s))
|
||||||
|
{
|
||||||
|
foreach (var entry in reader.Entries)
|
||||||
|
files.Add(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GetItemsFromIReader(string path, List<IEntry> files)
|
||||||
|
{
|
||||||
|
using (var s = File.OpenRead(path))
|
||||||
|
{
|
||||||
|
using (var reader = ReaderFactory.Open(s))
|
||||||
|
{
|
||||||
|
while (reader.MoveToNextEntry())
|
||||||
|
files.Add(reader.Entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
35
QuickLook.Plugin.ArchiveViewer/Properties/AssemblyInfo.cs
Normal file
35
QuickLook.Plugin.ArchiveViewer/Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
// General Information about an assembly is controlled through the following
|
||||||
|
// set of attributes. Change these attribute values to modify the information
|
||||||
|
// associated with an assembly.
|
||||||
|
[assembly: AssemblyTitle("QuickLook.Plugin.ArchiveViewer")]
|
||||||
|
[assembly: AssemblyDescription("")]
|
||||||
|
[assembly: AssemblyConfiguration("")]
|
||||||
|
[assembly: AssemblyCompany("")]
|
||||||
|
[assembly: AssemblyProduct("QuickLook.Plugin.ArchiveViewer")]
|
||||||
|
[assembly: AssemblyCopyright("Copyright © 2017")]
|
||||||
|
[assembly: AssemblyTrademark("")]
|
||||||
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
|
// Setting ComVisible to false makes the types in this assembly not visible
|
||||||
|
// to COM components. If you need to access a type in this assembly from
|
||||||
|
// COM, set the ComVisible attribute to true on that type.
|
||||||
|
[assembly: ComVisible(false)]
|
||||||
|
|
||||||
|
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||||
|
[assembly: Guid("de2e3bc5-6ab2-4420-a160-48c7a7506c1c")]
|
||||||
|
|
||||||
|
// Version information for an assembly consists of the following four values:
|
||||||
|
//
|
||||||
|
// Major Version
|
||||||
|
// Minor Version
|
||||||
|
// Build Number
|
||||||
|
// Revision
|
||||||
|
//
|
||||||
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
|
// by using the '*' as shown below:
|
||||||
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
|
[assembly: AssemblyVersion("1.0.0.0")]
|
||||||
|
[assembly: AssemblyFileVersion("1.0.0.0")]
|
@@ -0,0 +1,66 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ProjectGuid>{DE2E3BC5-6AB2-4420-A160-48C7A7506C1C}</ProjectGuid>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
|
<RootNamespace>QuickLook.Plugin.ArchiveViewer</RootNamespace>
|
||||||
|
<AssemblyName>QuickLook.Plugin.ArchiveViewer</AssemblyName>
|
||||||
|
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||||
|
<FileAlignment>512</FileAlignment>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>..\Build\Debug\Plugins\QuickLook.Plugin.ArchiveViewer\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>..\Build\Release\Plugins\QuickLook.Plugin.ArchiveViewer\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="PresentationCore" />
|
||||||
|
<Reference Include="PresentationFramework" />
|
||||||
|
<Reference Include="SharpCompress, Version=0.15.2.0, Culture=neutral, PublicKeyToken=afb0a02973931d96, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\SharpCompress.0.15.2\lib\net45\SharpCompress.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Core" />
|
||||||
|
<Reference Include="System.Xaml" />
|
||||||
|
<Reference Include="System.Xml.Linq" />
|
||||||
|
<Reference Include="System.Data.DataSetExtensions" />
|
||||||
|
<Reference Include="Microsoft.CSharp" />
|
||||||
|
<Reference Include="System.Data" />
|
||||||
|
<Reference Include="System.Net.Http" />
|
||||||
|
<Reference Include="System.Xml" />
|
||||||
|
<Reference Include="WindowsBase" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="Plugin.cs" />
|
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\QuickLook\QuickLook.csproj">
|
||||||
|
<Project>{8b4a9ce5-67b5-4a94-81cb-3771f688fdeb}</Project>
|
||||||
|
<Name>QuickLook</Name>
|
||||||
|
<Private>False</Private>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="packages.config" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
|
</Project>
|
5
QuickLook.Plugin.ArchiveViewer/packages.config
Normal file
5
QuickLook.Plugin.ArchiveViewer/packages.config
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<packages>
|
||||||
|
<package id="SharpCompress" version="0.15.2" targetFramework="net452" />
|
||||||
|
</packages>
|
53
QuickLook.Plugin.ImageViewer/ImageFileHelper.cs
Normal file
53
QuickLook.Plugin.ImageViewer/ImageFileHelper.cs
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
using System.IO;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Media.Imaging;
|
||||||
|
|
||||||
|
namespace QuickLook.Plugin.ImageViewer
|
||||||
|
{
|
||||||
|
internal static class ImageFileHelper
|
||||||
|
{
|
||||||
|
internal static Size GetImageSize(string path)
|
||||||
|
{
|
||||||
|
var ori = GetOrientationFromExif(path);
|
||||||
|
|
||||||
|
using (var stream = File.OpenRead(path))
|
||||||
|
{
|
||||||
|
var decoder = BitmapDecoder.Create(stream, BitmapCreateOptions.None, BitmapCacheOption.None);
|
||||||
|
var frame = decoder.Frames[0];
|
||||||
|
|
||||||
|
if (ori == ExifOrientation.Rotate90CW || ori == ExifOrientation.Rotate270CW)
|
||||||
|
return new Size {Width = frame.PixelHeight, Height = frame.PixelWidth};
|
||||||
|
|
||||||
|
return new Size {Width = frame.PixelWidth, Height = frame.PixelHeight};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static ExifOrientation GetOrientationFromExif(string path)
|
||||||
|
{
|
||||||
|
using (var stream = File.OpenRead(path))
|
||||||
|
{
|
||||||
|
var decoder = BitmapDecoder.Create(stream, BitmapCreateOptions.None, BitmapCacheOption.None);
|
||||||
|
var frame = decoder.Frames[0];
|
||||||
|
|
||||||
|
var orientation = ((BitmapMetadata) frame.Metadata).GetQuery(@"/app1/{ushort=0}/{ushort=274}");
|
||||||
|
|
||||||
|
if (orientation == null)
|
||||||
|
return ExifOrientation.Horizontal;
|
||||||
|
|
||||||
|
return (ExifOrientation) (ushort) orientation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal enum ExifOrientation
|
||||||
|
{
|
||||||
|
Horizontal = 1,
|
||||||
|
MirrorHorizontal = 2,
|
||||||
|
Rotate180 = 3,
|
||||||
|
MirrorVertical = 4,
|
||||||
|
MirrorHorizontal270CW = 5,
|
||||||
|
Rotate90CW = 6,
|
||||||
|
MirrorHorizontal90CW = 7,
|
||||||
|
Rotate270CW = 8
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.IO;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
@@ -20,7 +21,22 @@ namespace QuickLook.Plugin.ImageViewer
|
|||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
viewPanelImage.Source = new BitmapImage(new Uri(path));
|
var ori = ImageFileHelper.GetOrientationFromExif(path);
|
||||||
|
|
||||||
|
var bitmap = new BitmapImage();
|
||||||
|
using (var fs = File.OpenRead(path))
|
||||||
|
{
|
||||||
|
bitmap.BeginInit();
|
||||||
|
bitmap.StreamSource = fs;
|
||||||
|
bitmap.CacheOption = BitmapCacheOption.OnLoad;
|
||||||
|
bitmap.Rotation = ori == ImageFileHelper.ExifOrientation.Rotate90CW
|
||||||
|
? Rotation.Rotate90
|
||||||
|
: ori == ImageFileHelper.ExifOrientation.Rotate270CW
|
||||||
|
? Rotation.Rotate270
|
||||||
|
: Rotation.Rotate0;
|
||||||
|
bitmap.EndInit();
|
||||||
|
}
|
||||||
|
viewPanelImage.Source = bitmap;
|
||||||
|
|
||||||
Loaded += (sender, e) => { ZoomToFit(); };
|
Loaded += (sender, e) => { ZoomToFit(); };
|
||||||
|
|
||||||
|
@@ -1,16 +1,14 @@
|
|||||||
using System;
|
using System.IO;
|
||||||
using System.IO;
|
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Media.Imaging;
|
|
||||||
|
|
||||||
namespace QuickLook.Plugin.ImageViewer
|
namespace QuickLook.Plugin.ImageViewer
|
||||||
{
|
{
|
||||||
public class Plugin : IViewer
|
public class Plugin : IViewer
|
||||||
{
|
{
|
||||||
|
private Size _imageSize;
|
||||||
private ImagePanel _ip;
|
private ImagePanel _ip;
|
||||||
private BitmapDecoder decoder;
|
|
||||||
|
|
||||||
public int Priority { get; }
|
public int Priority => 9999;
|
||||||
|
|
||||||
public bool CanHandle(string path)
|
public bool CanHandle(string path)
|
||||||
{
|
{
|
||||||
@@ -37,10 +35,9 @@ namespace QuickLook.Plugin.ImageViewer
|
|||||||
|
|
||||||
public void Prepare(string path, ViewContentContainer container)
|
public void Prepare(string path, ViewContentContainer container)
|
||||||
{
|
{
|
||||||
decoder = BitmapDecoder.Create(new Uri(path), BitmapCreateOptions.None, BitmapCacheOption.None);
|
_imageSize = ImageFileHelper.GetImageSize(path);
|
||||||
var frame = decoder.Frames[0];
|
|
||||||
|
|
||||||
container.SetPreferedSizeFit(new Size {Width = frame.Width, Height = frame.Height}, 0.6);
|
container.SetPreferedSizeFit(_imageSize, 0.8);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void View(string path, ViewContentContainer container)
|
public void View(string path, ViewContentContainer container)
|
||||||
@@ -48,7 +45,7 @@ namespace QuickLook.Plugin.ImageViewer
|
|||||||
_ip = new ImagePanel(path);
|
_ip = new ImagePanel(path);
|
||||||
|
|
||||||
container.SetContent(_ip);
|
container.SetContent(_ip);
|
||||||
container.Title = $"{Path.GetFileName(path)}";
|
container.Title = $"{Path.GetFileName(path)} ({_imageSize.Width} × {_imageSize.Height})";
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Close()
|
public void Close()
|
||||||
|
@@ -49,6 +49,7 @@
|
|||||||
</Reference>
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="ImageFileHelper.cs" />
|
||||||
<Compile Include="ImagePanel.xaml.cs">
|
<Compile Include="ImagePanel.xaml.cs">
|
||||||
<DependentUpon>ImagePanel.xaml</DependentUpon>
|
<DependentUpon>ImagePanel.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
@@ -14,6 +14,10 @@ namespace QuickLook.Plugin.LastResort
|
|||||||
|
|
||||||
public static BitmapSource ToBitmapSource(this Bitmap source)
|
public static BitmapSource ToBitmapSource(this Bitmap source)
|
||||||
{
|
{
|
||||||
|
// BitmapSource.Create throws an exception when the image is scanned backward.
|
||||||
|
// The Clone() will make it back scanning forward.
|
||||||
|
source = (Bitmap) source.Clone();
|
||||||
|
|
||||||
var ip = source.GetHbitmap();
|
var ip = source.GetHbitmap();
|
||||||
BitmapSource bs = null;
|
BitmapSource bs = null;
|
||||||
try
|
try
|
||||||
|
@@ -1,256 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Drawing;
|
|
||||||
using System.IO;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
// ReSharper disable InconsistentNaming
|
|
||||||
|
|
||||||
namespace QuickLook.Plugin.LastResort
|
|
||||||
{
|
|
||||||
public static class IconHelper
|
|
||||||
{
|
|
||||||
public enum IconSizeEnum
|
|
||||||
{
|
|
||||||
SmallIcon16 = SHGFI_SMALLICON,
|
|
||||||
MediumIcon32 = SHGFI_LARGEICON,
|
|
||||||
LargeIcon48 = SHIL_EXTRALARGE,
|
|
||||||
ExtraLargeIcon = SHIL_JUMBO
|
|
||||||
}
|
|
||||||
|
|
||||||
private const int SHGFI_SMALLICON = 0x1;
|
|
||||||
private const int SHGFI_LARGEICON = 0x0;
|
|
||||||
private const int SHIL_JUMBO = 0x4;
|
|
||||||
private const int SHIL_EXTRALARGE = 0x2;
|
|
||||||
private const int WM_CLOSE = 0x0010;
|
|
||||||
|
|
||||||
[DllImport("user32")]
|
|
||||||
private static extern
|
|
||||||
IntPtr SendMessage(
|
|
||||||
IntPtr handle,
|
|
||||||
int Msg,
|
|
||||||
IntPtr wParam,
|
|
||||||
IntPtr lParam);
|
|
||||||
|
|
||||||
|
|
||||||
[DllImport("shell32.dll")]
|
|
||||||
private static extern int SHGetImageList(
|
|
||||||
int iImageList,
|
|
||||||
ref Guid riid,
|
|
||||||
out IImageList ppv);
|
|
||||||
|
|
||||||
[DllImport("Shell32.dll")]
|
|
||||||
private static extern int SHGetFileInfo(
|
|
||||||
string pszPath,
|
|
||||||
int dwFileAttributes,
|
|
||||||
ref SHFILEINFO psfi,
|
|
||||||
int cbFileInfo,
|
|
||||||
uint uFlags);
|
|
||||||
|
|
||||||
[DllImport("user32")]
|
|
||||||
private static extern int DestroyIcon(
|
|
||||||
IntPtr hIcon);
|
|
||||||
|
|
||||||
public static Bitmap GetBitmapFromFolderPath(
|
|
||||||
string filepath, IconSizeEnum iconsize)
|
|
||||||
{
|
|
||||||
var hIcon = GetIconHandleFromFolderPath(filepath, iconsize);
|
|
||||||
return getBitmapFromIconHandle(hIcon);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Bitmap GetBitmapFromFilePath(
|
|
||||||
string filepath, IconSizeEnum iconsize)
|
|
||||||
{
|
|
||||||
var hIcon = GetIconHandleFromFilePath(filepath, iconsize);
|
|
||||||
return getBitmapFromIconHandle(hIcon);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Bitmap GetBitmapFromPath(
|
|
||||||
string filepath, IconSizeEnum iconsize)
|
|
||||||
{
|
|
||||||
var hIcon = IntPtr.Zero;
|
|
||||||
if (Directory.Exists(filepath))
|
|
||||||
{
|
|
||||||
hIcon = GetIconHandleFromFolderPath(filepath, iconsize);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (File.Exists(filepath))
|
|
||||||
hIcon = GetIconHandleFromFilePath(filepath, iconsize);
|
|
||||||
}
|
|
||||||
return getBitmapFromIconHandle(hIcon);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Bitmap getBitmapFromIconHandle(IntPtr hIcon)
|
|
||||||
{
|
|
||||||
if (hIcon == IntPtr.Zero) throw new FileNotFoundException();
|
|
||||||
var myIcon = Icon.FromHandle(hIcon);
|
|
||||||
var bitmap = myIcon.ToBitmap();
|
|
||||||
myIcon.Dispose();
|
|
||||||
DestroyIcon(hIcon);
|
|
||||||
SendMessage(hIcon, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
|
|
||||||
return bitmap;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static IntPtr GetIconHandleFromFilePath(string filepath, IconSizeEnum iconsize)
|
|
||||||
{
|
|
||||||
var shinfo = new SHFILEINFO();
|
|
||||||
const uint SHGFI_SYSICONINDEX = 0x4000;
|
|
||||||
const int FILE_ATTRIBUTE_NORMAL = 0x80;
|
|
||||||
var flags = SHGFI_SYSICONINDEX;
|
|
||||||
return getIconHandleFromFilePathWithFlags(filepath, iconsize, ref shinfo, FILE_ATTRIBUTE_NORMAL, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static IntPtr GetIconHandleFromFolderPath(string folderpath, IconSizeEnum iconsize)
|
|
||||||
{
|
|
||||||
var shinfo = new SHFILEINFO();
|
|
||||||
|
|
||||||
const uint SHGFI_ICON = 0x000000100;
|
|
||||||
const uint SHGFI_USEFILEATTRIBUTES = 0x000000010;
|
|
||||||
const int FILE_ATTRIBUTE_DIRECTORY = 0x00000010;
|
|
||||||
var flags = SHGFI_ICON | SHGFI_USEFILEATTRIBUTES;
|
|
||||||
return getIconHandleFromFilePathWithFlags(folderpath, iconsize, ref shinfo, FILE_ATTRIBUTE_DIRECTORY,
|
|
||||||
flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static IntPtr getIconHandleFromFilePathWithFlags(
|
|
||||||
string filepath, IconSizeEnum iconsize,
|
|
||||||
ref SHFILEINFO shinfo, int fileAttributeFlag, uint flags)
|
|
||||||
{
|
|
||||||
const int ILD_TRANSPARENT = 1;
|
|
||||||
var retval = SHGetFileInfo(filepath, fileAttributeFlag, ref shinfo, Marshal.SizeOf(shinfo), flags);
|
|
||||||
if (retval == 0) throw new FileNotFoundException();
|
|
||||||
var iconIndex = shinfo.iIcon;
|
|
||||||
var iImageListGuid = new Guid("46EB5926-582E-4017-9FDF-E8998DAA0950");
|
|
||||||
IImageList iml;
|
|
||||||
var hres = SHGetImageList((int) iconsize, ref iImageListGuid, out iml);
|
|
||||||
var hIcon = IntPtr.Zero;
|
|
||||||
hres = iml.GetIcon(iconIndex, ILD_TRANSPARENT, ref hIcon);
|
|
||||||
return hIcon;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[ComImport]
|
|
||||||
[Guid("46EB5926-582E-4017-9FDF-E8998DAA0950")]
|
|
||||||
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
|
||||||
public interface IImageList
|
|
||||||
{
|
|
||||||
[PreserveSig]
|
|
||||||
int Add(
|
|
||||||
IntPtr hbmImage,
|
|
||||||
IntPtr hbmMask,
|
|
||||||
ref int pi);
|
|
||||||
|
|
||||||
[PreserveSig]
|
|
||||||
int ReplaceIcon(
|
|
||||||
int i,
|
|
||||||
IntPtr hicon,
|
|
||||||
ref int pi);
|
|
||||||
|
|
||||||
[PreserveSig]
|
|
||||||
int SetOverlayImage(
|
|
||||||
int iImage,
|
|
||||||
int iOverlay);
|
|
||||||
|
|
||||||
[PreserveSig]
|
|
||||||
int Replace(
|
|
||||||
int i,
|
|
||||||
IntPtr hbmImage,
|
|
||||||
IntPtr hbmMask);
|
|
||||||
|
|
||||||
[PreserveSig]
|
|
||||||
int AddMasked(
|
|
||||||
IntPtr hbmImage,
|
|
||||||
int crMask,
|
|
||||||
ref int pi);
|
|
||||||
|
|
||||||
[PreserveSig]
|
|
||||||
int Draw(
|
|
||||||
ref IMAGELISTDRAWPARAMS pimldp);
|
|
||||||
|
|
||||||
[PreserveSig]
|
|
||||||
int Remove(
|
|
||||||
int i);
|
|
||||||
|
|
||||||
[PreserveSig]
|
|
||||||
int GetIcon(
|
|
||||||
int i,
|
|
||||||
int flags,
|
|
||||||
ref IntPtr picon);
|
|
||||||
}
|
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
|
||||||
public struct IMAGEINFO
|
|
||||||
{
|
|
||||||
public IntPtr hbmImage;
|
|
||||||
public IntPtr hbmMask;
|
|
||||||
public int Unused1;
|
|
||||||
public int Unused2;
|
|
||||||
public RECT rcImage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct IMAGELISTDRAWPARAMS
|
|
||||||
{
|
|
||||||
public int cbSize;
|
|
||||||
public IntPtr himl;
|
|
||||||
public int i;
|
|
||||||
public IntPtr hdcDst;
|
|
||||||
public int x;
|
|
||||||
public int y;
|
|
||||||
public int cx;
|
|
||||||
public int cy;
|
|
||||||
public int xBitmap;
|
|
||||||
public int yBitmap;
|
|
||||||
public int rgbBk;
|
|
||||||
public int rgbFg;
|
|
||||||
public int fStyle;
|
|
||||||
public int dwRop;
|
|
||||||
public int fState;
|
|
||||||
public int Frame;
|
|
||||||
public int crEffect;
|
|
||||||
}
|
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
|
||||||
public struct POINT
|
|
||||||
{
|
|
||||||
private readonly int X;
|
|
||||||
private readonly int Y;
|
|
||||||
|
|
||||||
public POINT(int x, int y)
|
|
||||||
{
|
|
||||||
X = x;
|
|
||||||
Y = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
public POINT(Point pt) : this(pt.X, pt.Y)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public static implicit operator Point(POINT p)
|
|
||||||
{
|
|
||||||
return new Point(p.X, p.Y);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static implicit operator POINT(Point p)
|
|
||||||
{
|
|
||||||
return new POINT(p.X, p.Y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
|
||||||
public struct RECT
|
|
||||||
{
|
|
||||||
public int Left;
|
|
||||||
public int Top;
|
|
||||||
public int Right;
|
|
||||||
public int Bottom;
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct SHFILEINFO
|
|
||||||
{
|
|
||||||
public IntPtr hIcon;
|
|
||||||
public int iIcon;
|
|
||||||
public uint dwAttributes;
|
|
||||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 254)] public string szDisplayName;
|
|
||||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string szTypeName;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -10,7 +10,7 @@
|
|||||||
<ColumnDefinition Width="150" />
|
<ColumnDefinition Width="150" />
|
||||||
<ColumnDefinition Width="65*" />
|
<ColumnDefinition Width="65*" />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<Image x:Name="image" Grid.Column="0" Height="128" Width="128" Stretch="Fill" />
|
<Image x:Name="image" Grid.Column="0" Height="128" Width="128" Stretch="None" />
|
||||||
<Grid Grid.Column="1">
|
<Grid Grid.Column="1">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="20*" />
|
<ColumnDefinition Width="20*" />
|
||||||
|
@@ -24,9 +24,13 @@ namespace QuickLook.Plugin.LastResort
|
|||||||
|
|
||||||
public void DisplayInfo(string path)
|
public void DisplayInfo(string path)
|
||||||
{
|
{
|
||||||
var icon = IconHelper.GetBitmapFromPath(path, IconHelper.IconSizeEnum.ExtraLargeIcon).ToBitmapSource();
|
var icon =
|
||||||
|
WindowsThumbnailProvider.GetThumbnail(path, 256, 256,
|
||||||
|
ThumbnailOptions.ScaleUp);
|
||||||
|
|
||||||
image.Source = icon;
|
image.Source = icon.ToBitmapSource();
|
||||||
|
|
||||||
|
icon.Dispose();
|
||||||
|
|
||||||
var name = Path.GetFileName(path);
|
var name = Path.GetFileName(path);
|
||||||
filename.Content = string.IsNullOrEmpty(name) ? path : name;
|
filename.Content = string.IsNullOrEmpty(name) ? path : name;
|
||||||
|
@@ -54,7 +54,7 @@
|
|||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Plugin.cs" />
|
<Compile Include="Plugin.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="IconHelper.cs" />
|
<Compile Include="WindowsThumbnailProvider.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\QuickLook\QuickLook.csproj">
|
<ProjectReference Include="..\QuickLook\QuickLook.csproj">
|
||||||
|
203
QuickLook.Plugin.LastResort/WindowsThumbnailProvider.cs
Normal file
203
QuickLook.Plugin.LastResort/WindowsThumbnailProvider.cs
Normal file
@@ -0,0 +1,203 @@
|
|||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
using System.IO;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace QuickLook.Plugin.LastResort
|
||||||
|
{
|
||||||
|
[Flags]
|
||||||
|
internal enum ThumbnailOptions
|
||||||
|
{
|
||||||
|
None = 0x00,
|
||||||
|
BiggerSizeOk = 0x01,
|
||||||
|
InMemoryOnly = 0x02,
|
||||||
|
IconOnly = 0x04,
|
||||||
|
ThumbnailOnly = 0x08,
|
||||||
|
InCacheOnly = 0x10,
|
||||||
|
IconBackground = 0x80,
|
||||||
|
ScaleUp = 0x100
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static class WindowsThumbnailProvider
|
||||||
|
{
|
||||||
|
private const string IShellItem2Guid = "7E9FB0D3-919F-4307-AB2E-9B1860310C93";
|
||||||
|
|
||||||
|
[DllImport("shell32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
||||||
|
private static extern int SHCreateItemFromParsingName(
|
||||||
|
[MarshalAs(UnmanagedType.LPWStr)] string path,
|
||||||
|
// The following parameter is not used - binding context.
|
||||||
|
IntPtr pbc,
|
||||||
|
ref Guid riid,
|
||||||
|
[MarshalAs(UnmanagedType.Interface)] out IShellItem shellItem);
|
||||||
|
|
||||||
|
[DllImport("gdi32.dll")]
|
||||||
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
|
private static extern bool DeleteObject(IntPtr hObject);
|
||||||
|
|
||||||
|
public static Bitmap GetThumbnail(string fileName, int width, int height, ThumbnailOptions options)
|
||||||
|
{
|
||||||
|
var hBitmap = GetHBitmap(Path.GetFullPath(fileName), width, height, options);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// return a System.Drawing.Bitmap from the hBitmap
|
||||||
|
return GetBitmapFromHBitmap(hBitmap);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
// delete HBitmap to avoid memory leaks
|
||||||
|
DeleteObject(hBitmap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static Bitmap GetBitmapFromHBitmap(IntPtr nativeHBitmap)
|
||||||
|
{
|
||||||
|
var bmp = Image.FromHbitmap(nativeHBitmap);
|
||||||
|
|
||||||
|
if (Image.GetPixelFormatSize(bmp.PixelFormat) < 32)
|
||||||
|
return bmp;
|
||||||
|
|
||||||
|
return CreateAlphaBitmap(bmp, PixelFormat.Format32bppArgb);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static Bitmap CreateAlphaBitmap(Bitmap srcBitmap, PixelFormat targetPixelFormat)
|
||||||
|
{
|
||||||
|
var result = new Bitmap(srcBitmap.Width, srcBitmap.Height, targetPixelFormat);
|
||||||
|
|
||||||
|
var bmpBounds = new Rectangle(0, 0, srcBitmap.Width, srcBitmap.Height);
|
||||||
|
|
||||||
|
var srcData = srcBitmap.LockBits(bmpBounds, ImageLockMode.ReadOnly, srcBitmap.PixelFormat);
|
||||||
|
|
||||||
|
var isAlplaBitmap = false;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
for (var y = 0; y <= srcData.Height - 1; y++)
|
||||||
|
for (var x = 0; x <= srcData.Width - 1; x++)
|
||||||
|
{
|
||||||
|
var pixelColor = Color.FromArgb(
|
||||||
|
Marshal.ReadInt32(srcData.Scan0, srcData.Stride * y + 4 * x));
|
||||||
|
|
||||||
|
if ((pixelColor.A > 0) & (pixelColor.A < 255))
|
||||||
|
isAlplaBitmap = true;
|
||||||
|
|
||||||
|
result.SetPixel(x, y, pixelColor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
srcBitmap.UnlockBits(srcData);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isAlplaBitmap)
|
||||||
|
return result;
|
||||||
|
return srcBitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IntPtr GetHBitmap(string fileName, int width, int height, ThumbnailOptions options)
|
||||||
|
{
|
||||||
|
IShellItem nativeShellItem;
|
||||||
|
var shellItem2Guid = new Guid(IShellItem2Guid);
|
||||||
|
var retCode = SHCreateItemFromParsingName(fileName, IntPtr.Zero, ref shellItem2Guid, out nativeShellItem);
|
||||||
|
|
||||||
|
if (retCode != 0)
|
||||||
|
throw Marshal.GetExceptionForHR(retCode);
|
||||||
|
|
||||||
|
var nativeSize = new NativeSize();
|
||||||
|
nativeSize.Width = width;
|
||||||
|
nativeSize.Height = height;
|
||||||
|
|
||||||
|
IntPtr hBitmap;
|
||||||
|
var hr = ((IShellItemImageFactory) nativeShellItem).GetImage(nativeSize, options, out hBitmap);
|
||||||
|
|
||||||
|
Marshal.ReleaseComObject(nativeShellItem);
|
||||||
|
|
||||||
|
if (hr == HResult.Ok) return hBitmap;
|
||||||
|
|
||||||
|
throw Marshal.GetExceptionForHR((int) hr);
|
||||||
|
}
|
||||||
|
|
||||||
|
[ComImport]
|
||||||
|
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||||
|
[Guid("43826d1e-e718-42ee-bc55-a1e261c37bfe")]
|
||||||
|
internal interface IShellItem
|
||||||
|
{
|
||||||
|
void BindToHandler(IntPtr pbc,
|
||||||
|
[MarshalAs(UnmanagedType.LPStruct)] Guid bhid,
|
||||||
|
[MarshalAs(UnmanagedType.LPStruct)] Guid riid,
|
||||||
|
out IntPtr ppv);
|
||||||
|
|
||||||
|
void GetParent(out IShellItem ppsi);
|
||||||
|
void GetDisplayName(SIGDN sigdnName, out IntPtr ppszName);
|
||||||
|
void GetAttributes(uint sfgaoMask, out uint psfgaoAttribs);
|
||||||
|
void Compare(IShellItem psi, uint hint, out int piOrder);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal enum SIGDN : uint
|
||||||
|
{
|
||||||
|
NORMALDISPLAY = 0,
|
||||||
|
PARENTRELATIVEPARSING = 0x80018001,
|
||||||
|
PARENTRELATIVEFORADDRESSBAR = 0x8001c001,
|
||||||
|
DESKTOPABSOLUTEPARSING = 0x80028000,
|
||||||
|
PARENTRELATIVEEDITING = 0x80031001,
|
||||||
|
DESKTOPABSOLUTEEDITING = 0x8004c000,
|
||||||
|
FILESYSPATH = 0x80058000,
|
||||||
|
URL = 0x80068000
|
||||||
|
}
|
||||||
|
|
||||||
|
internal enum HResult
|
||||||
|
{
|
||||||
|
Ok = 0x0000,
|
||||||
|
False = 0x0001,
|
||||||
|
InvalidArguments = unchecked((int) 0x80070057),
|
||||||
|
OutOfMemory = unchecked((int) 0x8007000E),
|
||||||
|
NoInterface = unchecked((int) 0x80004002),
|
||||||
|
Fail = unchecked((int) 0x80004005),
|
||||||
|
ElementNotFound = unchecked((int) 0x80070490),
|
||||||
|
TypeElementNotFound = unchecked((int) 0x8002802B),
|
||||||
|
NoObject = unchecked((int) 0x800401E5),
|
||||||
|
Win32ErrorCanceled = 1223,
|
||||||
|
Canceled = unchecked((int) 0x800704C7),
|
||||||
|
ResourceInUse = unchecked((int) 0x800700AA),
|
||||||
|
AccessDenied = unchecked((int) 0x80030005)
|
||||||
|
}
|
||||||
|
|
||||||
|
[ComImport]
|
||||||
|
[Guid("bcc18b79-ba16-442f-80c4-8a59c30c463b")]
|
||||||
|
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||||
|
internal interface IShellItemImageFactory
|
||||||
|
{
|
||||||
|
[PreserveSig]
|
||||||
|
HResult GetImage(
|
||||||
|
[In] [MarshalAs(UnmanagedType.Struct)] NativeSize size,
|
||||||
|
[In] ThumbnailOptions flags,
|
||||||
|
[Out] out IntPtr phbm);
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
internal struct NativeSize
|
||||||
|
{
|
||||||
|
private int width;
|
||||||
|
private int height;
|
||||||
|
|
||||||
|
public int Width
|
||||||
|
{
|
||||||
|
set => width = value;
|
||||||
|
}
|
||||||
|
public int Height
|
||||||
|
{
|
||||||
|
set => height = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public struct RGBQUAD
|
||||||
|
{
|
||||||
|
public byte rgbBlue;
|
||||||
|
public byte rgbGreen;
|
||||||
|
public byte rgbRed;
|
||||||
|
public byte rgbReserved;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -15,7 +15,6 @@ namespace QuickLook.Plugin.TextViewer
|
|||||||
if (Directory.Exists(path))
|
if (Directory.Exists(path))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// ReSharper disable once InconsistentNaming
|
|
||||||
const long MAX_SIZE = 20 * 1024 * 1024;
|
const long MAX_SIZE = 20 * 1024 * 1024;
|
||||||
|
|
||||||
// if there is a possible highlighting scheme (by file extension), treat it as a plain text file
|
// if there is a possible highlighting scheme (by file extension), treat it as a plain text file
|
||||||
|
@@ -18,6 +18,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuickLook.Plugin.TextViewer
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuickLook.Plugin.ImageViewer", "QuickLook.Plugin.ImageViewer\QuickLook.Plugin.ImageViewer.csproj", "{FE5A5111-9607-4721-A7BE-422754002ED8}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuickLook.Plugin.ImageViewer", "QuickLook.Plugin.ImageViewer\QuickLook.Plugin.ImageViewer.csproj", "{FE5A5111-9607-4721-A7BE-422754002ED8}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuickLook.Plugin.ArchiveViewer", "QuickLook.Plugin.ArchiveViewer\QuickLook.Plugin.ArchiveViewer.csproj", "{DE2E3BC5-6AB2-4420-A160-48C7A7506C1C}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@@ -72,6 +74,14 @@ Global
|
|||||||
{FE5A5111-9607-4721-A7BE-422754002ED8}.Release|Any CPU.Build.0 = Release|Any CPU
|
{FE5A5111-9607-4721-A7BE-422754002ED8}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{FE5A5111-9607-4721-A7BE-422754002ED8}.Release|x86.ActiveCfg = Release|Any CPU
|
{FE5A5111-9607-4721-A7BE-422754002ED8}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
{FE5A5111-9607-4721-A7BE-422754002ED8}.Release|x86.Build.0 = Release|Any CPU
|
{FE5A5111-9607-4721-A7BE-422754002ED8}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{DE2E3BC5-6AB2-4420-A160-48C7A7506C1C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{DE2E3BC5-6AB2-4420-A160-48C7A7506C1C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{DE2E3BC5-6AB2-4420-A160-48C7A7506C1C}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{DE2E3BC5-6AB2-4420-A160-48C7A7506C1C}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{DE2E3BC5-6AB2-4420-A160-48C7A7506C1C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{DE2E3BC5-6AB2-4420-A160-48C7A7506C1C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{DE2E3BC5-6AB2-4420-A160-48C7A7506C1C}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{DE2E3BC5-6AB2-4420-A160-48C7A7506C1C}.Release|x86.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
@@ -12,8 +12,8 @@
|
|||||||
Topmost="True" d:DesignWidth="624" d:DesignHeight="700"
|
Topmost="True" d:DesignWidth="624" d:DesignHeight="700"
|
||||||
MinWidth="275" MinHeight="150"
|
MinWidth="275" MinHeight="150"
|
||||||
WindowStartupLocation="CenterScreen"
|
WindowStartupLocation="CenterScreen"
|
||||||
x:ClassModifier="internal" Focusable="False"
|
x:ClassModifier="internal" Focusable="False"
|
||||||
ShowActivated="False" ShowInTaskbar="False" WindowStyle="None"
|
ShowActivated="False" ShowInTaskbar="False" WindowStyle="None"
|
||||||
ResizeMode="CanResizeWithGrip" AllowsTransparency="True">
|
ResizeMode="CanResizeWithGrip" AllowsTransparency="True">
|
||||||
<Window.Background>
|
<Window.Background>
|
||||||
<SolidColorBrush Color="#DFFFFFFF" />
|
<SolidColorBrush Color="#DFFFFFFF" />
|
||||||
|
Reference in New Issue
Block a user