Я знаю, что это старо, но отвечает за потомство, так как никто здесь не упомянул это.
Скорее всего, проблема в том, что менеджер окон определяет, куда переслать сообщение. Если у вас есть иерархия окон, как вы, вероятно, делаете, то вам нужно убедиться, что окна не верхнего уровня, которые сами содержат элементы управления, должны иметь набор стилей WS_EX_CONTROLPARENT. Если это диалог, вы используете стиль DS_CONTROL. Наличие этих флагов изменяет поведение IsDialogMessage; они идентифицируют окно как имеющее свои собственные элементы управления, которые могут получать фокус и обрабатывать порядок табуляции и т. д., а не просто быть самим элементом управления.
Например, если у вас есть главное окно фрейма, у которого есть дочернее окно с WS_EX_CONTROLPARENT, у которого есть дочернее окно без WS_EX_CONTROLPARENT, у которого есть дочернее окно с фокусом, и вы нажимаете TAB, скорее всего, вы встретите бесконечный цикл в том же месте, о котором упоминаете.
Установка расширенного стиля второго дочернего элемента для включения WS_EX_CONTROLPARENT решит проблему.