using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Diagnostics;
using System.Drawing;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows.Forms;
//VistaMenu 1.1, created by Wyatt O'Day
//Visit: http://wyday.com/blog/2008/vista-menu-with-icons-in-c-sharp/
namespace wyDay.Controls
{
[ProvideProperty("Image", typeof(MenuItem))]
public partial class VistaMenu : System.ComponentModel.Component, IExtenderProvider, ISupportInitialize
{
private IContainer components = null;
private Hashtable properties = new Hashtable();
private Hashtable menuParents = new Hashtable();
private bool formHasBeenIntialized = false;
private bool isVistaOrLater = false;
#region Imports
public const int MIIM_BITMAP = 0x00000080;
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern bool SetMenuItemInfo(HandleRef hMenu, int uItem, bool fByPosition, MENUITEMINFO_T_RW lpmii);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern bool SetMenuInfo(HandleRef hMenu, MENUINFO lpcmi);
[DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr hObject);
#endregion
public VistaMenu()
{
isVistaOrLater = Environment.OSVersion.Platform == PlatformID.Win32NT && Environment.OSVersion.Version.Major >= 6;
InitializeComponent();
}
public VistaMenu(System.ComponentModel.IContainer container)
: this()
{
container.Add(this);
}
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
}
///
/// Clean up any resources being used.
///
protected override void Dispose(bool disposing)
{
if (disposing)
{
//release all the HBitmap handles created
foreach (DictionaryEntry de in properties)
{
if (((Properties)de.Value).renderBmpHbitmap != IntPtr.Zero)
DeleteObject(((Properties)de.Value).renderBmpHbitmap);
}
if (components != null)
{
components.Dispose();
}
}
base.Dispose(disposing);
}
bool IExtenderProvider.CanExtend(object o)
{
if (o is MenuItem || o is Form)
return true;
else
return false;
}
private Properties EnsurePropertiesExists(MenuItem key)
{
Properties p = (Properties)properties[key];
if (p == null)
{
p = new Properties();
properties[key] = p;
}
return p;
}
#region MenuItem.Image
[Description("The Image for the MenuItem")]
[Category("Appearance")]
public Image GetImage(MenuItem mnuItem)
{
return EnsurePropertiesExists(mnuItem).Image;
}
public void SetImage(MenuItem mnuItem, Image value)
{
Properties prop = EnsurePropertiesExists(mnuItem);
prop.Image = value;
if (!DesignMode && isVistaOrLater)
{
//Destroy old bitmap object
if (prop.renderBmpHbitmap != IntPtr.Zero)
{
DeleteObject(prop.renderBmpHbitmap);
prop.renderBmpHbitmap = IntPtr.Zero;
}
//if there's no Image, then just bail out
if (value == null)
return;
//convert to 32bppPArgb (the 'P' means The red, green, and blue components are premultiplied, according to the alpha component.)
Bitmap renderBmp = new Bitmap(value.Width, value.Height, System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
Graphics g = Graphics.FromImage(renderBmp);
g.DrawImage(value, 0, 0, value.Width, value.Height);
g.Dispose();
prop.renderBmpHbitmap = renderBmp.GetHbitmap(Color.FromArgb(0, 0, 0, 0));
renderBmp.Dispose();
if (formHasBeenIntialized)
{
AddVistaMenuItem(mnuItem);
}
}
//for every Pre-Vista Windows, add the parent of the menu item to the list of parents
if (!DesignMode && !isVistaOrLater && formHasBeenIntialized)
{
AddPreVistaMenuItem(mnuItem);
}
}
private bool ShouldSerializeImage(MenuItem mnuItem)
{
if (GetImage(mnuItem) != null)
return true;
else
return false;
}
private void ResetImage(MenuItem mnuItem)
{
SetImage(mnuItem, null);
}
#endregion
void ISupportInitialize.BeginInit()
{
}
MENUINFO mnuInfo = new MENUINFO();
void AddVistaMenuItem(MenuItem mnuItem)
{
//get the bitmap children of the parent
List