Тема: VBA: Непонятки с перехватом событий Word (WithEvents)
Здравствуйте! Не могу разобраться с такими непонятками. Допустим, мне надо перехватывать клики в Word. Пусть есть форма "myForm1" с двумя кнопками:
"Включить перехват" -- запускает процедуру "Word_Events_Register" (её код см. ниже)
"Выключить перехват" -- запускает процедуру "Word_Events_UnRegister" (её код см. ниже)
Есть модуль класса "clsWordEvents" с таким кодом
' Этот объект (класс) нужен для перехвата событий Word.
' В данном случаю он использ-ся для перехвата события
' WindowSelectionChange (это когда кликаешь курсором в
' разных местах)
'
Option Explicit
Public WithEvents AppWord As Word.Application
Private Sub AppWord_WindowSelectionChange(ByVal Sel As Selection)
Dim FontName As String
Dim SymbCode As Integer
Dim SymbCodeS As String
FontName = Sel.Range.Font.Name
If FontName <> "Verdana" Then
' шрифт не Verdana -- выходим
Exit Sub
End If
' Шрифт Verdana -- продолжаем
' выделяем смивол, по которому (перед которым) кликнули курсором
'
If Sel.Type = wdSelectionIP Then
Sel.MoveRight Unit:=wdCharacter, Count:=1, Extend:=wdExtend
End If
End Subесть модуль "Module1" с кодом:
Option Explicit
Private obWordEvents As clsWordEvents
'
' Объект класса clsWordEvents, после своего создания он будет
' реагир на события Word (тут на событ WindowSelectionChange)
'
' NOTES:
'
' 1. чтобы это работало, в VBA-проекте должен быть класс
' clsWordEvents -- проверь!
'
' 2. создание obj obWordEvents -- в sub Word_Events_Register,
' уничтожен -- в sub Word_Events_UnRegister (после уничтож
' Word не будет реагир на событие WindowSelectionChange --
' это сделано для удобства, чтобы отключ. перехват событий
' когда это не нужно и мешает. Запуск этих SUB -- вручную
' из окна макросов Word.
'
Sub Word_Events_Register()
' Создает объект (обработчик событий), перехватывающий события
' Word (в данном случае это будет событ WindowSelectionChange)
If Not obWordEvents Is Nothing Then
' ветка, когда объект-обработчик событий Word уже
' существует, so его создавать не надо -- выходим.
'
' MsgBox "Обработчик событий уже был создан" & Chr(13) & _
' "и не требует повторной регистрации" & Chr(13) & _
' "(просто выходим)."
Exit Sub
End If
Set obWordEvents = New clsWordEvents
Set obWordEvents.AppWord = Word.Application
End Sub
Sub Word_Events_UnRegister()
' Уничтожает объект (если он ранее был создан запуском
' Word_Events_Register), перехватывающий события Word.
' Я сделал это просто для удобства, чтобы при необходимости
' отключать перехват событий.
If obWordEvents Is Nothing Then
' ветка, когда объект-обработчик событий Word не
' существует, so его уничтожать не надо -- выход.
'
' MsgBox "Обработчик событий не существует," & Chr(13) & _
' "поэтому его уничтожение не нужно." & Chr(13) & _
' "(просто выходим)."
Exit Sub
End If
Set obWordEvents = Nothing
End SubЕсть модуль "FormsView" с кодом:
Option Explicit
' В этом модуле Е макросы для отображения или скрытия
' разного рода диалоговых окон (форм, сообщений итп.)
Sub myForm1_Show()
myForm1.Show ' отображ. форму myForm1
End SubТеперь делаем следующее. Выводим форму "myForm1" (запуском в окне макросов процедуры "myForm1_Show"). Жмём кнопку "Включить перехват" (сработает процедура "Word_Events_Register"). Кликаем по тексту в Word и после клика курсор превращается в выделение — примерно так: "сл|ово" --> "сл[о]во" ("|" означает курсор, а "[]" выделение).
Жмем кнопку "Выключить перехват" (сработает процедура "Word_Events_UnRegister") и теперь при кликах выделения не будет: "сл|ово". — Всё так как мне и надо, это понятно и нормально.
Допустим теперь, что на форме есть третья кнопка "Action" (название условное), которая запускает такой код:
Private Sub btnAction_Click()
Word_Events_UnRegister ' выключили перехват событий
Selection.Move Unit:=wdCharacter, Count:=1 ' сдвинули курсор на 1 символ вправо
Word_Events_Register ' включили перехват обратно
End SubТо есть тут по идее происходит то же самое, что было описано выше с нажатием кнопок, только отключение/включение перехвата событий делается не вручную (кнопками), а программно прямым запуском соотв-х процедур. Но вот тут и возникают лютые непонятки: при этом после клика получается так:
"сл|ово" --> "сл[о]во"
-- а должно быть (по идее) так: --
"сл|ово"
То есть такое впечатление, что движение курсора (Selection.Move) почему-то перехватывается, хотя перехват вроде бы выключен. Может кто-нибудь объяснить, почему так происходит?

