Что возвращает функция chr() в таком примере (chr (- 65 1))? |
Программирование на VBA
Отслеживание событий
Существует три типа событий - уровня приложения, уровня документа и уровня объекта. События первого типа связаны с открытием, сохранением, закрытием и печатью документа, загрузкой-выгрузкой приложений, изменением системных переменных. События второго типа связаны с добавлением, удалением, изменением объектов, активацией меню, изменением размеров окна рисунка, регенерацией, открытием, закрытием, печатью чертежа и др. И события уровня объекта возникают только тогда, когда объект изменился.
Написание обработчиков событий
События дают информацию о состоянии или активности. Хотя обработчики событий написаны специально для того, чтобы отвечать на события, AutoCAD часто вмешивается в обработку событий. Следовательно, обработчики событий имеют ограничения для выполнения безопасных операций в союзе с AutoCAD и его базой данных. Не стоит надеяться на последовательность событий, т.к. они могут случиться в любом порядке, что следует учитывать в обработчике. К примеру, при вызове команды Open происходят события BeginCommand, BeginOpen, EndOpen и EndCommand, но случиться они могут в любом порядке, кроме пожалуй только события начала и события завершения. Не надейтесь также на последовательность операций (например, при удалении двух объектов не обязательно, что событие удаления объекта 1 будет после 2). Не пытайтесь применять в обработчиках любые интерактивные функции, например ввод от пользователя. Не запускайте диалоговые окна, можно только окна сообщений. Писать данные можно в любой объект базы чертежа, кроме того, который вызвал событие. Любой объект, вызвавший событие, остается открытым для AutoCADа, но запись в него может быть фатальной, читать же можно без ограничений. Не выполняйте в обработчике событий действий, которые вызывают подобный обработчик. (например открытие документа из обработчика события BeginOpen.
Обработчики событий уровня приложения
Данные события не становятся автоматически доступны при загрузке VBA, поэтому они должны быть разрешены вручную. После этого будут доступны следующие события:
- AppActivate - происходит сразу перед активацией главного окна приложения;
- AppDeactivate - происходит сразу перед деактивацией главного окна приложения;
- ARXLoaded - происходит при загрузке ARX-приложения;
- ARXUnLoaded - происходит при выгрузке ARX-приложения;
- BeginCommand - происходит как только начала выполняться команда, но еще не завершена;
- BeginFileDrop - происходит когда файл "сброшен" в главное окно приложения;
- BeginLISP - происходит когда AutoCAD получает запрос на выполнение выражения LISP;
- BeginModal - происходит сразу перед появлением модального окна;
- BeginOpen - происходит сразу после того как AutoCAD получает запрос на открытие файла;
- BeginPlot - происходит сразу после того как AutoCAD получает запрос на печать;
- BeginQuit - происходит сразу перед тем как завершается сессия;
- BeginSave - происходит сразу после получения AutoCADом запроса на сохранение;
- EndCommand - происходит сразу при завершении команды;
- EndLISP - происходит сразу при завершении вычисления выражения LISP;
- EndModal - происходит сразу после закрытия модального окна диалога;
- EndOpen - происходит сразу после окончания процесса открытия чертежа;
- EndPlot - происходит сразу после завершения отправки на принтер;
- EndSave - происходит сразу по завершении сохранения;
- LISPCancelled - происходит при отмене выражения LISP;
- NewDrawing - происходит сразу перед созданием чертежа;
- SysVarChanged - происходит когда меняется значение системной переменной;
- WindowChanged - происходит при изменении окна приложения;
- WindowMovedOrResized - происходит при перемещении или изменении размера окна приложения.
Как разрешить события уровня приложения
Перед тем как начать использовать события уровня приложения следует создать новый модуль класса и объявить объект типа AcadApplication с применением ключевого слова WithEvents. Порядок работы следующий:
- В VBA IDE вставить модуль класса
- Выбрать новый модуль класса в окне проекта
- Изменить имя на EventClassModule
- В окне кода для класса добавить строку:
Public WithEvents App As AcadApplication
После того как новый объект объявлен с событиями он появится в окне списка объектов в модуле класса и можно выбирать процедуры событий для вновь созданного объекта из выпадающего списка. Однако перед тем как запустить процедуру нужно соединить объявленный объект с объектом Application, делается это с помощью такого кода в окне основного модуля:
Dim X As New EventClassModule Sub InitializeEvents() Set X.App = ThisDrawing.Application End Sub ' далее в коде основного модуля Call InitializeEvents
После того как выполнится процедура InitializeEvents объект App модуля класса будет указывать на объект Приложение (Application) Пример перехвата процесса загрузки, когда файл методом Drag-And-Drop перенесен в окно AutoCAD, выводящее окно сообщения с именем файла
' * * * В модуле класса * * * Option Explicit Public WithEvents App As AcadApplication Sub Example_AcadApplication_Events() ' Инициализируем глобальную переменную App ' которая будет использоваться для перехвата событий AcadApplication ' Обязательно запустить ее в начале Set App = GetObject(, "AutoCAD.Application") End Sub Private Sub App_BeginFileDrop(ByVal FileName As String, Cancel As Boolean) ' Пример перехвата события BeginFileDrop, каркас данной процедуры ' получен выбором из списка методов объекта App модуля класса в окне кода. ' Событие возникает как только файл перетащен в окно AutoCAD. ' If MsgBox("AutoCAD загружает " & FileName & vbCrLf _ & "продолжить загрузку?", vbYesNoCancel + vbQuestion) <> vbYes Then Cancel = True End If End Sub ' * * * В основной процедуре * * * Option Explicit Dim X As New EventClassModule Sub InitializeEvents() Set X.App = ThisDrawing.Application End Sub Sub main() Call InitializeEvents End Sub
Обработка событий уровня документа
События уровня документа постоянно происходят в процессе работы AutoCADа. Это значит, что они автоматически делаются доступными при загрузке проекта VBA, однако не доступны, например, для VB. То есть для других ActiveX Automation приложений их надо разрешать вручную. Доступны следующие события:
- Activate - происходит в момент активации документа;
- BeginClose - происходит перед закрытием документа;
- BeginCommand - происходит сразу после начала выполнения команды, но до ее завершения;
- BeginDoubleClick - происходит в момент двойного щелчка мышью;
- BeginLISP - происходит сразу после получения AutoCADом запроса на вычисление выражения LISP;
- BeginPlot - происходит сразу после получения AutoCADом запроса на печать документа;
- BeginRightClick - происходит после "правого щелчка" мышью в окне документа;
- BeginSave - происходит сразу после получения AutoCADом запроса на сохранение документа;
- BeginShortcutMenuCommand - происходит после "правого щелчка" мышью, но до появления всплывающего меню в режиме команд;
- BeginShortcutMenuDefault - происходит после "правого щелчка" мышью, но до появления всплывающего меню в режиме по-умолчанию;
- BeginShortcutMenuEdit - происходит после "правого щелчка" мышью, но до появления всплывающего меню в режиме редактирования;
- BeginShortcutMenuGrip - происходит после "правого щелчка" мышью, но до появления всплывающего меню в режиме "ручки";
- BeginShortcutMenuOsnap - происходит после "правого щелчка" мышью, но до появления всплывающего меню в режиме объектной привязки;
- Deactivate - происходит при деактивации окна документа;
- EndCommand - происходит сразу после завершения команды;
- EndLISP - происходит при завершении вычисления выражения LISP;
- EndPlot - происходит после отправки документа на печать;
- EndSave - происходит когда окончено сохранение документа;
- EndShortcutMenu - происходит после появления всплывающего меню;
- LayoutSwitched - происходит после переключения на другой Layout;
- LISPCancelled - происходит когда прервано вычисление выражения LISP;
- ObjectAdded - происходит когда добавлен объект;
- ObjectErased - происходит когда удален объект;
- ObjectModified - происходит когда изменен объект;
- SelectionChanged - присходит когда изменен выбор;
- WindowChanged - происходит когда изменено окно документа;
- WindowMovedOrResized - происходит сразу после изменения размера или перемещения окна документа.
Пример кодирования обработчиков событий уровня документа
Для этого нужно просто выбрать объект AutocadDocument из выпадающего меню в окне кода среды VBA IDE. Доступные события появятся в окне процедур, после выбора любой из них будет вставлен каркас процедуры обработки события. Данные процедуры будут касаться только активного документа. Пример обновления всплывающего меню при возникновении событий BeginShortcutMenuDefault и EndShortcutMenu путем добавления к нему пункта. Изменение не затрагивает файлы меню.
' это в модуле класса Option Explicit Public WithEvents mydoc As AcadDocument Private Sub mydoc_BeginShortcutMenuDefault(ShortcutMenu As IAcadPopupMenu) On Error Resume Next ' Добавим пункт меню Dim newMenuItem As AcadPopupMenuItem Dim openMacro As String openMacro = Chr(27) + Chr(27) + Chr(95) + "open" + Chr(32) Set newMenuItem = ShortcutMenu.AddMenuItem(0, Chr(Asc("&")) + "OpenDWG", openMacro) End Sub Private Sub mydoc_EndShortcutMenu(ShortcutMenu As IAcadPopupMenu) On Error Resume Next ShortcutMenu.Item("OpenDWG").Delete End Sub ' это в основном модуле Option Explicit Dim X As New EventClass Sub InitializeEvents() Set X.mydoc = ThisDrawing End Sub Sub main() Call InitializeEvents End Sub
Обработка событий уровня объекта
События уровня объекта не доступны на момент загрузки VBA. После того как они сделаны доступны становится доступно событие Modified. Следующий пример создает полилинию с обработчиком события, который показывает новую площадь при изменении полилинии.
' в модуле класса с именем EventClass Option Explicit Public WithEvents Object As AcadCircle Private Sub Object_Modified(ByVal pObject As IAcadObject) On Error GoTo errmsg MsgBox "Площадь " & pObject.ObjectName & " " & pObject.Area Exit Sub errmsg: MsgBox Err.Description End Sub ' В основой программе Dim X As New EventClass Sub main() Call InitializeEvents End Sub Sub InitializeEvents() Dim MyCircle As AcadCircle Dim centerPoint(0 To 2) As Double Dim radius As Double centerPoint(0) = 0#: centerPoint(1) = 0#: centerPoint(2) = 0#: radius = 5# Set MyCircle = ThisDrawing.ModelSpace.AddCircle(centerPoint, radius) Set X.Object = MyCircle ZoomExtents End Sub