• Categories

  • Archives

  • Subscribe

  • Meta

Detect Sub-selected Shapes Programmatically

Posted by Visio Guy on May 17th, 2008 758 views

Read Full Article

A coding problem that Visio developers often stumble upon recently reared its ugly head yet again in the newsgroups. The question, very simply, was:

How do you programmatically detect sub-selected shapes?

The usual place to start is with a simple line of code, like:

Visio.ActiveWindow.Selection

But as it turns out, this line surprisingly does not return sub-selected shapes. So let's dig deeper into the problem so that you can get your projects finished!

Two Three Modes of Selection

If you've used Visio for any amount of time, you've probably encountered the two types of selections that you can make in the UI. Normal selection, where you get the bright green handles, and sub-selection, where you delve into a group to select a sub-shape.

For the uninitiated, normal selection is the simplest, most-encountered case, and it looks like this when you select only one shape:

We can see that this shape is a group that contains two squares. If we click again on the smaller square, we will see slightly different selection handles: green boxes, each with a little x in the middle. This indicates that you have selected a shape within a group, i.e. you have sub-selected the shape:

But when it comes to coding, or seeing things from an internal, Visio-engine point of view, there is a third notion of selection: Super-selected shapes.

If you look closely at the sub-selection illustration above, you might make out a black dashed line surrounding the group. While you might only care that you have sub-selected the little square, Visio is still keeping track of the parent-group. In Visio geek terminology, this parent shape is Super-selected.

So when it comes to programming Visio and dealing with selections, keep the three modes of selection in mind: Selected, Sub-selected and Super-selected!

Tweak the Selection Object With IterationMode

It turns out that we can finely-tune which selected objects we want to know about by altering the IterationMode property of a Visio Selection object. The ItereationMode can have a combination of four values, enumerated in the VisSelectMode enumeration:

  • visSelModeSkipSuper Selection does not report superselected shapes
  • visSelModeOnlySuper Selection only reports superselected shapes
  • visSelModeSkipSub Selection does not report subselected shapes
  • visSelModeOnlySub Selection only reports subselected shapes

By default, a Selection object has an iteration mode of:

VisSelectMode.visSelModeSkipSub + VisSelectMode.visSelModeSkipSuper

which explains why we don't get any sub-selected shapes in a default selection - the argument says to skip them!

To get the result that many of us are probably looking for, namely normally-selected shapes and sub-selected shapes, we would use an IterationMode of:

VisSelectMode.visSelModeSkipSuper

This is the mode that is commented as "get all shapes together" in the code listing below. The idea is that we want a selection object that contains all of the shapes that a user specifically clicked on. Super-selected shapes are ignored, since I don't think a developer cares about them all that often.

Code Listing

Below is the code listing for the VBA code that is in the download at the very end of this article. The code requires a button and a text box. When the user clicks the button, a string containing information about the current Visio selection is returned by m_detectAllSelectedShapes. This string is then pushed to the text box control.

The function m_detectAllSelectedShapes returns overlapping results. First, it separates normally-selected shapes from sub-selected shapes, then it puts them all together at the end. So the resulting string can have up to three different lists.

Just look for where sel.IterationMode is set to see the differences.

    Private Sub CommandButton_DetectSelectedShapes_Click()
        Dim sReport As String
        sReport = m_detectAllSelectedShapes()
        Me.TextBox_Output.Text = sReport
    End Sub
 
    Private Function m_detectAllSelectedShapes() As String 
        Dim s As String
        Dim win As Visio.Window
        Dim sel As Visio.Selection
        Dim shp As Visio.Shape
 
        '// Use the ActiveWindow:
        win = Visio.ActiveWindow
 
        '// Get the normally selected shapes:
        sel = win.Selection
        sel.IterationMode = Visio.VisSelectMode.visSelModeSkipSub + _
                            Visio.VisSelectMode.visSelModeSkipSuper
 
        '// Header:
        If sel.Count > 0 Then
            s = s & "Normally-selected Shapes:" & vbCrLf
        End If
        '// Shape info:
        For Each shp In sel
            s = s & vbTab & shp.NameID & vbCrLf
        Next
 
        '// Get the sub-selected shapes:
        sel.IterationMode = Visio.VisSelectMode.visSelModeOnlySub + _
                           Visio.VisSelectMode.visSelModeSkipSuper
        '// Header:
        If sel.Count > 0 Then
            If (s <> vbNullString) Then s = s & vbCrLf
            s = s & "Sub-selected Shapes:" & vbCrLf
        End If
 
        '// Shape info:
        For Each shp In sel
            s = s & vbTab & shp.NameID & vbCrLf
        Next
 
        '// Get all selected shapes:
        sel.IterationMode = Visio.VisSelectMode.visSelModeSkipSuper
 
        '// Header:
        If sel.Count > 0 Then
            If (s <> vbNullString) Then s = s & vbCrLf
            s = s & "All Selected Shapes Together:" & vbCrLf
        End If
        '// Shape info:
        For Each shp In sel
            s = s & vbTab & shp.NameID & vbCrLf
        Next 
        m_detectAllSelectedShapes = s
    End Function

Again, to be technically complete, there should also be information about super-selected shapes returned by the code above, but I don't think that is information that most developers are interested in. The main concept is to be able to detect sub-selected shapes.

You can play with this code in a ready-to-go format by downloading the following Visio document:

Download: Detect Sub-selected Shapes.zip (69 KB)

Share this article!

These icons link to social bookmarking sites where readers can share and discover new web pages.

  • StumbleUpon
  • Digg
  • del.icio.us
  • Technorati
  • YahooMyWeb
  • Slashdot

Related Posts:

2 Responses to “Detect Sub-selected Shapes Programmatically”

  1. Steve Bolman Says:

    Thanks, Great article and the code is well annotated. While it is clear from the context, I would like to point out to others that there is a small typo second reference to “normally selected shapes” in the annotation below. This annotation should read “sub-selected shapes”.
    ‘// Get the normally selected shapes:
    sel.IterationMode = Visio.VisSelectMode.visSelModeOnlySub + _
    Visio.VisSelectMode.visSelModeSkipSuper

    Please advise if I am mistaken in my interpretation.
    Please keep up the good work, I am hoping to get up to speed someday.

  2. Visio Guy Says:

    Thanks Steve,

    I’ve corrected the comment, as you correctly specified!

    - Chris

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

  • Tag Cloud

  • Recent Comments on Visio Guy

  • RSS The Latest from the Visio Guy Forum

  •