In my last post Visual Studio 2010 getting rid of satellite DLLs for add-ins I mentioned that VS 2010 will provide two approaches to avoid satellite DLLs for command pictures of add-ins:
The first one was clear: command pictures will be able to be embedded in the own DLL of the add-in.
The second one was not so clear:
“Commands.AddNamedCommand2 will now support an IPicture”.
After that post I exchanged e-mails with Suzanne Hansen (Program Manager of Visual Studio Platform Shell Team) and Jeff Robison (the developer implementing the changes). While I thought that a new EnvDTE100.Commands3.AddNamedCommand3 would be added supporting managed System.Drawing.Bitmap or System.Drawing.Icon types, they explained me that the Bitmap parameter of the current EnvDTE80.Commands2.AddNamedCommand2 method is actually a Variant/Object, not an integer (as it happens with the old EnvDTE.Commands.AddNamedCommand method) and therefore it allows you to pass other types apart from an integer (denoting a numeric bitmap id). Jeff took advantage of this to accept an IPicture type without introducing a new AddNamedCommand method with a different signature.
The bad news was that, alas, IPicture is a native COM type, not a managed type, so developers of managed add-ins would have to use hacks such as OleCreatePictureIndirect or System.Windows.Forms.AxHost.GetIPictureDispFromPicture to convert a managed System.Drawing.Bitmap to a native COM IPicture or IPictureDisp. I was familiar with those techniques (see my article HOWTO: Creating custom pictures for Visual Studio .NET add-ins commands, buttons and toolwindows) and they were ugly to me, and prone to problems with transparency as happened in the past.
So, I suggested to make EnvDTE80.Commands2.AddNamedCommand2 to accept an IntPtr type that would denote the handle of a managed bitmap (System.Drawing.Bitmap.GetHBitmap). The EnvDTE.Window.SetTabPicture already accepts that happily to set the picture of a toolwindow.
They devoted some days to think about all that and a couple of days ago Suzanne informed me that Jeff was able to make EnvDTE80.Commands2.AddNamedCommand2 accept managed System.Drawing.Bitmap or System.Drawing.Icon apart from the native IPicture type added previously. This couldn’t be greater news. Not only you will be able to get rid of embedded bitmaps, so can also use icons if you are not comfortable with 32-bit bitmaps with alpha channel for transparency.
FWIW if you are developing a package and not an add-in:
“Jeff has also made a similar change for package authors – a new API, AddNamedCommand3, will be available that will also accept Bitmaps, Icons and IPictures.”
While these changes won’t be available in the next VS 2010 Beta 2, they will be in subsequent builds. It is also great that they did these changes so late in the VS 2010 development cycle. Usually when Beta 2 is reached it is “feature completed” and no changes such as those are allowed, just bug and performance fixes.
I am looking forward to test these new changes. At last Visual Studio will allow you to decide:
- The way to provide custom pictures for add-ins:
- Embedded bitmaps in satellite Dll
- Embedded bitmaps in add-in Dll
- Directly in the EnvDTE80.Commands2.AddNamedCommand2 method
- The type of image to use:
- 32-bit System.Drawing.Bitmap with alpha channel for transparency
- System.Drawing.Icon (built-in transparency)
That plethora of choices together with the absence of COM stuff is what makes a good EnvDTE API for add-in developers.
Jeff and Suzanne, very good job!!