ОТСЛЕЖИВАНИЕ СОБЫТИЙ

Существует три типа событий - уровня приложения, уровня документа и уровня объекта. Первое из них отвечает например за открытие, сохранение, закрытие и печать документа, загрузку-выгрузку приложений, изменение системных переменных. Второе за добавление, удаление, изменение объектов, активацию меню, изменение размеров окна рисунка, регенерацию, открытие, закрытие, печать рисунка и др. И последние возникает только если объект изменился.

НАПИСАНИЕ ОБРАБОТЧИКОВ СОБЫТИЙ

События дают информацию о состоянии или активности. Хотя обработчики событий могут быть написаны чтобы отвечать на это, Автокад часто вмешивается в обработку событий. (?) Следовательно, обработчики событий имеют ограничения для выполнения безопасных операций в союзе с Автокадом и его базой данных. Не стоит надеяться на последовательность событий, т.к. они могут случиться в любом порядке, что следует учитывать в обработчеке. К примеру при вызове команды Open происходят события BeginCommand, BeginOpen, EndOpen и EndCommand, но случиться они могут в любом порядке, кроме пожалуй только событие начала и событие завершения. Не надейтесь так же на последовательность операций (например при удалении двух объектов не факт, что событие удаления объекта 1 будет после 2). Не пытайтесь применять в обработчиках любые интерактивные функции, например ввод от пользователя. Не запускайте диалоговые окна, можно только окна сообщений. Писать данные можно в любой объект базы чертежа, кроме того который вызвал событие. Любой объект вызвавший событие остается открытым для Автокада, но запись в него может привести к катастрофе, читать же можно сколько душе угодно. Не выполняйте в обработчике событий действий, которые вызывают подобный обработчик. (например открытие документа из обработчика события BeginOpen.

ОБРАБОТЧИКИ СОБЫТИЙ УРОВНЯ ПРИЛОЖЕНИЯ

Данные события не становятся автоматически доступны при загрузке VBA, поэтому они должны быть разрешены вручную. После этого будут доступны следующие события:

КАК РАЗРЕШИТЬ СОБЫТИЯ УРОВНЯ ПРИЛОЖЕНИЯ

Перед тем как начать использовать события уровня приложения следует создать новый модуль класса и объявить объект типа AcadApplication с применением ключевого слова WithEvents. Порядок работы следующий:
1. В VBA IDE вставить модуль класса 2. Выбрать новый модуль класса в окне проекта 3. Изменить имя на EventClassModule 4. В окне кода для класса добавить строку: 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 перенесен в окно Автокада, выводящее окно сообщения с именем файла
' * * * В модуле класса * * *
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

ОБРАБОТКА СОБЫТИЙ УРОВНЯ ДОКУМЕНТА

События уровня документа постоянно происходят в процессе работы Автокада. Это значит, что они автоматически делаются доступными при загрузке проекта VBA, однако не доступны например для VB. То есть для других ActiveX Automation приложений их надо разрешать вручную. Доступны следующие события:

ПРИМЕР КОДИРОВАНИЯ ОБРАБОТЧИКОВ СОБЫТИЙ УРОВНЯ ДОКУМЕНТА

Для этого нужно просто выбрать объект 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
Читать дальше - В начало - На главную