imagelist_setoverlayimage (comctl32)
Last changed: -174.27.67.128

.
Summary
Adds a specified image to the list of images to be used as overlay masks.

C# Signature:

[DllImport("comctl32.dll", SetLastError=true)]
static extern bool ImageList_SetOverlayImage(IntPtr hImageList, int iImage, int iOverlay);

VB Signature:

<DllImport("comctl32.dll", SetLastError := True)> _
Private Shared Function ImageList_SetOverlayImage(hImageList As IntPtr, iImage As Integer, iOverlay As Integer) As Boolean
End Function

User-Defined Types:

None.

Alternative Managed API:

using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.InteropServices;

namespace Microsoft.Win32
{
    internal static partial class NativeMethods
    {
       public const uint CLR_NONE = 0xFFFFFFFF;
       public const uint CLR_DEFAULT = 0xFF000000;

       [Flags]
       public enum ImageListDrawingStyle : uint
       {
      Normal = 0x00000000,
      Transparent = 0x00000001,
      Blend25 = 0x00000002,
      Blend50 = 0x00000004,
      Mask = 0x00000010,
      Image = 0x00000020,
      Rop = 0x00000040,
      OverlayMask = 0x00000F00,
      PreserveAlpha = 0x00001000, // This preserves the alpha channel in dest
      Scale = 0x00002000, // Causes the image to be scaled to cx, cy instead of clipped
      DpiScale = 0x00004000,
      Async = 0x00008000,
       }

       [DllImport("comctl32.dll", SetLastError = true)]
       [return: MarshalAs(UnmanagedType.Bool)]
       public extern static bool ImageList_SetOverlayImage(IntPtr himl, int iImage, int iOverlay);

       [DllImport("comctl32.dll", SetLastError = true)]
       [return: MarshalAs(UnmanagedType.Bool)]
       public extern static bool ImageList_DrawEx(IntPtr himl, int i, IntPtr hdcDst, int x, int y, int dx, int dy, uint rgbBk, uint rgbFg, ImageListDrawingStyle fStyle);
    }
}

namespace System.Windows.Forms
{
    internal static class ImageListExtension
    {
       private static Dictionary<ImageList, List<int>> imageListOverlays = new Dictionary<ImageList, List<int>>();

       /// <summary>
       /// Draw color with options for <see cref="Draw"/> method.
       /// </summary>
       public struct ImageListDrawColor
       {
      private uint value;
      public ImageListDrawColor(Color color) { value = (uint)ColorTranslator.ToWin32(color); }
      private ImageListDrawColor(uint val) { value = val; }
      public static ImageListDrawColor None = new ImageListDrawColor(NativeMethods.CLR_NONE);
      public static ImageListDrawColor Default = new ImageListDrawColor(NativeMethods.CLR_DEFAULT);
      public static implicit operator uint(ImageListDrawColor c) { return c.value; }
      public static implicit operator ImageListDrawColor(Color c) { return new ImageListDrawColor(c); }
       }

