Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Как поймать событие изменения текста документа Word?  (Прочитано 13129 раз)
0 Пользователей и 1 Гость смотрят эту тему.
adev
Гость
« : 19-03-2010 18:28 » 

Задача: необходимо контролировать количество символов в тексте документа, а в случае превышения некоторого максимального значения выделять цветом "лишние" символы. Собственно сама проверка и выделение цветом проблем не вызывают. Главный вопрос, каким образом оперативно отслеживать изменения в документе и вызывать проверку.

Вариант 1. Запускать проверку периодически через некоторые интервалы времени. Недостатки: бесконечный цикл с проверкой условия даже при отсутствии изменений в документе.
Вариант 2. Отслеживать события нажатия клавиш (набор и удаление символов) и левой кнопки мыши (вставка текста посредством контекстного меню или кнопки на панели инструментов).
Код:
Sub HandleEvents()
  Dim m As MSG
 
  bCancel = False
  Do While Not bCancel
    WaitMessage
    If PeekMessage(m, GetActiveWindow, 0, 0, PM_NOREMOVE) Then
      Select Case m.Message
      Case WM_KEYUP, WM_LBUTTONUP
        UpdateInfo
      End Select
    End If
    DoEvents
  Loop
End Sub

Sub AutoOpen()
  HandleEvents
End Sub
Недостатки варианта 2: 1) некоторые изменения становятся видны только после дополнительного клика мышью или нажатия клавиши; 2) при открытии документа в Word 2003 SP3 иконки стандартных панелей инструментов не видны до первого клика (см. приложенный скриншот).

Может, есть решение лучше? Подходящих событий объектной модели Word я не нашел.
Событие WindowSelectionChange не подходит, так как не происходит:
1) при наборе текста с клавиатуры, хотя курсор перемещается вправо;
2) при удалении символов клавишей BackSpace.

* dead_toolbars.png (5.31 Кб - загружено 976 раз.)
Записан
HandKot
Молодой специалист

ru
Offline Offline

« Ответ #1 : 22-03-2010 08:10 » 

ИМХО, лучше отслеживвать не в процессе набора, а впроцессе сохранения или печати
Логика упрощается
Записан

I Have Nine Lives You Have One Only
THINK!
baldr
Команда клуба

cy
Offline Offline
Пол: Мужской
Дорогие россияне


WWW
« Ответ #2 : 22-03-2010 08:20 » 

HandKot, логика упрощается, но если пользователь превысит лимит на 2 тысячи символов, то он, по-твоему, узнает об этом только через час, при попытке сохранить??
adev, должно быть событие что-то типа onKeyUp или похожее - сейчас не помню - на каждое нажатие клавиши в документе.
Записан

Приличный компьютер всегда будет стоить дороже 1000 долларов, потому что 500 долларов - это не вполне прилично
adev
Гость
« Ответ #3 : 27-03-2010 10:06 » 

baldr, к сожалению, события KeyPress, KeyUp, KeyDown есть только в MS Forms. С использованием форм VBA появится другая проблема - невозможность сохранения форматирования текста.
Записан
Naghual
Модератор

ua
Offline Offline
Пол: Мужской
ОПТИМИСТ


WWW
« Ответ #4 : 11-04-2010 21:09 » 

Интересная задачка.
Я рекомендую Вам использовать событие приложения "WindowSelectionChange" в связке с таймером.
Записан
adev
Гость
« Ответ #5 : 13-04-2010 02:37 » new

Да, в итоге пришел к решению с таймером
Код:
Sub AutoOpen()
'установка таймера
  TimerId = SetTimer(&H0, &H0, TimerInterval, AddressOf TimerProc)
  'сохраняем идентификатор таймера в пользовательском свойстве документа
  UpdateDocProperty TIMERPROP, msoPropertyTypeNumber, TimerId
End Sub

Sub AutoClose()
  StopTimer
End Sub

Sub StopTimer()
'остановка таймера
  KillTimer &H0, TimerId
End Sub

Public Sub TimerProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal idEvent As Long, _
  ByVal dwTimer As Long)
'обработчик таймера
  Dim DocTimer As Long

  'предотвращение нескольких одновременных обновлений
  If UpdateInProcess Then Exit Sub
 
  'работаем только со "своим" документом!
  DocTimer = GetDocProperty(TIMERPROP, 0)
  If DocTimer = TimerId Then
    CheckTables
  End If
End Sub

Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines