ActiveX Controls that Interact with Shapes: an Example

To understand how ActiveX® controls can interact with Microsoft® Visio® shapes, consider the following example, which shows a drawing that contains a combo box control that lists the names of shapes in the drawing. The drawing also contains text boxes that display the text and certain custom properties of a selected shape, and a command button that updates a selected shape with new values in the text boxes. The drawing maintains a running total of cost and duration for all process flowchart shapes on the page, updating the totals as shapes are added, deleted, or changed.

A drawing that uses ActiveX controls to interact with shapes

A drawing that uses ActiveX controls to interact with shapes

The following code example shows a ComboBox1_Change event handler; this handler selects a shape in the drawing and displays its custom properties in the text boxes when the user highlights the shape's name in the combo box list:

Private Sub ComboBox1_Change()     'The user has clicked on an item in the list box     Dim strName As String     On Error GoTo Ignore:     If (bInComboBoxChanged) Then         'Exit without doing anything; already responding to the initial Change event         Exit Sub     End If     'Set flag indicating the program is in the Change routine. If an error occurs     'after this, it skips to the Ignore label, after which the flag is reset.     bInComboBoxChanged = True     'Calling DeselectAll and Select on the Window object set ComboBox1.Text     '(see theWindow_SelectionChanged). Save the current text before calling          'DeselectAll, so that we know which shape to select.     strName = ComboBox1.Text     'Select the item and get its properties     ActiveWindow.DeselectAll     ActiveWindow.Select ActivePage.Shapes(strName), visSelect     With ActivePage.Shapes(strName)         TextBox1.Text = .Text         TextBox2.Text = Format(.Cells("prop.cost").ResultIU, "Currency")         TextBox3.Text = Format(.Cells("prop.duration").Result(visElapsedMin), _             "###0 min.")     End With     Exit Sub Ignore:     'Set flag indicating the program is NOT in the Change handler anymore     bInComboBoxChanged = False End Sub

This handler does the following:

  1. Clears the selection in the drawing.
  1. Selects the shape whose name corresponds to the value of the ComboBox1 control's Text property. If the drawing doesn't contain such a shape, the handler simply exits.
  1. Sets the TextBox1 control's Text property to the Text property of the shape.
  1. Sets the TextBox2 control's Text property to the value of the shape's Cost custom property, expressed as currency.
  1. Sets the TextBox3 control's Text property to the value of the shape's Duration custom property, expressed as minutes.

The global variable bInComboBoxChanged indicates whether the ComboBox1_Change handler is being called for the first time. Clearing the selection and selecting a shape triggers Window_SelectionChanged events. However, this example's handler for that event sets the ComboBox1.Text property, which triggers a ComboBox1_Change event and causes the ComboBox1_Change handler to run again. Because the handler sets bInComboBoxChanged the first time it runs, it can skip the selection operations the second time, preventing the program from entering a recursive loop.

It's also possible to prevent such loops by setting the EventsEnabled property of the Application object to disable event handling while the handler performs operations that would otherwise trigger events and cause handlers to run inappropriately. However, this approach is not recommended, because it disables all events for the instance of Visio, which might interfere with other solutions running on the user's system (especially if an error in your solution prevents it from reenabling events). Unless you are certain that your solution is the only one that will be handling Visio events, it's recommended that you use the global variable technique shown in the previous example.