@@ -20,6 +20,32 @@ public static partial class WindowsStorableHelpers
20
20
private static ( Guid Format , Guid Encorder ) [ ] ? GdiEncoders ;
21
21
private static ConcurrentDictionary < ( string , int , int ) , byte [ ] > ? DllIconCache ;
22
22
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
+
23
49
// Methods
24
50
25
51
/// <inheritdoc cref="TryGetThumbnail"/>
@@ -57,15 +83,43 @@ public unsafe static HRESULT TryGetThumbnail(this IWindowsStorable storable, int
57
83
return hr ;
58
84
}
59
85
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 )
63
89
{
64
- if ( gpBitmap is not null ) PInvoke . GdipDisposeImage ( ( GpImage * ) gpBitmap ) ;
65
90
if ( ! hBitmap . IsNull ) PInvoke . DeleteObject ( hBitmap ) ;
66
91
return HRESULT . E_FAIL ;
67
92
}
68
93
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
+
69
123
if ( TryConvertGpBitmapToByteArray ( gpBitmap , out thumbnailData ) )
70
124
{
71
125
if ( ! hBitmap . IsNull ) PInvoke . DeleteObject ( hBitmap ) ;
0 commit comments