Setting custom toolwindow icon for Visual Studio add-in
Posted on : 12-08-2009 | By : Utkarsh Shigihalli | In : .net, programming, vsx
0
I recently completed a minor update to my Favorites Menu for Visual Studio add-in. The new installer is already put under ‘My Development’ section on my site.
The update includes a minor bug fix i.e, toolwindow icon is not set properly inside Visual Studio 2008. I do not remember from where I got the following code, but this worked for me.
Paste the below code in to a Utililty.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 | public class MyIcon { private static Color GuessTransparentColor(Bitmap bitmap) { Color pixel = bitmap.GetPixel(0, 0); Color color2 = bitmap.GetPixel(bitmap.Width - 1, 0); Color color3 = bitmap.GetPixel(0, bitmap.Height - 1); Color color4 = bitmap.GetPixel(bitmap.Width - 1, bitmap.Height - 1); if (pixel == color2) { return pixel; } if (color2 == color3) { return color2; } if (color3 == color4) { return color3; } return color4; } public static Bitmap PrepareImage(Image image, Color transparentColor) { Bitmap bitmap = new Bitmap(image); Bitmap bitmap2 = new Bitmap(0x10, 0x10, PixelFormat.Format24bppRgb); Color color = guessTransparentColor(bitmap); for (int i = 0; i < bitmap2.Width; i++) { for (int j = 0; j < bitmap2.Height; j++) { Color baseColor = color; if ((i < bitmap.Width) && (j < bitmap.Height)) { baseColor = bitmap.GetPixel(i, j); } baseColor = Color.FromArgb(0xff, baseColor); if (baseColor != color) { bitmap2.SetPixel(i, j, baseColor); } else if ((transparentColor != color) && (baseColor == transparentColor)) { if (baseColor.R > 0) { bitmap2.SetPixel(i, j, Color.FromArgb(baseColor.R - 1, baseColor.G, baseColor.B)); } else { bitmap2.SetPixel(i, j, Color.FromArgb(baseColor.R + 1, baseColor.G, baseColor.B)); } } else { bitmap2.SetPixel(i, j, transparentColor); } } } return bitmap2; } public static Bitmap PrepareImage(Bitmap image, Color transparentColor) { Bitmap bitmap = new Bitmap(image); Bitmap bitmap2 = new Bitmap(0x10, 0x10, PixelFormat.Format24bppRgb); Color color = guessTransparentColor(bitmap); for (int i = 0; i < bitmap2.Width; i++) { for (int j = 0; j < bitmap2.Height; j++) { Color baseColor = color; if ((i < bitmap.Width) && (j < bitmap.Height)) { baseColor = bitmap.GetPixel(i, j); } baseColor = Color.FromArgb(0xff, baseColor); if (baseColor != color) { bitmap2.SetPixel(i, j, baseColor); } else if ((transparentColor != color) && (baseColor == transparentColor)) { if (baseColor.R > 0) { bitmap2.SetPixel(i, j, Color.FromArgb(baseColor.R - 1, baseColor.G, baseColor.B)); } else { bitmap2.SetPixel(i, j, Color.FromArgb(baseColor.R + 1, baseColor.G, baseColor.B)); } } else { bitmap2.SetPixel(i, j, transparentColor); } } } return bitmap2; } public static Bitmap PrepareMask(Image image) { Bitmap bitmap = new Bitmap(image); Bitmap bitmap2 = new Bitmap(0x10, 0x10, PixelFormat.Format24bppRgb); Color color = guessTransparentColor(bitmap); for (int i = 0; i < image.Width; i++) { for (int j = 0; j < image.Height; j++) { Color pixel = bitmap.GetPixel(i, j); Color color3 = ((pixel == color) || (pixel.A < 0xff)) ? Color.White : Color.Black; bitmap2.SetPixel(i, j, color3); } } return bitmap2; } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] private struct SHFILEINFO { public IntPtr hIcon; public int iIcon; public int dwAttributes; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x100)] public char[] szDisplayName; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 80)] public char[] szTypeName; } public static Icon GetIconFromFile(string path) { SHFILEINFO psfi = new SHFILEINFO(); SHGetFileInfo(path, 0x80, ref psfi, Marshal.SizeOf(psfi), 0x111); return Icon.FromHandle(psfi.hIcon); } [DllImport("shell32.dll", CharSet = CharSet.Auto)] private static extern IntPtr SHGetFileInfo(string pszPath, int dwFileAttributes, ref SHFILEINFO psfi, int cbFileInfo, int uFlags); [DllImport("oleaut32.dll", CharSet = CharSet.Auto, SetLastError = true)] internal static extern int OleLoadPictureFile(object fileName, [MarshalAs(UnmanagedType.IDispatch)] ref object iPictureDisp); public static Color VS_MENUCOLOR = Color.FromArgb(0xec, 0xe9, 0xd8); public static Color VS2005_COLOR = Color.FromArgb(0, 254, 0); public static Image GetImageFromAnyFormat(string path) { string str = path.ToLower(); if (str.EndsWith(".exe") || str.EndsWith(".ico")) { return GetIconFromFile(path).ToBitmap(); } return Image.FromFile(path, true); } protected static object OleLoadPictureFile(string fileName) { object iPictureDisp = null; OleLoadPictureFile(fileName, ref iPictureDisp); return iPictureDisp; } public static StdPicture CreatePictureDisp(Image image) { return (StdPicture)ImageConverter.GetIPictureDispFromImage(image); } } class ImageConverter : AxHost { internal ImageConverter() : base("52D64AAC-29C1-CAC8-BB3A-115F0D3D77CB") { } public static IPictureDisp GetIPictureDispFromImage(Image image) { return (IPictureDisp)AxHost.GetIPictureDispFromPicture(image); } } |
Usage:
1 2 3 4 5 6 7 8 9 10 | if (string.Equals(@"Software\Microsoft\VisualStudio\8.0", _applicationObject.RegistryRoot)) { //If VS 2005 _myFavoritesWindow.SetTabPicture(Resources.favicon.GetHbitmap()); } else { //If VS 2008 _myFavoritesWindow.SetTabPicture(MyIcon.CreatePictureDisp(MyIcon.PrepareImage(Resources.favicon, MyIcon.VS_MENUCOLOR))); } |
Note:
1. The code above is not tested extensively on different machines.
2. Before using the above code you can check a nice article by Carlos Quintero. He has also written how the icon can be set for Visual Studio 2010 toolwindow.



