Author Topic: Inserting Master Icon image to tree view in Add-ins with C# or VB .net  (Read 15216 times)

0 Members and 1 Guest are viewing this topic.

JuneTheSecond

  • Hero Member
  • *****
  • Posts: 1027
    • Visio Shapes, Stencils and Sample Drawings
I've posted a tree view where Master icons are inserted with VBA macro.
But in the Add-in we can not find the way to insert Master icon.
The image list of tree view does not allow the format of Visio Master icon, IPictureDisp.
We googled and tried the way how to convert the image format from IpictureDisp to Image, but failed to convert the image.
http://blogs.msdn.com/b/andreww/archive/2007/07/30/converting-between-ipicturedisp-and-system-drawing-image.aspx
Just the Visio Master icon cannot be converted.
If you have experienced like this kind of problem, please, let us know anything you have done or tried.
Than you in advance.

This is the code for conversion in Visual Studio 2010.

Code
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                Visio.Application app = this.app;
                IPictureDisp pic = app.ActiveDocument.Masters[1].Icon;
                Image img = AxHostConverter.PictureDispToImage(pic);            
              
            }
            catch (Exception ex)
            {
                MessageBox.Show("Program Error  " + ex);
            }

        }
        public Visio.Application app { get; set; }

    }

This is the error message issued at the conversion.by PictureDispToImage.
"The Object of the type of 'System.Drawing.Icon' cannot be casted to the type of 'System.Drawing.Image'."
I feel this message quite curious, because the type of Maste.Icon is not icon, but IPictureDisp..
« Last Edit: August 24, 2010, 06:43:58 AM by JuneTheSecond »
Best Regards,

Junichi Yoda
http://june.minibird.jp/

Nikolay

  • Hero Member
  • *****
  • Posts: 1307
    • UnmanagedVisio
Re: Inserting Master Icon image to tree view in Add-ins with C# or VB .net
« Reply #1 on: August 24, 2010, 12:01:48 PM »
Hi Junichi, I think you might be overcomplicating the things here.
Try the following: ;)

Code
IPicture pic = (IPicture)app.ActiveDocument.Masters[1].Icon;
Image img = Icon.FromHandle((IntPtr)pic.Handle).ToBitmap();

worksforme

JuneTheSecond

  • Hero Member
  • *****
  • Posts: 1027
    • Visio Shapes, Stencils and Sample Drawings
Re: Inserting Master Icon image to tree view in Add-ins with C# or VB .net
« Reply #2 on: August 24, 2010, 06:15:35 PM »
Thank you, Nikolay.

It really works like a charm.  :) :) :) :) :) :) :) :) :) :) :)
Best Regards,

Junichi Yoda
http://june.minibird.jp/

nashwaan

  • Full Member
  • ***
  • Posts: 85
Hi, Is there a way to do the same thing in VBA?
I need to convert visio's Shape.Picture (which is of type IPictureDisp but in EMF format "See Visio Automation Reference") to a IPictureDisp in bitmap format. Because the ImageList of TreeView refuses to understand 'IPictureDisp in EMF format'.
What do i need to convert Shape.Picture to bitmap and then to icon? in VBA, please.
Thanks,
Yousuf.
Give me six hours to chop down a tree and I will spend the first four sharpening the axe — Abraham Lincoln

Nikolay

  • Hero Member
  • *****
  • Posts: 1307
    • UnmanagedVisio
Yes, it is possible but may be too wordy and too unnatural. I mean, as far as I can tell you can't do this with VBA directly, but since you can use Windows API from VBA (i.e. "Declare Function bla-bla-bla") you could do that with API (see the attached drawing and macro in it, it draws all shapes on active page as a tree with images, i.e. sort of "yet another drawing explorer", look at the screenshot). Uses VBA only.
« Last Edit: May 25, 2011, 08:15:24 AM by Nikolay »

nashwaan

  • Full Member
  • ***
  • Posts: 85
Thanks Nicolay for your reply. This kind of solution is what i am looking for, VBA-based. But...
For some reasons, i get different output than yours! see attached screenshot. As you can see, White backround is replaced with black. Some shapes (like the green circle) is also shown as black! However, in the "yet another drawing explorer" of your screeshot, the black outline of the green circle is shown as white outline!

Note that I have Visio 2010 32-bit running on Windows 7 32-bit.

