Using the same set of bitmaps in Visio'03 Visio'07 and Visio'10

Started by Nikolay, April 12, 2010, 05:06:27 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Nikolay

Is there a simple way to use the same set of images
in both Visio 2007, 2003 and Visio 2010 ribbon (supporting "transparency"?)

Means, "old" Visio "command bars" expects bitmap + mask,
whereas Visio 2010 ribbon expects image with "real" transparency.

Supporting two sets of images doesn't sound fun :-[

Nikolay

I ended up with generating bitmap/mask pairs for Visio '03 and Visio '07 dynamically at runtime
out of PNG files with transparency, intended for Visio '10 (included in resources)
Seems to work.

scott

Nikolay -- sounds interesting. Can you provide a few more details?

Nikolay

Quote from: scott on April 23, 2010, 03:29:07 AM
Nikolay -- sounds interesting. Can you provide a few more details?

Yes, sure. Sorry for the late reply - I was on vacation :D

For Visio 2003, 2007
the code sets "Picture" and "Mask" properties of "CommandBarButton":


CommandBarButton button = ...

Bitmap picture, mask;
PictureConvert.BitmapToPictureAndMask(Resources.Logo, out picture, out mask);

button.Picture = PictureConvert.ImageToPictureDisp(picture);
button.Mask = PictureConvert.ImageToPictureDisp(mask);


For Visio 2010,
the code just returns the PNG picture as is:

public object OnRibbonLoadImage(string id)
{
   return PictureConvert.ImageToPictureDisp(Resources.Logo);
}


The "PictureConvert" class follows.
The class splists the PNG into 2 images for "old" versions, and converts "Bitmap" to "IPictureDisp" for Visio.

   internal class PictureConvert : System.Windows.Forms.AxHost
   {
       private PictureConvert() : base("") { }

       static public stdole.IPictureDisp ImageToPictureDisp(Bitmap image)
       {
           return (stdole.IPictureDisp)GetIPictureDispFromPicture(image);
       }

       static public void BitmapToPictureAndMask(Bitmap bm, out Bitmap picture, out Bitmap mask)
       {
           int w = bm.Width;
           int h = bm.Height;

           byte[] picture_data = new byte[3 * w * h];
           byte[] mask_data = new byte[3 * w * h];

           BitmapData bm_bits = bm.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
           byte[] bits = new byte[4 * w * h];
           Marshal.Copy(bm_bits.Scan0, bits, 0, 4 * w * h);
           bm.UnlockBits(bm_bits);

           for (int y = 0; y < h; ++y)
           {
               for (int x = 0; x < w; ++x)
               {
                   int src_idx = (x + y * w) * 4;
                   int dst_idx = (x + y * w) * 3;

                   picture_data[dst_idx + 0] = bits[src_idx + 0];
                   picture_data[dst_idx + 1] = bits[src_idx + 1];
                   picture_data[dst_idx + 2] = bits[src_idx + 2];

                   byte t = (bits[src_idx + 3] < 128) ? (byte)255 : (byte)0;

                   mask_data[dst_idx + 0] = t;
                   mask_data[dst_idx + 1] = t;
                   mask_data[dst_idx + 2] = t;
               }
           }

           Rectangle rect = new Rectangle(0, 0, w, h);

           picture = new Bitmap(w, h, PixelFormat.Format24bppRgb);
           BitmapData picture_bits = picture.LockBits(rect, ImageLockMode.WriteOnly, picture.PixelFormat);
           Marshal.Copy(picture_data, 0, picture_bits.Scan0, w * h * 3);
           picture.UnlockBits(picture_bits);

           mask = new Bitmap(w, h, PixelFormat.Format24bppRgb);
           BitmapData mask_bits = mask.LockBits(rect, ImageLockMode.WriteOnly, picture.PixelFormat);
           Marshal.Copy(mask_data, 0, mask_bits.Scan0, w * h * 3);
           mask.UnlockBits(mask_bits);

       }
   }


The test project is attached.
It adds a toolbar with a button (with transparency) for Visio 2003 and 2007, or a ribbon tab with a button (with transparency) for Visio 2010.

The project is Visual Studio 2010 (NET 4.0) project to take advantage of NO-PIA technology of NET 4. Thanks to M$ it seems that now it is finally possible to create a SINGLE managed add-in that would works for ALL VERSIONS of Visio, and would be able to take advantage of the "latest" version (e.g. able to install either "ribbon" or "command bars" user interface depending on Visio version). Means, the add-in can be build agains LATEST interop type library of Visio 2010, and still work with Visio 2003. The article that explains why this was a problem can be found here