Skip to content

Commit 15911f5

Browse files
committed
Fix for icons
1 parent 6465306 commit 15911f5

File tree

1 file changed

+58
-4
lines changed

1 file changed

+58
-4
lines changed

src/Files.App.Storage/Storables/WindowsStorage/WindowsStorableHelpers.Icon.cs

+58-4
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,32 @@ public static partial class WindowsStorableHelpers
2020
private static (Guid Format, Guid Encorder)[]? GdiEncoders;
2121
private static ConcurrentDictionary<(string, int, int), byte[]>? DllIconCache;
2222

23+
private const int PixelFormat32bppARGB = 2498570; // Added constant for transparency
24+
25+
[StructLayout(LayoutKind.Sequential)]
26+
private struct BITMAP // Added BITMAP structure for bitmap operations
27+
{
28+
public int bmType;
29+
public int bmWidth;
30+
public int bmHeight;
31+
public int bmWidthBytes;
32+
public ushort bmPlanes;
33+
public ushort bmBitsPixel;
34+
public IntPtr bmBits;
35+
}
36+
37+
[DllImport("gdi32.dll", SetLastError = true)] // Added P/Invoke for GetObject
38+
private static extern int GetObject(IntPtr hObject, int nCount, ref BITMAP lpObject);
39+
40+
[DllImport("gdiplus.dll", SetLastError = true)] // Added P/Invoke for GdipCreateBitmapFromScan0
41+
private static extern int GdipCreateBitmapFromScan0(
42+
int width,
43+
int height,
44+
int stride,
45+
int pixelFormat,
46+
IntPtr scan0,
47+
out IntPtr bitmap);
48+
2349
// Methods
2450

2551
/// <inheritdoc cref="TryGetThumbnail"/>
@@ -57,15 +83,43 @@ public unsafe static HRESULT TryGetThumbnail(this IWindowsStorable storable, int
5783
return hr;
5884
}
5985

60-
// Convert to GpBitmap of GDI+
61-
GpBitmap* gpBitmap = default;
62-
if (PInvoke.GdipCreateBitmapFromHBITMAP(hBitmap, HPALETTE.Null, &gpBitmap) is not Status.Ok)
86+
// Retrieve BITMAP data
87+
BITMAP bmp = new BITMAP();
88+
if (GetObject((nint)hBitmap.Value, Marshal.SizeOf(typeof(BITMAP)), ref bmp) == 0)
6389
{
64-
if (gpBitmap is not null) PInvoke.GdipDisposeImage((GpImage*)gpBitmap);
6590
if (!hBitmap.IsNull) PInvoke.DeleteObject(hBitmap);
6691
return HRESULT.E_FAIL;
6792
}
6893

94+
// Allocate buffer for flipped pixel data
95+
IntPtr flippedBits = Marshal.AllocHGlobal(bmp.bmWidthBytes * bmp.bmHeight);
96+
byte* src = (byte*)bmp.bmBits;
97+
byte* dst = (byte*)flippedBits;
98+
99+
// Flip the image manually row by row
100+
for (int y = 0; y < bmp.bmHeight; y++)
101+
{
102+
Buffer.MemoryCopy(
103+
src + y * bmp.bmWidthBytes,
104+
dst + (bmp.bmHeight - y - 1) * bmp.bmWidthBytes,
105+
bmp.bmWidthBytes,
106+
bmp.bmWidthBytes
107+
);
108+
}
109+
110+
// Create GpBitmap from the flipped pixel data
111+
IntPtr gpBitmapPtr;
112+
if (GdipCreateBitmapFromScan0(bmp.bmWidth, bmp.bmHeight, bmp.bmWidthBytes, PixelFormat32bppARGB, flippedBits, out gpBitmapPtr) != 0)
113+
{
114+
Marshal.FreeHGlobal(flippedBits);
115+
if (!hBitmap.IsNull) PInvoke.DeleteObject(hBitmap);
116+
return HRESULT.E_FAIL;
117+
}
118+
119+
Marshal.FreeHGlobal(flippedBits);
120+
121+
GpBitmap* gpBitmap = (GpBitmap*)gpBitmapPtr;
122+
69123
if (TryConvertGpBitmapToByteArray(gpBitmap, out thumbnailData))
70124
{
71125
if (!hBitmap.IsNull) PInvoke.DeleteObject(hBitmap);

0 commit comments

Comments
 (0)