Author Topic: Using the same set of bitmaps in Visio'03 Visio'07 and Visio'10  (Read 5979 times)

0 Members and 1 Guest are viewing this topic.

Nikolay

  • Hero Member
  • *****
  • Posts: 1123
    • UnmanagedVisio
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 :-[
« Last Edit: April 12, 2010, 01:39:06 AM by Nikolay Belyh »

Nikolay

  • Hero Member
  • *****
  • Posts: 1123
    • UnmanagedVisio
Re: Using the same set of bitmaps in Visio'03 Visio'07 and Visio'10
« Reply #1 on: April 14, 2010, 10:01:06 PM »
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.
« Last Edit: April 14, 2010, 11:34:23 PM by Nikolay Belyh »

scott

  • Full Member
  • ***
  • Posts: 106
Re: Using the same set of bitmaps in Visio'03 Visio'07 and Visio'10
« Reply #2 on: April 22, 2010, 10:29:07 PM »
Nikolay -- sounds interesting. Can you provide a few more details?

Nikolay

  • Hero Member
  • *****
  • Posts: 1123
    • UnmanagedVisio
Re: Using the same set of bitmaps in Visio'03 Visio'07 and Visio'10
« Reply #3 on: May 22, 2010, 04:32:18 PM »
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":

Code
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:
Code
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.
Code
    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
« Last Edit: May 22, 2010, 05:11:30 PM by Nikolay Belyh »