DeskCore 1.0.0
Desktop-Icons in eigene Kategorien sortieren: Windows-11-Design (hell/dunkel), Desktop-Boxen, automatisches Einsortieren nach Regeln, Rückgängig, Suche, Infobereich mit Tastenkürzel, Sicherung als ZIP und Installer ohne Adminrechte. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+100
@@ -0,0 +1,100 @@
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
|
||||
namespace DeskCore;
|
||||
|
||||
/// <summary>Holt das Icon (bzw. Vorschaubild) einer Datei so, wie der Explorer es anzeigt.</summary>
|
||||
public static class ShellIcon
|
||||
{
|
||||
public static ImageSource? Get(string path, int size = 64)
|
||||
{
|
||||
IntPtr hbm = IntPtr.Zero;
|
||||
try
|
||||
{
|
||||
SHCreateItemFromParsingName(path, IntPtr.Zero, typeof(IShellItemImageFactory).GUID, out var factory);
|
||||
int hr = factory.GetImage(new SIZE { cx = size, cy = size }, 0, out hbm);
|
||||
Marshal.ReleaseComObject(factory);
|
||||
if (hr != 0 || hbm == IntPtr.Zero) return null;
|
||||
return FromHBitmap(hbm);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (hbm != IntPtr.Zero) DeleteObject(hbm);
|
||||
}
|
||||
}
|
||||
|
||||
// CreateBitmapSourceFromHBitmap verliert den Alphakanal, daher Pixel selbst kopieren.
|
||||
private static BitmapSource? FromHBitmap(IntPtr hbm)
|
||||
{
|
||||
GetObject(hbm, Marshal.SizeOf<BITMAP>(), out BITMAP bm);
|
||||
int w = bm.bmWidth, h = Math.Abs(bm.bmHeight);
|
||||
if (w <= 0 || h <= 0) return null;
|
||||
|
||||
var bmi = new BITMAPINFOHEADER
|
||||
{
|
||||
biSize = Marshal.SizeOf<BITMAPINFOHEADER>(),
|
||||
biWidth = w,
|
||||
biHeight = -h, // top-down
|
||||
biPlanes = 1,
|
||||
biBitCount = 32,
|
||||
};
|
||||
var bits = new byte[w * h * 4];
|
||||
IntPtr hdc = GetDC(IntPtr.Zero);
|
||||
try
|
||||
{
|
||||
if (GetDIBits(hdc, hbm, 0, (uint)h, bits, ref bmi, 0) == 0) return null;
|
||||
}
|
||||
finally
|
||||
{
|
||||
ReleaseDC(IntPtr.Zero, hdc);
|
||||
}
|
||||
|
||||
bool hasAlpha = false;
|
||||
for (int i = 3; i < bits.Length; i += 4)
|
||||
if (bits[i] != 0) { hasAlpha = true; break; }
|
||||
|
||||
var src = BitmapSource.Create(w, h, 96, 96, hasAlpha ? PixelFormats.Pbgra32 : PixelFormats.Bgr32, null, bits, w * 4);
|
||||
src.Freeze();
|
||||
return src;
|
||||
}
|
||||
|
||||
[ComImport, Guid("bcc18b79-ba16-442f-80c4-8a59c30c463b"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
private interface IShellItemImageFactory
|
||||
{
|
||||
[PreserveSig] int GetImage(SIZE size, int flags, out IntPtr phbm);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private struct SIZE { public int cx, cy; }
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private struct BITMAP
|
||||
{
|
||||
public int bmType, bmWidth, bmHeight, bmWidthBytes;
|
||||
public ushort bmPlanes, bmBitsPixel;
|
||||
public IntPtr bmBits;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private struct BITMAPINFOHEADER
|
||||
{
|
||||
public int biSize, biWidth, biHeight;
|
||||
public ushort biPlanes, biBitCount;
|
||||
public int biCompression, biSizeImage, biXPelsPerMeter, biYPelsPerMeter, biClrUsed, biClrImportant;
|
||||
}
|
||||
|
||||
[DllImport("shell32.dll", CharSet = CharSet.Unicode, PreserveSig = false)]
|
||||
private static extern void SHCreateItemFromParsingName(string path, IntPtr pbc,
|
||||
[MarshalAs(UnmanagedType.LPStruct)] Guid riid, out IShellItemImageFactory ppv);
|
||||
|
||||
[DllImport("gdi32.dll")] private static extern bool DeleteObject(IntPtr h);
|
||||
[DllImport("gdi32.dll")] private static extern int GetObject(IntPtr h, int size, out BITMAP bm);
|
||||
[DllImport("gdi32.dll")] private static extern int GetDIBits(IntPtr hdc, IntPtr hbm, uint start, uint lines, byte[] bits, ref BITMAPINFOHEADER bmi, uint usage);
|
||||
[DllImport("user32.dll")] private static extern IntPtr GetDC(IntPtr hwnd);
|
||||
[DllImport("user32.dll")] private static extern int ReleaseDC(IntPtr hwnd, IntPtr hdc);
|
||||
}
|
||||
Reference in New Issue
Block a user