TAnimate в Windows XP / Vista с включенными темами не будет работать - PullRequest
0 голосов
/ 06 августа 2009

Коллега использовал пользовательский AVI для индикации прогресса в течение более длительных операций в течение многих лет. Это всегда хорошо работало.

Недавно он решил перейти с Delphi 7 на Delphi 2007, частично чтобы получить поддержку тем для своих приложений. (У нас, наконец, есть большинство людей, но не все, работающие на XP.) Анимация перестала работать. Отключение тем заставляет его работать снова.

TAnimate - это оболочка для элемента управления анимацией Windows, созданная с помощью InitCommonControlsEx (ICC_ANIMATE_CLASS). Документация MSDN гласит: «Если вы используете ComCtl32.dll версии 6, поток не поддерживается, поэтому убедитесь, что ваше приложение не блокирует пользовательский интерфейс или анимация не произойдет». Очевидно, это и есть предполагаемое поведение.

Есть ли у кого-нибудь предложение об обходном пути или альтернативе этой проблеме? Обработка, для которой он пытается показать прогресс, не годится для создания отдельного потока, и по понятным причинам Application.ProcessMessages также не является хорошим решением.

РЕДАКТИРОВАТЬ: Я присуждаю Робу Кеннеди правильный ответ на этот вопрос, потому что а) он предоставил «недостающее звено» (каламбур) в блоге Рэймонда Чена на эту тему, и б) из-за того, что он переместился в отдельный ответ был правильным ответом.

Ирония здесь: операция, которую он проводил, которая блокировала TAnimate, была операцией индексации для используемого нами механизма базы данных (Advantage Database Server или ADS). Он не упомянул об этом, когда пришел ко мне с проблемой.

ADS поддерживает обратный вызов прогресса с использованием методов TAdsDataSet.AdsRegisterCallbackFunction и TAdsDataSet.AdsClearCallbackFunction. Функция обратного вызова обеспечивает как ход выполнения (в процентах) текущей операции, так и способ отменить операцию с помощью возвращаемого значения функции. Таким образом, весь вопрос оказывается спорным; функцию обратного вызова можно использовать для обновления индикатора выполнения, который указывает пользователю, что приложение не зависло.

Ответы [ 2 ]

6 голосов
/ 06 августа 2009

Раймонд Чен писал об этом. Он даже не затрагивает то, что я обычно считаю основной причиной того, что многопоточный элемент управления не будет работать хорошо, а именно то, что поток не должен нарисовать на окне, связанном с другой нитью.

Я призываю вашего коллегу вернуться к тому, что заставило его решить, что он не может поместить задачу в отдельный поток. Это просто не очень хорошая идея, чтобы заблокировать основной поток пользовательского интерфейса, независимо от того, есть ли там элемент управления анимацией, чтобы скрыть неотзывчивость.

1 голос
/ 06 августа 2009

В качестве альтернативы TThreads вы можете использовать AsyncCalls , что обеспечивает более легкую точку входа в многопоточную обработку с функциональной точки зрения. Тем не менее, лучший способ справиться с этим - выполнить длительный процесс в фоновом режиме, чтобы приложение реагировало.

...