vbAccelerator - Contents of code file: SysImageList.csusing System;
using System.Drawing;
using System.Runtime.InteropServices;
namespace vbAccelerator.Components.ImageList
{
#region Public Enumerations
public enum SysImageListSize : int
{
/// <summary>
/// System Large Icon Size (typically 32x32)
/// </summary>
largeIcons = 0x0,
/// <summary>
/// System Small Icon Size (typically 16x16)
/// </summary>
smallIcons = 0x1,
/// <summary>
/// System Extra Large Icon Size (typically 48x48).
/// Only available under XP; other OS return the
/// Large Icon ImageList.
/// </summary>
extraLargeIcons = 0x2
}
[Flags]
public enum ImageListDrawItemConstants : int
{
/// <summary>
/// Draw item normally.
/// </summary>
ILD_NORMAL = 0x0,
/// <summary>
/// Draw item transparently.
/// </summary>
ILD_TRANSPARENT = 0x1,
/// <summary>
/// Draw item blended with 25% of the specified foreground colour
/// or the Highlight colour if no foreground colour specified.
/// </summary>
ILD_BLEND25 = 0x2,
/// <summary>
/// Draw item blended with 50% of the specified foreground colour
/// or the Highlight colour if no foreground colour specified.
/// </summary>
ILD_SELECTED = 0x4,
/// <summary>
/// Draw the icon's mask
/// </summary>
ILD_MASK = 0x10,
/// <summary>
/// Draw the icon image without using the mask
/// </summary>
ILD_IMAGE = 0x20,
/// <summary>
/// Draw the icon using the ROP specified.
/// </summary>
ILD_ROP = 0x40,
/// <summary>
/// ?
/// </summary>
ILD_OVERLAYMASK = 0xF00,
/// <summary>
/// Preserves the alpha channel in dest. XP only.
/// </summary>
ILD_PRESERVEALPHA = 0x1000, //
/// <summary>
/// Scale the image to cx, cy instead of clipping it. XP only.
/// </summary>
ILD_SCALE = 0x2000,
/// <summary>
/// Scale the image to the current DPI of the display. XP only.
/// </summary>
ILD_DPISCALE = 0x4000
}
#endregion
#region SysImageList
/// <summary>
/// Summary description for SysImageList.
/// </summary>
public class SysImageList : IDisposable
{
#region UnmanagedCode
private const int MAX_PATH = 260;
[DllImport("shell32")]
private static extern IntPtr SHGetFileInfo (
string pszPath,
int dwFileAttributes,
ref SHFILEINFO psfi,
uint cbFileInfo,
uint uFlags);
[DllImport("user32.dll")]
private static extern int DestroyIcon(IntPtr hIcon);
private const int FILE_ATTRIBUTE_NORMAL = 0x80;
private const int FILE_ATTRIBUTE_DIRECTORY = 0x10;
private const int FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x100;
private const int FORMAT_MESSAGE_ARGUMENT_ARRAY = 0x2000;
private const int FORMAT_MESSAGE_FROM_HMODULE = 0x800;
private const int FORMAT_MESSAGE_FROM_STRING = 0x400;
private const int FORMAT_MESSAGE_FROM_SYSTEM = 0x1000;
private const int FORMAT_MESSAGE_IGNORE_INSERTS = 0x200;
private const int FORMAT_MESSAGE_MAX_WIDTH_MASK = 0xFF;
[DllImport("kernel32")]
private extern static int FormatMessage (
int dwFlags,
IntPtr lpSource,
int dwMessageId,
int dwLanguageId,
string lpBuffer,
uint nSize,
int argumentsLong);
[DllImport("kernel32")]
private extern static int GetLastError();
[DllImport("comctl32")]
private extern static int ImageList_Draw(
IntPtr hIml,
int i,
IntPtr hdcDst,
int x,
int y,
int fStyle);
[DllImport("comctl32")]
private extern static int ImageList_DrawIndirect(
ref IMAGELISTDRAWPARAMS pimldp);
[DllImport("comctl32")]
private extern static int ImageList_GetIconSize(
IntPtr himl,
ref int cx,
ref int cy);
[DllImport("comctl32")]
private extern static IntPtr ImageList_GetIcon(
IntPtr himl,
int i,
int flags);
/// <summary>
/// SHGetImageList is not exported correctly in XP. See KB316931
/// http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q316931
/// Apparently (and hopefully) ordinal 727 isn't going to change.
/// </summary>
[DllImport("shell32.dll", EntryPoint = "#727")]
private extern static int SHGetImageList(
int iImageList,
ref Guid riid,
ref IImageList ppv
);
#endregion
#region Private Enumerations
[Flags]
private enum SHGetFileInfoConstants : int
{
SHGFI_ICON = 0x100, // get icon
SHGFI_DISPLAYNAME = 0x200, // get display name
SHGFI_TYPENAME = 0x400, // get type name
SHGFI_ATTRIBUTES = 0x800, // get attributes
SHGFI_ICONLOCATION = 0x1000, // get icon location
SHGFI_EXETYPE = 0x2000, // return exe type
SHGFI_SYSICONINDEX = 0x4000, // get system icon index
SHGFI_LINKOVERLAY = 0x8000, // put a link overlay on icon
SHGFI_SELECTED = 0x10000, // show icon in selected state
SHGFI_ATTR_SPECIFIED = 0x20000, // get only specified attributes
SHGFI_LARGEICON = 0x0, // get large icon
SHGFI_SMALLICON = 0x1, // get small icon
SHGFI_OPENICON = 0x2, // get open icon
SHGFI_SHELLICONSIZE = 0x4, // get shell size icon
//SHGFI_PIDL = 0x8, // pszPath is a pidl
SHGFI_USEFILEATTRIBUTES = 0x10, // use passed dwFileAttribute
SHGFI_ADDOVERLAYS = 0x000000020, // apply the appropriate overlays
SHGFI_OVERLAYINDEX = 0x000000040 // Get the index of the overlay
}
#endregion
#region Private ImageList structures
[StructLayout(LayoutKind.Sequential)]
private struct RECT
{
int left;
int top;
int right;
int bottom;
}
[StructLayout(LayoutKind.Sequential)]
private struct POINT
{
int x;
int y;
}
[StructLayout(LayoutKind.Sequential)]
private struct IMAGELISTDRAWPARAMS
{
public int cbSize;
public IntPtr himl;
public int i;
public IntPtr hdcDst;
public int x;
public int y;
public int cx;
public int cy;
public int xBitmap; // x offest from the upperleft of bitmap
public int yBitmap; // y offset from the upperleft of bitmap
public int rgbBk;
public int rgbFg;
public int fStyle;
public int dwRop;
public int fState;
public int Frame;
public int crEffect;
}
[StructLayout(LayoutKind.Sequential)]
private struct IMAGEINFO
{
public IntPtr hbmImage;
public IntPtr hbmMask;
public int Unused1;
public int Unused2;
public RECT rcImage;
}
[StructLayout(LayoutKind.Sequential)]
private struct SHFILEINFO
{
public IntPtr hIcon;
public int iIcon;
public int dwAttributes;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=MAX_PATH)]
public string szDisplayName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=80)]
public string szTypeName;
}
#endregion
#region Private ImageList COM Interop (XP)
[ComImportAttribute()]
[GuidAttribute("46EB5926-582E-4017-9FDF-E8998DAA0950")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
//helpstring("Image List"),
interface IImageList
{
[PreserveSig]
int Add(
IntPtr hbmImage,
IntPtr hbmMask,
ref int pi);
[PreserveSig]
int ReplaceIcon(
int i,
IntPtr hicon,
ref int pi);
[PreserveSig]
int SetOverlayImage(
int iImage,
int iOverlay);
[PreserveSig]
int Replace(
int i,
IntPtr hbmImage,
IntPtr hbmMask);
[PreserveSig]
int AddMasked(
IntPtr hbmImage,
int crMask,
ref int pi);
[PreserveSig]
int Draw(
ref IMAGELISTDRAWPARAMS pimldp);
[PreserveSig]
int Remove(
int i);
[PreserveSig]
int GetIcon(
int i,
int flags,
ref IntPtr picon);
[PreserveSig]
int GetImageInfo(
int i,
ref IMAGEINFO pImageInfo);
[PreserveSig]
int Copy(
int iDst,
IImageList punkSrc,
int iSrc,
int uFlags);
[PreserveSig]
int Merge(
int i1,
IImageList punk2,
int i2,
int dx,
int dy,
ref Guid riid,
ref IntPtr ppv);
[PreserveSig]
int Clone(
ref Guid riid,
ref IntPtr ppv);
[PreserveSig]
int GetImageRect(
int i,
ref RECT prc);
[PreserveSig]
int GetIconSize(
ref int cx,
ref int cy);
[PreserveSig]
int SetIconSize(
int cx,
int cy);
[PreserveSig]
int GetImageCount(
ref int pi);
[PreserveSig]
int SetImageCount(
int uNewCount);
[PreserveSig]
int SetBkColor(
int clrBk,
ref int pclr);
[PreserveSig]
int GetBkColor(
ref int pclr);
[PreserveSig]
int BeginDrag(
int iTrack,
int dxHotspot,
int dyHotspot);
[PreserveSig]
int EndDrag();
[PreserveSig]
int DragEnter(
IntPtr hwndLock,
int x,
int y);
[PreserveSig]
int DragLeave(
IntPtr hwndLock);
[PreserveSig]
int DragMove(
int x,
int y);
[PreserveSig]
int SetDragCursorImage(
ref IImageList punk,
int iDrag,
int dxHotspot,
int dyHotspot);
[PreserveSig]
int DragShowNolock(
int fShow);
[PreserveSig]
int GetDragImage(
ref POINT ppt,
ref POINT pptHotspot,
ref Guid riid,
ref IntPtr ppv);
[PreserveSig]
int GetItemFlags(
int i,
ref int dwFlags);
[PreserveSig]
int GetOverlayImage(
int iOverlay,
ref int piIndex);
};
#endregion
#region Member Variables
private IntPtr hIml = IntPtr.Zero;
private IImageList iImageList = null;
private SysImageListSize size = SysImageListSize.smallIcons;
private bool disposed = false;
#endregion
#region Implementation
#region Properties
/// <summary>
/// Gets/sets the size of System Image List to retrieve.
/// </summary>
public SysImageListSize ImageListSize
{
get
{
return size;
}
set
{
size = value;
create();
}
}
/// <summary>
/// Returns the size of the Image List Icons.
/// </summary>
public System.Drawing.Size Size
{
get
{
int cx = 0;
int cy = 0;
if (iImageList == null)
{
ImageList_GetIconSize(
hIml,
ref cx,
ref cy);
}
else
{
iImageList.GetIconSize(ref cx, ref cy);
}
System.Drawing.Size sz = new System.Drawing.Size(
cx, cy);
return sz;
}
}
#endregion
#region Methods
/// <summary>
/// Returns a GDI+ copy of the icon from the ImageList
/// at the specified index.
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
public Icon Icon(int index)
{
Icon icon = null;
IntPtr hIcon = IntPtr.Zero;
if (iImageList == null)
{
hIcon = ImageList_GetIcon(
hIml,
index,
(int)ImageListDrawItemConstants.ILD_TRANSPARENT);
}
else
{
iImageList.GetIcon(
index,
(int)ImageListDrawItemConstants.ILD_TRANSPARENT,
ref hIcon);
}
if (hIcon != IntPtr.Zero)
{
icon = System.Drawing.Icon.FromHandle(hIcon);
}
return icon;
}
/// <summary>
/// Return the index of the icon for the specified file, always using
/// the cached version where possible.
/// </summary>
/// <param name="fileName">Filename to get icon for</param>
/// <returns></returns>
public int IconIndex(string fileName)
{
return IconIndex(fileName, false);
}
/// <summary>
/// Returns the index of the icon for the specified file
/// </summary>
/// <param name="fileName">Filename to get icon for</param>
/// <param name="forceLoadFromDisk">If True, then hit the disk to get the
icon,
/// otherwise only hit the disk if no cached icon is available.</param>
/// <returns></returns>
public int IconIndex(string fileName, bool forceLoadFromDisk)
{
SHGetFileInfoConstants dwFlags =
SHGetFileInfoConstants.SHGFI_SYSICONINDEX;
int dwAttr = 0;
if (size == SysImageListSize.smallIcons)
{
dwFlags |= SHGetFileInfoConstants.SHGFI_SMALLICON;
}
// We can choose whether to access the disk or not. If you don't
// hit the disk, you may get the wrong icon if the icon is
// not cached. But the speed is very good!
if (!forceLoadFromDisk)
{
dwFlags |= SHGetFileInfoConstants.SHGFI_USEFILEATTRIBUTES;
dwAttr = FILE_ATTRIBUTE_NORMAL;
}
else
{
dwAttr = 0;
}
// sFileSpec can be any file. You can specify a
// file that does not exist and still get the
// icon, for example sFileSpec = "C:\PANTS.DOC"
SHFILEINFO shfi = new SHFILEINFO();
uint shfiSize = (uint)Marshal.SizeOf(shfi.GetType());
IntPtr retVal = SHGetFileInfo(
fileName, dwAttr, ref shfi, shfiSize,
(uint)dwFlags);
if (retVal.Equals(IntPtr.Zero))
{
System.Diagnostics.Debug.Assert((!retVal.Equals(IntPtr.Zero)),"Faile
d to get icon index");
return 0;
}
else
{
return shfi.iIcon;
}
}
/// <summary>
/// Draws an image
/// </summary>
/// <param name="hdc">Device context to draw to</param>
/// <param name="index">Index of image to draw</param>
/// <param name="x">X Position to draw at</param>
/// <param name="y">Y Position to draw at</param>
public void DrawImage(
IntPtr hdc,
int index,
int x,
int y
)
{
DrawImage(hdc, index, x, y,
ImageListDrawItemConstants.ILD_TRANSPARENT);
}
/// <summary>
/// Draws an image using the specified flags
/// </summary>
/// <param name="hdc">Device context to draw to</param>
/// <param name="index">Index of image to draw</param>
/// <param name="x">X Position to draw at</param>
/// <param name="y">Y Position to draw at</param>
/// <param name="flags">Drawing flags</param>
public void DrawImage(
IntPtr hdc,
int index,
int x,
int y,
ImageListDrawItemConstants flags
)
{
if (iImageList == null)
{
int ret = ImageList_Draw(
hIml,
index,
hdc,
x,
y,
(int)flags);
}
else
{
IMAGELISTDRAWPARAMS pimldp = new IMAGELISTDRAWPARAMS();
pimldp.hdcDst = hdc;
pimldp.cbSize = Marshal.SizeOf(pimldp.GetType());
pimldp.i = index;
pimldp.x = x;
pimldp.y = y;
pimldp.fStyle = (int)flags;
iImageList.Draw(ref pimldp);
}
}
/// <summary>
/// Draws an image using the specified flags
/// </summary>
/// <param name="hdc">Device context to draw to</param>
/// <param name="index">Index of image to draw</param>
/// <param name="x">X Position to draw at</param>
/// <param name="y">Y Position to draw at</param>
/// <param name="flags">Drawing flags</param>
/// <param name="cx">Width to draw</param>
/// <param name="cy">Height to draw</param>
public void DrawImage(
IntPtr hdc,
int index,
int x,
int y,
ImageListDrawItemConstants flags,
int cx,
int cy
)
{
IMAGELISTDRAWPARAMS pimldp = new IMAGELISTDRAWPARAMS();
pimldp.hdcDst = hdc;
pimldp.cbSize = Marshal.SizeOf(pimldp.GetType());
pimldp.i = index;
pimldp.x = x;
pimldp.y = y;
pimldp.cx = cx;
pimldp.cy = cy;
pimldp.fStyle = (int)flags;
if (iImageList == null)
{
int ret = ImageList_DrawIndirect(ref pimldp);
}
else
{
iImageList.Draw(ref pimldp);
}
}
/// <summary>
/// Determines if the system is running Windows XP
/// or above
/// </summary>
/// <returns>True if system is running XP or above, False
otherwise</returns>
private bool isXpOrAbove()
{
bool ret = false;
if (Environment.OSVersion.Version.Major > 5)
{
ret = true;
}
else if ((Environment.OSVersion.Version.Major == 5) &&
(Environment.OSVersion.Version.Minor >= 1))
{
ret = true;
}
return ret;
}
/// <summary>
/// Creates the SystemImageList
/// </summary>
private void create()
{
// forget last image list if any:
hIml = IntPtr.Zero;
if (isXpOrAbove())
{
Guid iidImageList = new
Guid("46EB5926-582E-4017-9FDF-E8998DAA0950");
int ret = SHGetImageList(
(int)size,
ref iidImageList,
ref iImageList
);
}
else
{
// Prepare flags:
SHGetFileInfoConstants dwFlags =
SHGetFileInfoConstants.SHGFI_USEFILEATTRIBUTES |
SHGetFileInfoConstants.SHGFI_SYSICONINDEX ;
if (size == SysImageListSize.smallIcons)
{
dwFlags |= SHGetFileInfoConstants.SHGFI_SMALLICON;
}
// Get image list
SHFILEINFO shfi = new SHFILEINFO();
uint shfiSize = (uint)Marshal.SizeOf(shfi.GetType());
hIml = SHGetFileInfo(".txt", FILE_ATTRIBUTE_NORMAL, ref shfi,
shfiSize, (uint)dwFlags);
System.Diagnostics.Debug.Assert ((hIml != IntPtr.Zero),"Failed to
create Image List");
}
}
/// <summary>
/// Gets the hImageList handle
/// </summary>
public IntPtr Handle
{
get
{
if (iImageList == null)
{
return this.hIml;
}
else
{
return Marshal.GetIUnknownForObject(
iImageList);
}
}
}
#endregion
#region Constructor, Dispose, Destructor
/// <summary>
/// Creates a Small Icons SystemImageList
/// </summary>
public SysImageList()
{
create();
}
/// <summary>
/// Creates a SystemImageList with the specified size
/// </summary>
/// <param name="size">Size of System ImageList</param>
public SysImageList(SysImageListSize size)
{
this.size = size;
create();
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
public virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
if (iImageList != null)
{
Marshal.ReleaseComObject(iImageList);
}
iImageList = null;
}
}
disposed = true;
}
~SysImageList()
{
Dispose(false);
}
}
#endregion
#endregion
#endregion
}
|
|