Как заставить TProgressBar перестать отставать? - PullRequest
4 голосов
/ 30 июня 2009

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

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

Я замечаю, что это происходит только под Windows Vista. Не уверен, идет ли он также на XP или нет, потому что когда я тестирую его на XP, процесс идет намного быстрее, и он заканчивается слишком быстро. : P Но это может быть или не быть специфичным для Vista. В любом случае, это сводит меня с ума. Кто-нибудь знает как это исправить?

Ответы [ 7 ]

6 голосов
/ 30 июня 2009

У меня есть быстрое, но частичное и не элегантное решение, если вы не возражаете, чтобы индикатор выполнения был желтым вместо зеленого:

  ProgressBar1.SmoothReverse := True;
  ProgressBar1.State := pbsPaused; // for yellow or pbsError for red

Или, если вы не против потерять внешний вид / тему, и вернитесь к плоскому синему:

  UxTheme.SetWindowTheme(ProgressBar1.Handle, ' ', ' ');

Настоящая «проблема», по мнению Microsoft, заключается в том, что вы пытаетесь «превратить» ProgressBar в метр, который, как они утверждают, не является.

Вы также можете попробовать нарисовать это сами; -)

5 голосов
/ 04 мая 2012

Та же проблема в Windows7 !!

Но ответ уже был в одном из старых постов:

Если сделать шаг прогресса назад, задержки не будет !!! Поэтому я реализовал это ..... (и получаю мгновенные обновления)

if(progress < ProgressBar.Max)
then
begin
  ProgressBar.Position := progress+1;
  ProgressBar.Position := progress; //This will set Progress backwards and give an instant update....
end
else
begin //cannot set position beyond max...
  ProgressBar.Max      := progress + 1;
  ProgressBar.Position := progress + 1;
  ProgressBar.Max      := progress; //This will also set Progress backwards also so instant update........
end;
3 голосов
/ 30 июня 2009

Я столкнулся с точно такой же проблемой некоторое время назад. После поиска в Google в течение long времени я обнаружил, что это проблема, относящаяся к Vista. Похоже, это сводится к следующему: Microsoft добавила необычные анимации в элемент управления индикатора выполнения в Vista (то есть движущуюся «подсветку»). Чтобы сделать обновления более плавными, они внедрили своего рода «запаздывание» в перерисовке элемента управления - и это, по сути, наворачивает весь индикатор выполнения. Скорее раздражает, я бы сказал, тем более что вроде бы не найдется достойного решения .

См. Более подробную информацию об ответах Арвида Винкельсдорфа на это сообщение Дискуссионного форума Embarcadero :

То же самое для VB, C ++ и C # так или иначе, так как проблема заключается в Перспектива рисования нового анимированного Индикаторы выполнения. Чтобы обеспечить более гладкий визуальная обратная связь откладывается при движении вперед. Ваше приложение не могу быть уверен, что 100% будет достигнуто в любой момент времени.

Установив положение обратно в меньшее значение, чертеж ProgressBar вынужден отскочить назад. Нет задержки в добраться до позиции меньше, чем ток. Таким образом, у вас будет почти 100% немедленно. После этого установите на максимум, и вы получите ровно 100%.

[...]

Есть похожий глюк при использовании новые стили Vista ProgressBar, такие как PB Paused или PB Error. Если бар все еще движется (часть MS) и ваше приложение устанавливает цвет на паузу SendMessage (как в D2009) сообщение будет проигнорировано ProgressBar.

3 голосов
/ 30 июня 2009

Кроме того, есть несколько сторонних компонентов, которые обеспечивают лучшую реализацию панели индикаторов, которые по-прежнему хорошо работают в Vista.Лично я предпочитаю один из компонентов Raize , который работает довольно хорошо.Он не «запаздывает», как это делает элемент управления Windows, и работает независимо от каких-либо тем.

Если вы действительно не хотите что-то необычное, вы всегда можете создать его самостоятельно, используя панель и форму, выровненную по левому краю.внутри панели.Измените размер tshape, чтобы он был в% от панели, на которой он установлен.

3 голосов
/ 30 июня 2009

Возможно, вы можете попытаться установить положение ProgressBar напрямую, вместо использования процедуры StepIt. Я нахожусь на XP с Delphi 7 здесь, поэтому я не могу проверить это, но, глядя на код TProgressBar, он использует другое сообщение (PBM_SETPOS вместо PBM_STEPIT). Поэтому, возможно, он устанавливает положение индикатора выполнения без анимации.

1 голос
/ 30 июля 2010

У меня была та же проблема, мое решение было переключиться на другой элемент управления, доступный в VCL:

Я решил использовать Range TTrackBar для отображения прогрессии. (со слайдером и измененным размером элемента управления, чтобы скрыть метки диапазона).

Не такой же визуальный (особенно если тематический), но он хорошо подходит моей потребности (без задержки).

0 голосов
/ 30 июня 2017

Вот простое решение:
ProgressBar.max := ProgressBar.max +1; ProgressBar.StepBy(2); ProgressBar.StepBy(-1); ProgressBar.max := ProgressBar.max -1;

...