По сути, причина в том, что Windows обрабатывает сообщения - она делает это синхронно во внутреннем цикле сообщений.
Дело в том, что было сообщение, котороесработал ваш код.Например, нажатие кнопки.Ваше приложение находится в процессе обработки сообщения.Из этого обработчика вы вызываете обновление, которое помещает еще один WM_PAINT в очередь сообщений.Когда ваш обработчик завершит работу, цикл обработки сообщений обязательно его заберет и отправит, таким образом, перерисовав элемент управления.Но ваш код не завершен, фактически он вызывает ваш ShowProgress
, вызывая то, что WM_PAINT ставится в очередь навсегда.
С другой стороны, DoEvents () вызывает запуск независимого экземпляра цикла сообщений.Он запускается из внутри вашего кода, что означает, что стек вызовов выглядит следующим образом:
внешний цикл сообщений -> ваш код -> внутренний цикл сообщений.
внутреннее сообщениеЦикл обрабатывает все ожидающие сообщения, включая WM_PAINT (таким образом, элемент управления перерисовывается), но это опасно - так как он будет отправлять все другие ожидающие сообщения , включая нажатия кнопок, нажатия меню или события, закрывающие ваше приложение с Xв правом верхнем углу.К сожалению, нет простого способа сделать цикл для обработки только WM_PAINT, что означает, что вызов DoEvents () подвергает ваше приложение тонким потенциальным проблемам, связанным с неожиданной пользовательской активностью во время выполнения вашего кода, который вызывает DoEvents.