       /// <summary>
       /// Draws the image indicated by the given index on the specified <see cref="Graphics"/> at the specified location.
       /// </summary>
       /// <param name="imageList">The image list.</param>
       /// <param name="g">The <see cref="Graphics"/> to draw on.</param>
       /// <param name="bounds">The bounds in which to draw the image. Set width and height to 0 to draw image at full size.</param>
       /// <param name="index">The index of the image in the ImageList to draw.</param>
       /// <param name="bgColor">The background color of the image. This parameter can be a <see cref="Color"/> value or <see cref="ImageListDrawColor.None"/>
       /// so the image is drawn transparently or <see cref="ImageListDrawColor.Default"/> so the image is drawn using the background color of the image list.</param>
       /// <param name="fgColor">The foreground color of the image. This parameter can be a <see cref="Color"/> value or <see cref="ImageListDrawColor.None"/>
       /// so the image is blended with the color of the destination device context or <see cref="ImageListDrawColor.Default"/> so the image is drawn using the system highlight color as the foreground color.</param>
       /// <param name="style">The drawing style.</param>
       /// <param name="overlayImageIndex">Optional index of an overlay image.</param>
       /// <exception cref="System.ComponentModel.Win32Exception">Unable to draw the image with defined parameters.</exception>
       public static void Draw(this ImageList imageList, Graphics g, Rectangle bounds, int index, ImageListDrawColor bgColor, ImageListDrawColor fgColor, NativeMethods.ImageListDrawingStyle style = NativeMethods.ImageListDrawingStyle.Normal, int overlayImageIndex = 0)
       {
      if (index < 0 || index >= imageList.Images.Count)
         throw new ArgumentOutOfRangeException("index");
      if (overlayImageIndex < 0 || overlayImageIndex > imageList.GetOverlayCount())
         throw new ArgumentOutOfRangeException("overlayImageIndex");
      using (var hg = new SafeGDIHandle(g))
         if (!NativeMethods.ImageList_DrawEx(imageList.Handle, index, hg, bounds.X, bounds.Y, bounds.Width, bounds.Height, bgColor, fgColor, style | (NativeMethods.ImageListDrawingStyle)(overlayImageIndex << 8)))
        throw new Win32Exception();
       }

       private static int GetOverlayCount(this ImageList imageList)
       {
      List<int> vals;
      if (!imageListOverlays.TryGetValue(imageList, out vals))
         return 0;
      return vals.Count;
       }

       /// <summary>
       /// Assigns the image at the specified index as an overlay and returns is overlay index.
       /// </summary>
       /// <param name="imageList">The image list.</param>
       /// <param name="imageIndex">Index of the image within the ImageList.</param>
       /// <returns>The 1 based index of the overlay.</returns>
       /// <exception cref="System.ArgumentOutOfRangeException">The imageIndex is not in the current list.</exception>
       /// <exception cref="System.ComponentModel.Win32Exception">The image cannot be added as an overlay.</exception>
       public static int SetImageIndexAsOverlay(this ImageList imageList, int imageIndex)
       {
      if (imageIndex < 0 || imageIndex >= imageList.Images.Count)
         throw new ArgumentOutOfRangeException("imageIndex");
      List<int> vals;
      if (!imageListOverlays.TryGetValue(imageList, out vals))
      {
         imageList.RecreateHandle += imageList_RecreateHandle;
         imageListOverlays.Add(imageList, vals = new List<int>(15));
      }
      vals.Add(imageIndex);
      int overlayIndex = vals.Count;
      if (!NativeMethods.ImageList_SetOverlayImage(imageList.Handle, imageIndex, overlayIndex))
         throw new Win32Exception();
      return overlayIndex;
       }

       /// <summary>
       /// Adds the specified image to the ImageList as an overlay, using the specified color to determine transparency.
       /// </summary>
       /// <param name="imageList">The image list.</param>
       /// <param name="value">A Bitmap of the image to add to the list.</param>
       /// <param name="transparentColor">The color to use as the transparent color within the Bitmap.</param>
       /// <returns>The 1 based index of the overlay.</returns>
       /// <exception cref="System.ComponentModel.Win32Exception">The image cannot be added as an overlay.</exception>
       public static int AddOverlay(this ImageList imageList, Image value, Color transparentColor)
       {
      int idx = imageList.Images.Add(value, transparentColor);
      return SetImageIndexAsOverlay(imageList, idx);
       }

       private static void imageList_RecreateHandle(object sender, EventArgs e)
       {
      List<int> vals;
      if (imageListOverlays.TryGetValue(sender as ImageList, out vals))
      {
         for (int i = 0; i < vals.Count; i++)
        NativeMethods.ImageList_SetOverlayImage(((ImageList)sender).Handle, vals[i], i + 1);
      }
       }
    }
}

Notes:

None.

Tips & Tricks:

Please add some!

Sample Code:

Please add some!

Documentation