Прокрутка таблицы - хитрость PeekMessage
На днях я решил поиграть с API-функцией PeekMessage(). Функция работает, но ловить ее нужно следующим образом.
Я прокручиваю таблицу, связанную с набором данных. "Поиск" в наборе данных
замедляет процесс скролирования (условимся называть "поиском" синхронное
перемещение табличного курсора в процессе скроллирования, при котором текущей
записью становится запись, ближайшая к нажимаемой кнопке полосы прокрутки).
Возникла задача: необходимо отменить "поиск" (процесс слежения) и переместить
указатель на необходимую запись только в случае остановки пользователем процесса
скроллирования, другими словами - пока пользователь осуществляет скроллирование,
"поиск" необходимо отменить. Итак, ко мне в голову пришла мысль, что с помощью
PeekMessage() можно выловить определенное сообщение и тем самым отменить поиск
во время прокрутки. Звучит просто, но на самом деле все оказалось наоборот.
Я установил фильтр поиска сообщений на WM_MOUSEFIRST/LAST. Ситуация:
пользователь непрерывно прокручивает DBGrid вниз, т.е. держит нажатой нижнюю
кнопку скроллирования. В результате PeekMessage() возвращает False - нас это не
устраивает, это не то, что мы хотим. Положительный результат можно получить
только в случае сверхскоростных манипуляций мышью.
Если в фильтре использовать 0 и 0, чтобы поймать любое сообщение, результат
всегда будет True. Причина, очевидно в том, что любой щелчок мыши в области
DBGrid никак не обойдется без последствий, генерация системой сообщения PAINT
яркий тому пример, поэтому PeekMessage может возвратить True в любое время, что
тоже не может нам помочь.
Было бы хорошо, если бы дескриптор DBGrid получал событие OnMouseUp() во
время его скроллирования. Обидно, но OnMouseUp() работает только с DBGrid, а не
с полосами прокрутки. OnMouseUp() с TForm при KeyPreview:=true не работает, я
проверял.
После пришла идея опросить состояние кнопок мыши с помощью функции
GetKeyState(). Пока кнопка нажата (DOWN), "поиск" запрещен, и наоборот. UP
(кнопка отжата) свидетельствует об окончании процесса скроллирования. Данный
способ работы с окном во время манипуляций с его полосой прокрутки заработал без
проблем. Теперь все в порядке: поиска во время прокрутки не происходит и
табличный курсор также никуда не перемещается.
Рассмотренная тема имеет отношение к полосам прокрутки, а события OnKeyUp() и
OnMouseUp() могут применяться где-нибудь еще.
|