Я могу объяснить поведение, хотя, возможно, не предложить прямого решения.
Когда вы вызываете Показать в любой форме, события формы обрабатываются с помощью обработчика сообщений по умолчанию (который настраивается при вызове «Выполнить»). Когда вы вызываете ShowDialog, целевая форма получает свой собственный отдельный насос сообщений.
Теперь добавленный вами фильтр находится в главном насосе сообщений и просматривает там все сообщения, но вызов ShowDialog обходит это - сообщения, отправленные в диалог, никогда не достигнут фильтра.
Теперь мы добавили вызов Application2.ShowDialog в качестве попытки обойти эту проблему, но, если честно, хотя я написал полную реализацию Application.Run/IMEssageFilter, я не делал обходной путь ShowDialog, и я действительно не не знаю, насколько хорошо это было реализовано. Основываясь на вашем отчете, я рискну предположить, что это «не хорошо», хотя решить эту проблему непросто. Корень этой проблемы в том, что SDF не контролирует то, что происходит в BCL, когда вы вызываете Show и ShowDialog - мы просто пытаемся сидеть над ним и обеспечивать наилучшее поведение, которое мы можем. В этом случае это проблематично.
Можете ли вы случайно не использовать вызов ShowDialog, а вместо этого просто использовать Show в сочетании с чем-то вроде сохранения формы TopMost? Это позволило бы фильтру получать все сообщения для псевдо-диалога. Другой вариант, который я могу придумать сразу, - это базовый класс для диалогов, который будет уведомлять механизм фильтрации, но при этом становится все труднее контролировать.