Troubleshooting TAdvProgressBar: Fixing Common Rendering and Update Bugs

Written by

in

Building Dynamic Multi-Step Loading Bars Using TAdvProgressBar

When executing long-running database operations, complex file exports, or multi-stage API integrations in Delphi, a standard progress bar often falls short. Users get frustrated when a bar jumps wildly from 0% to 100% or stalls indefinitely during a hidden sub-task. To provide a premium user experience, you need a progress indicator that reflects multiple distinct phases of execution.

TMS Software’s TAdvProgressBar is the ideal component for this task. Moving far beyond the standard Windows progress bar, it supports custom styling, step-by-step text overlays, and complex visual segments. This article provides a technical guide to building a dynamic, multi-step loading bar using TAdvProgressBar. Step 1: Establish Your Multi-Step Architecture

To prevent your user interface from freezing and to keep your progress bar accurate, you must break your main task into distinct, measurable segments. Hardcoding progress values directly into your business logic creates brittle code. Instead, define your steps using a clear data structure.

A clean approach uses an enum for the states and a record to hold metadata for each step.

type TProcessStep = (psFetchData, psValidateRecords, psProcessCalculations, psExportToDisk); TStepDetail = record Description: string; Weight: Integer; // Percentage of the total process this step takes end; const StepConfigs: array[TProcessStep] of TStepDetail = ( (Description: ‘Fetching records from database…’; Weight: 20), (Description: ‘Validating data integrity…’; Weight: 15), (Description: ‘Running analytical calculations…’; Weight: 50), (Description: ‘Writing export payload to disk…’; Weight: 15) ); Use code with caution. Step 2: Configure TAdvProgressBar for Multi-Step Feedback

Drop a TAdvProgressBar onto your form. To make it look dynamic and informative, configure the following properties in the Object Inspector or at runtime:

Min and Max: Set Min to 0 and Max to 100 to work with percentages.

ShowPercentage: Set to False. We will display custom descriptive text instead of raw numbers.

TextPosition: Set to tpContent to overlay the current step description directly inside the bar.

Format: Set to %s so it renders our custom string explicitly.

Stacked: If you want to show segmented blocks visually, look into the Stacked properties, though for a continuous multi-step bar, a smooth gradient usually works best. Step 3: Implement the Thread-Safe Progress Controller

Long-running tasks must run in a background thread (using TThread.CreateAnonymousThread or TTask from the Parallel Programming Library) so the UI remains responsive. Because UI components are not thread-safe, use TThread.Synchronize or TThread.Queue to update TAdvProgressBar.

Here is a robust implementation of a background processor updating the multi-step progress bar dynamically:

procedure TFormMain.StartMultiStepProcess; begin // Reset the progress bar before starting AdvProgressBar1.Min := 0; AdvProgressBar1.Max := 100; AdvProgressBar1.Position := 0; AdvProgressBar1.Text := ‘Initializing…’; TThread.CreateAnonymousThread( procedure var CurrentStep: TProcessStep; AccumulatedProgress: Integer; StepProgress: Integer; I: Integer; begin AccumulatedProgress := 0; // Loop through each logical phase of production for CurrentStep := Low(TProcessStep) to High(TProcessStep) do begin // Update UI to show the start of a new step TThread.Synchronize(nil, procedure begin AdvProgressBar1.Text := StepConfigs[CurrentStep].Description; end); // Simulate processing the current step for I := 1 to 10 do begin Sleep(150); // Simulate workload // Calculate current progress within the specific step’s weight StepProgress := Round((I / 10)StepConfigs[CurrentStep].Weight); // Update the progress bar smoothly TThread.Queue(nil, procedure begin AdvProgressBar1.Position := AccumulatedProgress + StepProgress; end); end; // Securely lock in the completed step’s total weight AccumulatedProgress := AccumulatedProgress + StepConfigs[CurrentStep].Weight; end; // Finalize UI state upon completion TThread.Queue(nil, procedure begin AdvProgressBar1.Position := 100; AdvProgressBar1.Text := ‘Process Complete!’; ShowMessage(‘Data processing finished successfully.’); end); end).Start; end; Use code with caution. Step 4: Add Visual Polish and Dynamic Color Shifts

TAdvProgressBar shines when it comes to visual customization. You can enhance user experience further by changing the bar’s color theme based on the active step. For example, you might want a soft blue for data gathering, a vibrant orange during intense calculations, and a solid green upon completion.

Inside your TThread.Synchronize block where the step description changes, dynamically adjust the ProgressColor and ProgressColorTo properties:

TThread.Synchronize(nil, procedure begin AdvProgressBar1.Text := StepConfigs[CurrentStep].Description; // Change bar colors dynamically based on the current milestone case CurrentStep of psFetchData: begin AdvProgressBar1.ProgressColor := clWebSkyBlue; AdvProgressBar1.ProgressColorTo := clWebDodgerBlue; end; psProcessCalculations: begin AdvProgressBar1.ProgressColor := clWebLightSalmon; AdvProgressBar1.ProgressColorTo := clWebCoral; end; psExportToDisk: begin AdvProgressBar1.ProgressColor := clWebPaleGreen; AdvProgressBar1.ProgressColorTo := clWebLimeGreen; end; end; end); Use code with caution. Conclusion

A standard progress bar tells users that something is happening, but a dynamic multi-step loading bar built with TAdvProgressBar tells them exactly what is happening. By assigning mathematical weights to your software’s execution phases, running operations on background threads, and leveraging custom text overlays, you transform a boring waiting period into an informative, highly polished user experience. If you would like to expand on this implementation,

Implement a secondary sub-progress bar for individual file chunks.

Learn how to apply advanced TMS Styles and skins to match modern UI designs.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *