Skip to content

Commit 6012c81

Browse files
authored
Fixed flipped context menu icons (e.g winrar) (#2141)
1 parent 75d73b1 commit 6012c81

File tree

1 file changed

+44
-17
lines changed

1 file changed

+44
-17
lines changed

Files.Launcher/Win32API_ContextMenu.cs

Lines changed: 44 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Collections.Generic;
66
using System.Diagnostics;
77
using System.Drawing;
8+
using System.Drawing.Imaging;
89
using System.Linq;
910
using System.Runtime.InteropServices;
1011
using System.Threading;
@@ -255,7 +256,7 @@ private static void EnumMenuItems(
255256
}
256257
if (mii.hbmpItem != HBITMAP.NULL)
257258
{
258-
var bitmap = GetItemBitmap(mii.hbmpItem);
259+
var bitmap = GetBitmapFromHBitmap(mii.hbmpItem);
259260
menuItem.Icon = bitmap;
260261
}
261262
if (mii.hSubMenu != HMENU.NULL)
@@ -317,31 +318,57 @@ private static string GetCommandString(Shell32.IContextMenu cMenu, uint offset,
317318
}
318319
}
319320

320-
private static Bitmap GetItemBitmap(HBITMAP hbitmap)
321+
private static Bitmap GetBitmapFromHBitmap(HBITMAP hBitmap)
321322
{
322-
var bitmap = GetTransparentBitmap(hbitmap);
323-
bitmap.RotateFlip(RotateFlipType.Rotate270FlipNone);
324-
return bitmap;
323+
Bitmap bmp = hBitmap.ToBitmap();
324+
325+
if (Bitmap.GetPixelFormatSize(bmp.PixelFormat) < 32)
326+
return bmp;
327+
328+
if (IsAlphaBitmap(bmp, out var bmpData))
329+
return GetAlphaBitmapFromBitmapData(bmpData);
330+
331+
return bmp;
325332
}
326333

327-
private static Bitmap GetTransparentBitmap(HBITMAP hbitmap)
334+
private static Bitmap GetAlphaBitmapFromBitmapData(BitmapData bmpData)
328335
{
336+
return new Bitmap(
337+
bmpData.Width,
338+
bmpData.Height,
339+
bmpData.Stride,
340+
PixelFormat.Format32bppArgb,
341+
bmpData.Scan0);
342+
}
343+
344+
private static bool IsAlphaBitmap(Bitmap bmp, out BitmapData bmpData)
345+
{
346+
Rectangle bmBounds = new Rectangle(0, 0, bmp.Width, bmp.Height);
347+
348+
bmpData = bmp.LockBits(bmBounds, ImageLockMode.ReadOnly, bmp.PixelFormat);
349+
329350
try
330351
{
331-
var dibsection = GetObject<BITMAP>(hbitmap);
332-
var bitmap = new Bitmap(dibsection.bmWidth, dibsection.bmHeight, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
333-
using var mstr = new NativeMemoryStream(dibsection.bmBits, dibsection.bmBitsPixel * dibsection.bmHeight * dibsection.bmWidth);
334-
for (var x = 0; x < dibsection.bmWidth; x++)
335-
for (var y = 0; y < dibsection.bmHeight; y++)
352+
for (int y = 0; y <= bmpData.Height - 1; y++)
353+
{
354+
for (int x = 0; x <= bmpData.Width - 1; x++)
336355
{
337-
var rgbquad = mstr.Read<RGBQUAD>();
338-
if (rgbquad.rgbReserved != 0)
339-
bitmap.SetPixel(x, y, rgbquad.Color);
356+
Color pixelColor = Color.FromArgb(
357+
Marshal.ReadInt32(bmpData.Scan0, (bmpData.Stride * y) + (4 * x)));
358+
359+
if (pixelColor.A > 0 & pixelColor.A < 255)
360+
{
361+
return true;
362+
}
340363
}
341-
return bitmap;
364+
}
342365
}
343-
catch { }
344-
return Image.FromHbitmap((IntPtr)hbitmap);
366+
finally
367+
{
368+
bmp.UnlockBits(bmpData);
369+
}
370+
371+
return false;
345372
}
346373

347374
#region IDisposable Support

0 commit comments

Comments
 (0)