Skip to content

Commit 4eef142

Browse files
committed
Improved
1 parent 15911f5 commit 4eef142

File tree

3 files changed

+18
-41
lines changed

3 files changed

+18
-41
lines changed

src/Files.App.CsWin32/Extras.cs

+2
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ public static unsafe nint SetWindowLongPtr(HWND hWnd, WINDOW_LONG_PTR_INDEX nInd
4040

4141
[DllImport("shell32.dll", EntryPoint = "SHUpdateRecycleBinIcon", CharSet = CharSet.Unicode, SetLastError = true)]
4242
public static extern void SHUpdateRecycleBinIcon();
43+
44+
public const int PixelFormat32bppARGB = 2498570;
4345
}
4446

4547
namespace Extras

src/Files.App.CsWin32/NativeMethods.txt

+3
Original file line numberDiff line numberDiff line change
@@ -219,3 +219,6 @@ DestinationList
219219
IObjectArray
220220
GetCurrentProcessExplicitAppUserModelID
221221
SetCurrentProcessExplicitAppUserModelID
222+
GdipCreateBitmapFromScan0
223+
BITMAP
224+
GetObject

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

+13-41
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright (c) Files Community
22
// Licensed under the MIT License.
33

4+
using System.Drawing;
45
using System.Collections.Concurrent;
56
using System.Runtime.InteropServices;
67
using Windows.Win32;
@@ -20,32 +21,6 @@ public static partial class WindowsStorableHelpers
2021
private static (Guid Format, Guid Encorder)[]? GdiEncoders;
2122
private static ConcurrentDictionary<(string, int, int), byte[]>? DllIconCache;
2223

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-
4924
// Methods
5025

5126
/// <inheritdoc cref="TryGetThumbnail"/>
@@ -84,48 +59,45 @@ public unsafe static HRESULT TryGetThumbnail(this IWindowsStorable storable, int
8459
}
8560

8661
// Retrieve BITMAP data
87-
BITMAP bmp = new BITMAP();
88-
if (GetObject((nint)hBitmap.Value, Marshal.SizeOf(typeof(BITMAP)), ref bmp) == 0)
62+
BITMAP bmp = default;
63+
if (PInvoke.GetObject(hBitmap, sizeof(BITMAP), &bmp) is 0)
8964
{
9065
if (!hBitmap.IsNull) PInvoke.DeleteObject(hBitmap);
9166
return HRESULT.E_FAIL;
9267
}
9368

9469
// 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;
70+
byte* flippedBits = (byte*)NativeMemory.AllocZeroed((nuint)(bmp.bmWidthBytes * bmp.bmHeight));
9871

9972
// Flip the image manually row by row
10073
for (int y = 0; y < bmp.bmHeight; y++)
10174
{
10275
Buffer.MemoryCopy(
103-
src + y * bmp.bmWidthBytes,
104-
dst + (bmp.bmHeight - y - 1) * bmp.bmWidthBytes,
76+
(byte*)bmp.bmBits + y * bmp.bmWidthBytes,
77+
flippedBits + (bmp.bmHeight - y - 1) * bmp.bmWidthBytes,
10578
bmp.bmWidthBytes,
10679
bmp.bmWidthBytes
10780
);
10881
}
10982

11083
// Create GpBitmap from the flipped pixel data
111-
IntPtr gpBitmapPtr;
112-
if (GdipCreateBitmapFromScan0(bmp.bmWidth, bmp.bmHeight, bmp.bmWidthBytes, PixelFormat32bppARGB, flippedBits, out gpBitmapPtr) != 0)
84+
GpBitmap* gpBitmap = default;
85+
if (PInvoke.GdipCreateBitmapFromScan0(bmp.bmWidth, bmp.bmHeight, bmp.bmWidthBytes, PInvoke.PixelFormat32bppARGB, flippedBits, &gpBitmap) != Status.Ok)
11386
{
114-
Marshal.FreeHGlobal(flippedBits);
87+
if (flippedBits is not null) NativeMemory.Free(flippedBits);
11588
if (!hBitmap.IsNull) PInvoke.DeleteObject(hBitmap);
11689
return HRESULT.E_FAIL;
11790
}
11891

119-
Marshal.FreeHGlobal(flippedBits);
120-
121-
GpBitmap* gpBitmap = (GpBitmap*)gpBitmapPtr;
122-
123-
if (TryConvertGpBitmapToByteArray(gpBitmap, out thumbnailData))
92+
if (!TryConvertGpBitmapToByteArray(gpBitmap, out thumbnailData))
12493
{
12594
if (!hBitmap.IsNull) PInvoke.DeleteObject(hBitmap);
12695
return HRESULT.E_FAIL;
12796
}
12897

98+
if (flippedBits is not null) NativeMemory.Free(flippedBits);
99+
if (!hBitmap.IsNull) PInvoke.DeleteObject(hBitmap);
100+
129101
return HRESULT.S_OK;
130102
}
131103

0 commit comments

Comments
 (0)