|
5 | 5 | using System.Collections.Generic;
|
6 | 6 | using System.Diagnostics;
|
7 | 7 | using System.Drawing;
|
| 8 | +using System.Drawing.Imaging; |
8 | 9 | using System.Linq;
|
9 | 10 | using System.Runtime.InteropServices;
|
10 | 11 | using System.Threading;
|
@@ -255,7 +256,7 @@ private static void EnumMenuItems(
|
255 | 256 | }
|
256 | 257 | if (mii.hbmpItem != HBITMAP.NULL)
|
257 | 258 | {
|
258 |
| - var bitmap = GetItemBitmap(mii.hbmpItem); |
| 259 | + var bitmap = GetBitmapFromHBitmap(mii.hbmpItem); |
259 | 260 | menuItem.Icon = bitmap;
|
260 | 261 | }
|
261 | 262 | if (mii.hSubMenu != HMENU.NULL)
|
@@ -317,31 +318,57 @@ private static string GetCommandString(Shell32.IContextMenu cMenu, uint offset,
|
317 | 318 | }
|
318 | 319 | }
|
319 | 320 |
|
320 |
| - private static Bitmap GetItemBitmap(HBITMAP hbitmap) |
| 321 | + private static Bitmap GetBitmapFromHBitmap(HBITMAP hBitmap) |
321 | 322 | {
|
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; |
325 | 332 | }
|
326 | 333 |
|
327 |
| - private static Bitmap GetTransparentBitmap(HBITMAP hbitmap) |
| 334 | + private static Bitmap GetAlphaBitmapFromBitmapData(BitmapData bmpData) |
328 | 335 | {
|
| 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 | + |
329 | 350 | try
|
330 | 351 | {
|
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++) |
336 | 355 | {
|
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 | + } |
340 | 363 | }
|
341 |
| - return bitmap; |
| 364 | + } |
342 | 365 | }
|
343 |
| - catch { } |
344 |
| - return Image.FromHbitmap((IntPtr)hbitmap); |
| 366 | + finally |
| 367 | + { |
| 368 | + bmp.UnlockBits(bmpData); |
| 369 | + } |
| 370 | + |
| 371 | + return false; |
345 | 372 | }
|
346 | 373 |
|
347 | 374 | #region IDisposable Support
|
|
0 commit comments