BTW, i have to do few changes to your code to make workable: I have to re-create TreeView control on the Form and re-create ImageList control to overcome this error message:
"Could not load some objects because they are not available on this machine."
Although it was a matter of dragging the control and drop it on the form, but i don't understand why your version wouldn't load!
Also, tvwChild is not recognized, so i had to replace it with digit 4 in this line:
Code
           'TreeView1.Nodes.Add root, tvwChild, id, "[" & shp.Name & "] " & shp.Text, id, id
            TreeView1.Nodes.Add root, 4, id, "[" & shp.Name & "] " & shp.Text, id, id ' tvwChild is replaced with 4

Ok, i complain about many things here, but i am mostly concerned about the correct rendering of the shapes in the TreeView.
Any idea? Does anyone else get same output as mine?

Thanks,
Yousuf.
Give me six hours to chop down a tree and I will spend the first four sharpening the axe — Abraham Lincoln

Nikolay

  • Hero Member
  • *****
  • Posts: 1307
    • UnmanagedVisio
Probably the problem is that you haven't set the image list mask color?
I think it should be set to black.
« Last Edit: May 25, 2011, 11:00:16 PM by Nikolay »

nashwaan

  • Full Member
  • ***
  • Posts: 85
Again, thanks for your reply Nikolay. After using your suggestion:
Code
ImageList1.MaskColor = vbBlack
i got another output (see attached screeshot) which i can identify few issues:
  • Anything black color is replaced with White (compare this screenshot with my previous post's screenshot). Thats why the black outline of the green circle in your screenshot is rendered as white outline. Also note the hair color which is supposed to be black is not shown at all.
  • the green circle is not rendered in its own. It's rendered however when it is part of a group.
  • the shape group of 'user' is not rendered at all. though, some sub-shapes are rendered.
Any idea? Anyone else is having same output?

Thanks,
Yousuf.
Give me six hours to chop down a tree and I will spend the first four sharpening the axe — Abraham Lincoln

Nikolay

  • Hero Member
  • *****
  • Posts: 1307
    • UnmanagedVisio
Hi Yousuf,

Yes, indeed black mask color does not seem to be a best choice - all black items are eaten up by it :)
Actually a color which does not exist in diagram should be used as mask color I suppose. So I've changed now this mask color to RGB(0,0,1) - "almost" black.
So now the missing parts of the thumbnail images seem to be okay (the updated version is attached). Also fixed the issue with the reference.

The other thing is that thumbnail image quality is quite low; but this is what you get with a straightforward approach (e.g. if you don't use anti-aliasing or interpolation).
And it seems I'm a little bit too lazy to enhance this sample any further :)

Kind regards,
Nick
« Last Edit: May 29, 2011, 01:15:29 PM by Nikolay »

nashwaan

  • Full Member
  • ***
  • Posts: 85
Thanks Nick for your kind reply. That helped me ALOT and it solved the problem i was facing. I opted not to use RGB(0,0,1) approach. However, using same principle from the code you provide in the attached vsd document. i used:
Code
    hBrush = CreateSolidBrush(vbWhite)
instead of:
Code
    hBrush = CreateSolidBrush(RGB(0, 0, 1))
and i did not set ImageList1.MaskColor to any color.

Ok, looking at your code, i just wonder where to find good references/examples to these Windows APIs:  ???
Code
Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function GetWindowDC Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function ReleaseDC Lib "user32" (ByVal hwnd As Long, ByVal hdc As Long) As Integer
Private Declare Function CreateCompatibleBitmap Lib "gdi32" (ByVal hdc As Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long
Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hObject As Long) As Long
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
Private Declare Function OleCreatePictureIndirect Lib "olepro32.dll" (PicDesc As PicBmpType, RefIID As GUID, ByVal fPictureOwnsHandle As Long, IPic As IPicture) As Long
Private Declare Function CreateSolidBrush Lib "gdi32" (ByVal crColor As Long) As Long
Private Declare Function FillRect Lib "user32" (ByVal hdc As Long, lpRect As RECT, ByVal hBrush As Long) As Long
Private Declare Function PlayEnhMetaFile Lib "gdi32" (ByVal hdc As Long, ByVal hEmf As Long, lpRect As RECT) As Long

Don't feel you need to answer me on this one. I am already very HAPPY with the solution you provided so far.  :D :D :D
Thank you Nikolay.
Regards,
Yousuf.
Give me six hours to chop down a tree and I will spend the first four sharpening the axe — Abraham Lincoln

Nikolay

  • Hero Member
  • *****
  • Posts: 1307
    • UnmanagedVisio
Well, it's no big deal to answer sometimes :)
All this stuff is just plain old WINAPI, which was the way people used to write programs for Windows not more than 10 years ago. It is thoroughly documented in MSDN
Although from the .NET prospective it might seem more like a stone axe :)