Selection – это набор фигур, хотя может быть выбрана и только одна фигура. С помощью этого объекта можно делать различные действия над фигурами: действия над геометрией (объединять, сегментировать, комбинировать, вычитать, обрезать), выравнивать, размещать, вращать, перемещать, сдвигать, отражать, менять начальный и конечные точки, группировать, копировать, вырезать, удалять, соединять, связывать с данными, менять порядок (индекс глубины) – уф, не знаю все ли перечислил. Впечатляет?
Сначала нужно разобраться как пользователь выделяет объекты и что при это происходит.
Объекты можно выделять обводя вокруг объектов мышкой c нажатой левой клавишей. Если объект полностью обведен,
то после отпускания клавиши мыши - он становится выделенным, появляется рамка с маркерами.
В Visio есть настройка, позволяющая обводить объекты не полностью для того, чтобы они были выбраны:
Сервис - Параметры - закладка Общие - Выделять фигуры, частично находящиеся в области. Кроме обводки мышью можно выделять объекты щелкая по ним мышью и удерживая при этом клавишу
Shift или
Ctrl. При этом мы можем добавлять и удалять объекты из выделения.
Первый выделенный объект, подкрашен более толстой линией. В некоторых операциях важно какой объект был выделен первым.
При выделении нескольких объектов вокруг области выделения появляется рамка.
Если объект находится в группе, и мы его выделили, то рамка выглядит немного иначе. В маркерах мы видим небольшие крестики. При этом сама группа так же выделяется пунктирной линией.
Вложение:
2 Select in group.png [ 39.64 Кб | Просмотров: 1170 ]
Теперь разберемся - как все эти виды выделений отражаются на объект Selection.
Выделение в окне и в памятиВыделять объекты мы можем в памяти, а можем в окне (визуально).
Для выделения объектов в окне мы используем объект Window и его методы: Select, SelectAll, DeselectAll
Код:
Private Sub SelectWindow()
Dim win As Visio.Window
Set win = ActiveWindow
win.DeselectAll
win.SelectAll
End Sub
Так мы выделили объекты визуально. Обратится к выделенным объектам мы можем через свойство окна Selection.
Если мы хотим выделять в памяти, то поступаем так:
Код:
Private Sub SelectInMemory()
Dim win As Visio.Window
Dim sel As Visio.Selection
Set win = ActiveWindow
Set sel = ActiveWindow.Selection
sel.DeselectAll
sel.SelectAll
End Sub
Выделяем программноМетоды SelectAll и DeselectAll – просты.
А вот метод Select более сложен. Метод Select имеет следующий синтаксис:
expression.Select(SheetObject, SelectAction)SheetObject – это фигура для выбора\отмены, SelectionAction – действие:
Constant | Value | Description |
visDeselect | 1 | Отменить выделение объекта (убрать из выделения). |
visSelect | 2 | Выделить объект (добавить в выделение). |
visSubSelect | 3 | Выделить объект в группе (при этом сама группа тоже будет выделена, но пунктирной рамкой). |
visSelectAll | 4 | Выделить все одноранговые объекты. |
visDeselectAll | 256 | Отменить выделение для всех одноранговых объектов. |
Для наглядности будем выделять объекты в окне визуально. Sheet.1 и Sheet.2 объединены в группу Sheet.4.
Вложение:
3 Select all.png [ 27.42 Кб | Просмотров: 1159 ]
Вот код, который выделяет объекты:
Код:
Private Sub SelectInMemory()
Dim win As Visio.Window
Dim pg As Visio.Page
Set win = ActiveWindow
Set pg = ActiveWindow.Page
win.Select pg.Shapes("Sheet.3"), visDeselectAll
win.Select pg.Shapes("Sheet.3"), visSelect
win.Select pg.Shapes("Sheet.5"), visSelect
' группу можно не выделять, если хотим потом выделить объекты в ней
'win.Select pg.Shapes("Sheet.4"), visSelect
win.Select pg.Shapes("Sheet.1"), visSubSelect
win.Select pg.Shapes("Sheet.2"), visSubSelect
' а вот так делать нельзя!
'win.Select pg.Shapes("Sheet.1"), visDeselectAll
' А вот так можно
'win.Select pg.Shapes("Sheet.3"), visDeselectAll
End Sub
Здесь нужно отметить, что для выделения объектов внутри группы используется флаг visSubSelect.
Три типа выделенияПри выделении объектов различаются три типа выделения:
простое выделение (визуально – зеленая рамка с маркерами),
выделение внутри группы (SubSelect) (визуально – зеленая рамка с маркерами с крестиками внутри),
выделение группы, когда в ней выделены объекты (SuperSelect) (визуально – пунктирная линия по контуру группы).
Хочу обратить внимание свойство
IterationMode влияет только на перебор объектов внутри Selection и на свойство Count, но не на действия с выбранными объектами.
Оно может принимать комбинацию следующих значений Visio.VisSelectMode:
Constant | Value | Description |
visSelModeSkipSuper | &H0100 | Все объекты, кроме Superselected. |
visSelModeOnlySuper | &H0200 | Только объекты Superselected. |
visSelModeSkipSub | &H0400 | Все объекты, кроме Subselected. |
visSelModeOnlySub | &H0800 | Только объекты Subselected. |
Логика немного запутанная.
По умолчанию идет комбинация visSelModeSkipSuper + visSelModeSkipSub. Это значит, что видны все объекты, кроме выбранных внутри групп и самих групп, которые выбраны как SuperSelect. То есть просто как бы объекты первого уровня.
Режим
visSelModeSkipSuper даст возможность перебора всех объектов, кроме SuperSelect, то есть простой выбор и SubSelect.
Режим
visSelModeOnlySuper даст возможность перебора всех объектов (групп), которые выбраны как SuperSelect (т.е. вследтвие выбора внутри них объектов).
Режим
visSelModeSkipSub даст возможность перебора всех объектов и простого выбора и групп, которые выбраны как SuperSelect .
Режим
visSelModeOnlySub даст возможность перебора всех объектов выбранных внутри группы (SubSelect).
Изменение IterationMode не влияет на включение\исключение в\из Selection, он влияет только на перебор объектов в циклах и на свойство Count.
Для определения типа выделения для объекта есть еще индексное свойство ItemStatus(index). Оно может возвращать комбинацию следующих значений:
Constant | Value | Description |
visSelIsPrimaryItem | &H1 | Первично выбранный |
visSelIsSubItem | &H2 | Выбранный SubSelect |
visSelIsSuperItem | &H4 | Выбранный SuperSelect |
Еще один способ получения множества выбранных фигур – это метод GetIDs – получение массива ID фигур. IterationMode – непосредственно влияет на возвращаемый список.
Код:
Public Sub GetIDs_Example()
Dim vsoSelection As Visio.Selection
Dim lngShapeIDs() As Long
Dim lngShapeID As Long
ActiveWindow.DeselectAll
ActiveWindow.SelectAll
Set vsoSelection = ActiveWindow.Selection
vsoSelection.IterationMode = Visio.VisSelectMode.visSelModeSkipSuper
Call vsoSelection.GetIDs(lngShapeIDs)
For lngShapeID = LBound(lngShapeIDs) To UBound(lngShapeIDs)
Debug.Print lngShapeIDs(lngShapeID)
Next
End Sub
Следует отметить, что перебор с использование индексов начинается с 1.
IterationMode не влияет на действия с фигурами. Действия распространяются на простые выбранные фигуры и на фигуры SubSelect, т.е. как бы выбран режим visSelModeSkipSuper. Если выполнить sel.Rotate90, то фигуры SuperSelect не повернутся даже если выбран режим visSelModeOnlySuper.
BoundingBoxМетод BoundingBox возвращает координаты обрамляющего прямоугольника. При этом он игнорирует фигуры, выделенные Subselect и как Supeselect вне зависимости от режима InteractiveMode. Вот его синтаксис:
expression.BoundingBox(Flags, lpr8Left, lpr8Bottom, lpr8Right, lpr8Top)
Последние 4 параметра – возвращаемые координаты прямоугольника. Разберем наиболее важные параметры Flags для Selection.
Этот параметр определяет какой прямоугольник нам нужен.
visBBoxUprightWH | &H1 | Минимальный контур выбранных фигур. То есть это практически то, что мы обычно видим, когда выделяем несколько фигур. |
visBBoxUprightText | &H2 | Определяет минимальный прямоугольник, обрамляющий тексты фигур. Нужно иметь ввиду - прямоугольник обрамляет именно тексты, а не Текстовые блоки, то есть это минимальный прямоугольник, который нужен, чтобы закрыть все тексты выделенных фигур. |
visBBoxExtents | &H4 | Минимальный прямоугольник, обрамляющий геометрию фигур. Рамка фигуры может отличаться от рамки геометрии фигуры. |
visBBoxIncludeHidden | &H10 | Учитывать невидимую геометрию фигур |
visBBoxIgnoreVisible | &H20 | Учитывать видимую геометрию фигур (если геометрия выходит за рамки фигуры). |
visBBoxNoNonPrint | &H4000 | Игнорировать непечатные фигуры. |
Это основные значения, которые могут понадобится. Остальные значения достаточно специфичны и здесь я приводить их не буду.
Хочется обратить внимание на выборку внутри группы – Subselection. Если такая выборка есть, то BoundingBox возвращает ошибку. В случае ошибки BoundingBox возвращает прямоугольник:
x1 = 0, y1 = 0, x2 = -1, y2 = -1.