Если приложение занято и не успевает обработать цикл сообщений, событие OnTimer пропускается.
Это действительно правильно. Эти и эти сообщения в блоге на MSDN дают некоторые внутренние детали реализации, в частности, они упоминают, что истекающий таймер вызывает установку флага QS_TIMER
состояния очереди сообщений.Никакой дальнейший промежуток времени не заставит флаг состояния очереди быть еще более установленным.Когда этот флаг установлен и [Peek|Get]Message
не может выбрать любое сообщение с более высоким приоритетом, генерируется сообщение таймера.
Хотя сообщения таймера не накапливаются в очереди, возможно, чтобы таймер снова срабатывал, покапредыдущий обработчик событий выполняется.Это возможно, когда выполнение кода в обработчике занимает больше времени, чем интервал таймера, и повторный вход разрешен.Если обработчик таймера заставляет приложение обрабатывать помещенные в очередь сообщения, любой флаг состояния ожидающей очереди может быть сброшен, а сообщение отправлено снова, что может привести к срабатыванию таймера до завершения выполнения обработчика.
Использует ли TTimer внутреннюю / отдельную нить (через SetTimer)?
Нет.В главном потоке создается служебное окно, которое будет получать сообщения таймера.После получения сообщения таймера это окно вызывает обработчик события, если он назначен.
Почему форма, которая содержит таймер (и даже его OnTimer), все еще может делать вещи, если модальныйMessageDlg «блокирует» форму?
Модальный цикл продолжает обрабатывать очередь, он вызывает HandleMessage
Приложения в цикле, который вызывает ProcessMessage
.Следовательно, сообщения таймера все еще обрабатываются.
Это потенциальная причина для повторного входа, упомянутого выше.Вы можете использовать флаг или отключить / включить таймер, чтобы предотвратить это.Или вообще исключить обработку сообщений в обработчике.
В документации сказано, что SetTimer требует минимум Win2000.Как был реализован TTimer в Win98
То же самое.Документация постоянно меняется, иногда MSDN отбрасывает неподдерживаемые версии ОС из минимальных требований - довольно непоследовательно.Моя документация по API XE2 гласит:
Минимум операционных систем Windows 95, Windows NT 3.1
для сообщения WM_TIMER
.