Ваш подход не может быть хорошим по нескольким причинам:
1) Виндузе не гарантирует, что Ваша программа будет вызываться каждые
миллисекунд. У них есть внутренний квант времени, и найти вызов, задающий его, мне не удалось. Более того, не гарантируется, что этот квант не зависит от конфигурации виндузе. Мне приходилось сталкиваться и с квантами 10 мс, и с квантами 15.625 мс Вы можете выставить таймер на любое целое число мс, но вызываться Ваша задача будет по квантам.
2) Виндузе не гарантирует, что кванты не будут пропускаться. В частности, если квант был пропущен, не означает, что событие таймера будет вызвано дважды.
Единственный правильный способ делать часы — это организовывать таймер, и спрашивать у виндузе (в обработчике события) текущее время. Если Вас устраивает ошибка порядка кванта — лучше всего использовать GetSystemTimeAsFileTime() Если я не ошибаюсь, это очень быстрая функция, не использующая переход ядро (и переключение контекста). Не смотря на очень высокое разрешение (100 наносекунд) она имеет невысокую точность. Если нужна более высокая точность, можно использовать QueryPerformanceCounter() / QueryPerformanceFrequency(). По-моему, эти функции медленнее (переключаются в ядро), позволяют мерить только интервалы времени, но зато с большой точностью — субмикросекунды. Кроме того, не гарантируется сверхвысокая точность этих часов. В частности, при синхронизации часов PerformanceCounter идут равномерно, а SystemTime — слегка меняется.
Ну а дальше — выбор за Вами.
P.S. Всё это совершенно одинаково во всех средах. Builder здесь — последнее, абсолютно ничего не решающее звено. Всё тоже самое будет в студии…