![]() |
![]() |
|||
![]() |
||||
![]() |
![]() |
This article explains how to get the bitmap of a component or control type from a Visual Studio add-in. More informationTypes that are components or controls have associated a bitmap that Visual Studio uses in different places (Toolbox, Document Outline, designers, etc.). That bitmap can be established by the creator of the component in two different ways:
Both approaches possed a problem in Visual Studio 2012, which uses gray bitmaps for components rather than colored bitmaps. Since Visual Studio is multi-.NET Framework, some assembly (for example System.Windows.Forms version 4.0.0.0) can be used in Visual Studio 2010 and 2012. If the bitmaps of the assembly are colored (the default with assemblies installed by Visual Studio 2010 and .NET Framework 4), they would appear fine in Visual Studio 2010 (which uses colored bitmaps) but not in Visual Studio 2012 (which uses gray bitmaps). And if Visual Studio 2012 would install new versions of assemblies of a previous .NET Framework with gray bitmaps, they would appear fine (gray) in Visual Studio 2012 but also gray in Visual Studio 2010 (this happened during the beta releases of Visual Studio 2012 with the System.Windows.Forms 4.0.0.0 assembly). To solve that problem, Visual Studio 2012 and the .NET Framework 4.5 introduced a way to allow multiple versions of a bitmap (color, gray) for the same component type of a given assembly, overriding the default bitmap of a component in previous versions of Visual Studio and .NET Framework through the use of a suffix that allows a different name (and even assembly) for the bitmap resource. The approach is the following:
For example:
The following add-in shows how to get bitmap of a component with any of these approaches. It gets the bitmap of the System.Windows.Forms.Button type and shows it on a form (Form1). In Visual Studio 2012 it gets the gray bitmap correctly.
Imports System Imports Microsoft.VisualStudio.CommandBars Imports Extensibility Imports EnvDTE Imports EnvDTE80 ' Reference these assemblies: Imports System.Windows.Forms Imports System.Drawing Imports System.Configuration Public Class Connect Implements IDTExtensibility2 Private _applicationObject As DTE2 Private _addInInstance As AddIn Public Sub OnConnection(ByVal application As Object, ByVal connectMode As ext_ConnectMode, ByVal addInInst As Object, _ ByRef custom As Array) Implements IDTExtensibility2.OnConnection _applicationObject = CType(application, DTE2) _addInInstance = CType(addInInst, AddIn) Select Case connectMode Case ext_ConnectMode.ext_cm_AfterStartup Call Initialize() Case ext_ConnectMode.ext_cm_Startup ' OnStartupComplete will be called End Select End Sub Public Sub OnStartupComplete(ByRef custom As Array) Implements IDTExtensibility2.OnStartupComplete Initialize() End Sub Public Sub OnDisconnection(ByVal disconnectMode As ext_DisconnectMode, ByRef custom As Array) _ Implements IDTExtensibility2.OnDisconnection End Sub Public Sub OnAddInsUpdate(ByRef custom As Array) Implements IDTExtensibility2.OnAddInsUpdate End Sub Public Sub OnBeginShutdown(ByRef custom As Array) Implements IDTExtensibility2.OnBeginShutdown End Sub Private Sub Initialize() Dim bmp As Bitmap Dim frm As Form1 bmp = GetComponentBitmap(GetType(System.Windows.Forms.Button)) frm = New Form1() frm.BackgroundImageLayout = ImageLayout.None frm.BackgroundImage = bmp Using (frm) frm.ShowDialog() End Using End Sub Private Function GetComponentBitmap(ByVal componentType As Type) As Bitmap Dim bmp As Bitmap bmp = GetComponentBitmapByEmbeddedResource(componentType) If bmp Is Nothing Then bmp = GetComponentBitmapByToolboxBitmapAttribute(componentType) End If If bmp IsNot Nothing Then bmp.MakeTransparent(Color.Magenta) End If Return bmp End Function Private Function GetComponentBitmapByEmbeddedResource(ByVal componentType As Type) As Bitmap Dim bmp As Bitmap = Nothing Dim originalAssembly As System.Reflection.Assembly Dim suffix As String Dim satelliteAssembly As System.Reflection.Assembly Dim originalTypeFullName As String Dim newTypeFullName As String originalAssembly = componentType.Assembly originalTypeFullName = componentType.FullName If AssemblyHasCustomAttribute(originalAssembly, "System.Drawing.BitmapSuffixInSameAssemblyAttribute") Then suffix = GetAssemblySuffix() If suffix <> "" Then newTypeFullName = AppendSuffix(originalTypeFullName, suffix) bmp = GetBitmapFromManifestResource(originalAssembly, newTypeFullName) End If ElseIf AssemblyHasCustomAttribute(originalAssembly, "System.Drawing.BitmapSuffixInSatelliteAssemblyAttribute") Then suffix = GetAssemblySuffix() If suffix <> "" Then satelliteAssembly = GetSatelliteAssembly(originalAssembly, suffix) If satelliteAssembly IsNot Nothing Then bmp = GetBitmapFromManifestResource(satelliteAssembly, originalTypeFullName) End If End If End If If bmp Is Nothing Then bmp = GetBitmapFromManifestResource(componentType.Assembly, originalTypeFullName) End If Return bmp End Function Private Function GetComponentBitmapByToolboxBitmapAttribute(ByVal componentType As Type) As Bitmap Dim toolboxBitmapAttributeArray() As Object Dim toolboxBitmapAttribute As ToolboxBitmapAttribute Dim bmp As Bitmap = Nothing Dim img As Image toolboxBitmapAttributeArray = componentType.GetCustomAttributes(GetType(ToolboxBitmapAttribute), True) If toolboxBitmapAttributeArray IsNot Nothing Then If toolboxBitmapAttributeArray.Length > 0 Then toolboxBitmapAttribute = CType(toolboxBitmapAttributeArray(0), ToolboxBitmapAttribute) img = toolboxBitmapAttribute.GetImage(componentType) If img IsNot Nothing Then bmp = New Bitmap(img) End If End If End If Return bmp End Function Private Function GetAssemblySuffix() As String Dim section As Object Dim configurationSection As System.Configuration.ConfigurationSection Dim result As String = "" Try ' In VS 2012 this reads the "system.drawing" of the following config file: ' C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\devenv.exe.config ' which has the value: ' <system.drawing bitmapSuffix=".VisualStudio.11.0" /> section = System.Configuration.ConfigurationManager.GetSection("system.drawing") configurationSection = CType(section, System.Configuration.ConfigurationSection) If configurationSection IsNot Nothing Then result = configurationSection.ElementInformation.Properties.Item("bitmapSuffix").Value.ToString() End If Catch ex As Exception End Try Return result End Function Private Function AppendSuffix(ByVal sOriginalName As String, ByVal sSuffix As String) As String Dim result As String = sOriginalName Try result = IO.Path.ChangeExtension(sOriginalName, sSuffix & IO.Path.GetExtension(sOriginalName)) Catch ex As Exception End Try Return result End Function Private Function GetSatelliteAssembly(ByVal assembly As System.Reflection.Assembly, ByVal suffix As String) _ As System.Reflection.Assembly Dim satelliteAssembly As System.Reflection.Assembly = Nothing Dim asmName As System.Reflection.AssemblyName asmName = assembly.GetName() asmName.Name = asmName.Name & suffix Try satelliteAssembly = System.Reflection.Assembly.Load(asmName) Catch ex As Exception End Try Return satelliteAssembly End Function Private Function AssemblyHasCustomAttribute(ByVal assembly As System.Reflection.Assembly, ByVal attributeName As String) As Boolean Dim result As Boolean = False Dim assemblyAttributeArray() As Object Dim attr As Attribute Try assemblyAttributeArray = assembly.GetCustomAttributes(False) If assemblyAttributeArray IsNot Nothing Then If assemblyAttributeArray.Length > 0 Then For Each attr In assemblyAttributeArray If attr.ToString() = attributeName Then result = True Exit For End If Next End If End If Catch ex As Exception End Try Return result End Function Private Function GetBitmapFromManifestResource(ByVal assembly As System.Reflection.Assembly, ByVal typeFullName As String) As Bitmap Dim bitmapStream As System.IO.Stream Dim bmp As Bitmap = Nothing If assembly IsNot Nothing Then Try bitmapStream = assembly.GetManifestResourceStream(typeFullName & ".bmp") If bitmapStream IsNot Nothing Then bmp = New Bitmap(bitmapStream) End If Catch ex As Exception End Try End If Return bmp End Function End Class
using System; using Extensibility; using EnvDTE; using EnvDTE80; // Reference these assemblies: using System.Windows.Forms; using System.Drawing; using System.Configuration; namespace MyAddIn1 { public class Connect : IDTExtensibility2 { private DTE2 _applicationObject; private AddIn _addInInstance; public void OnConnection(object application, ext_ConnectMode connectMode, object addInInst, ref Array custom) { _applicationObject = (DTE2)application; _addInInstance = (AddIn)addInInst; switch (connectMode) { case ext_ConnectMode.ext_cm_AfterStartup: Initialize(); break; case ext_ConnectMode.ext_cm_Startup: // OnStartupComplete will be called break; } } public void OnDisconnection(ext_DisconnectMode disconnectMode, ref Array custom) { } public void OnStartupComplete(ref Array custom) { Initialize(); } public void OnAddInsUpdate(ref Array custom) { } public void OnBeginShutdown(ref Array custom) { } private void Initialize() { Bitmap bmp = null; Form1 frm = null; bmp = GetComponentBitmap(typeof(System.Windows.Forms.Button)); frm = new Form1(); frm.BackgroundImageLayout = ImageLayout.None; frm.BackgroundImage = bmp; using ((frm)) { frm.ShowDialog(); } } private Bitmap GetComponentBitmap(Type componentType) { Bitmap bmp = null; bmp = GetComponentBitmapByEmbeddedResource(componentType); if (bmp == null) { bmp = GetComponentBitmapByToolboxBitmapAttribute(componentType); } if (bmp != null) { bmp.MakeTransparent(Color.Magenta); } return bmp; } private Bitmap GetComponentBitmapByEmbeddedResource(Type componentType) { Bitmap bmp = null; System.Reflection.Assembly originalAssembly = null; string suffix = null; System.Reflection.Assembly satelliteAssembly = null; string originalTypeFullName = null; string newTypeFullName = null; originalAssembly = componentType.Assembly; originalTypeFullName = componentType.FullName; if (AssemblyHasCustomAttribute(originalAssembly, "System.Drawing.BitmapSuffixInSameAssemblyAttribute")) { suffix = GetAssemblySuffix(); if (!string.IsNullOrEmpty(suffix)) { newTypeFullName = AppendSuffix(originalTypeFullName, suffix); bmp = GetBitmapFromManifestResource(originalAssembly, newTypeFullName); } } else if (AssemblyHasCustomAttribute(originalAssembly, "System.Drawing.BitmapSuffixInSatelliteAssemblyAttribute")) { suffix = GetAssemblySuffix(); if (!string.IsNullOrEmpty(suffix)) { satelliteAssembly = GetSatelliteAssembly(originalAssembly, suffix); if (satelliteAssembly != null) { bmp = GetBitmapFromManifestResource(satelliteAssembly, originalTypeFullName); } } } if (bmp == null) { bmp = GetBitmapFromManifestResource(componentType.Assembly, originalTypeFullName); } return bmp; } private Bitmap GetComponentBitmapByToolboxBitmapAttribute(Type componentType) { object[] toolboxBitmapAttributeArray = null; ToolboxBitmapAttribute toolboxBitmapAttribute = null; Bitmap bmp = null; Image img = null; toolboxBitmapAttributeArray = componentType.GetCustomAttributes(typeof(ToolboxBitmapAttribute), true); if (toolboxBitmapAttributeArray != null) { if (toolboxBitmapAttributeArray.Length > 0) { toolboxBitmapAttribute = (ToolboxBitmapAttribute)toolboxBitmapAttributeArray[0]; img = toolboxBitmapAttribute.GetImage(componentType); if (img != null) { bmp = new Bitmap(img); } } } return bmp; } private string GetAssemblySuffix() { object section = null; System.Configuration.ConfigurationSection configurationSection = null; string result = ""; try { // In VS 2012 this reads the "system.drawing" of the following config file: // C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\devenv.exe.config // which has the value: // <system.drawing bitmapSuffix=".VisualStudio.11.0" /> section = System.Configuration.ConfigurationManager.GetSection("system.drawing"); configurationSection = (System.Configuration.ConfigurationSection)section; if (configurationSection != null) { result = configurationSection.ElementInformation.Properties["bitmapSuffix"].Value.ToString(); } } catch { } return result; } private string AppendSuffix(string sOriginalName, string sSuffix) { string result = sOriginalName; try { result = System.IO.Path.ChangeExtension(sOriginalName, sSuffix + System.IO.Path.GetExtension(sOriginalName)); } catch { } return result; } private System.Reflection.Assembly GetSatelliteAssembly(System.Reflection.Assembly assembly, string suffix) { System.Reflection.Assembly satelliteAssembly = null; System.Reflection.AssemblyName asmName = null; asmName = assembly.GetName(); asmName.Name = asmName.Name + suffix; try { satelliteAssembly = System.Reflection.Assembly.Load(asmName); } catch { } return satelliteAssembly; } private bool AssemblyHasCustomAttribute(System.Reflection.Assembly assembly, string attributeName) { bool result = false; object[] assemblyAttributeArray = null; Attribute attr = null; try { assemblyAttributeArray = assembly.GetCustomAttributes(false); if (assemblyAttributeArray != null) { if (assemblyAttributeArray.Length > 0) { foreach (Attribute attr_loopVariable in assemblyAttributeArray) { attr = attr_loopVariable; if (attr.ToString() == attributeName) { result = true; break; // TODO: might not be correct. Was : Exit For } } } } } catch { } return result; } private Bitmap GetBitmapFromManifestResource(System.Reflection.Assembly assembly, string typeFullName) { System.IO.Stream bitmapStream = null; Bitmap bmp = null; if (assembly != null) { try { bitmapStream = assembly.GetManifestResourceStream(typeFullName + ".bmp"); if (bitmapStream != null) { bmp = new Bitmap(bitmapStream); } } catch { } } return bmp; } } } Follow @VSExtensibility |
Copyright © 2000-2021 MZTools Software. All Rights Reserved. Legal Notice |