View Issue Details

IDProjectCategoryView StatusLast Update
0012816LazarusLCLpublic2009-06-13 12:09
ReporterAndrea Mauri Assigned ToPaul Ishenin  
Status closedResolutionfixed 
Product Version0.9.27 (SVN) 
Target Version1.0.0Fixed in Version0.9.27 (SVN) 
Summary0012816: TStatusBar flickering
DescriptionTStatusBar panel text flickers when the text is updated.
Modifications of the panel text appears also if no Application.ProcessMessages is invoked.
In order to reproduce that:
Create a new project, drop a label, a statusbar and a button on the form. Create a panel on the statusbar.
On buttonclick drop the following code:

procedure TForm1.Button1Click(Sender: TObject);
i: integer;
i:= 0;
while i < 10000 do
// Application.ProcessMessages;
  label1.Caption:= Format('Number: %d', [i]);
  statusbar1.Panels[0].Text:= Format('Number: %d', [i]);

Clicking on the button the text in the statusbar panel start to be updated, and it flickers. The text in the caption is updated only at the end of the while do cycle.
If I uncomment the line Application.ProcessMessages both texts in label and in statusbar panel are updated during the while do cycle. The text in the label does not flicker while the text in the statusbar panel flickers.
TagsNo tags attached.
Fixed in Revision18619
Attached Files


Martin Friebe

2008-12-20 11:51

manager   ~0023881

The following was observed under Windows XP, and shows where the 2paint actions (delete / redraw) happen. At least for this specific case:

In lcl\interfaces\win32\ line 460

       if ThemeServices.ThemesEnabled then
       DC := Windows.BeginPaint(Window, @PS);

At this point the whole status bar gets deleted.(Themes apparently enabled). This gets painted within Windows.BeginPaint

Therefore the statusbar show an empty area on the screen until it reaches line 544 (code fro line 530)
     if (ControlDC = 0) or not needParentPaint then
       DCIndex := Windows.SaveDC(PaintMsg.DC);
       MoveWindowOrgEx(PaintMsg.DC, ORect.Left, ORect.Top);
       Windows.GetClipBox(PaintMsg.DC, ClipBox);
       DebugLn('LCL Drawing in DC ', IntToHex(PaintMsg.DC, 8), ' with clipping rect (',
         IntToStr(ClipBox.Left), ',', IntToStr(ClipBox.Top), ';',
         IntToStr(ClipBox.Right), ',', IntToStr(ClipBox.Bottom), ')');
       DeliverMessage(lWinControl, PaintMsg);
       Windows.RestoreDC(PaintMsg.DC, DCIndex);
     if useDoubleBuffer then
       Windows.BitBlt(DC, 0, 0, WindowWidth, WindowHeight, CurDoubleBuffer.DC, 0, 0, SRCCOPY);

- The first IF block is entered (due to controDC = 0).
- The DelieverMessage (inside the IF) will trigger the TStatusBar.Paint
- use DoubleBuffer is true BitBlt Paints the Complet Statusbar (with Panels) in one go onto the screen.

So in this specific case, where DoubleBuffer is actually used, the code at line 460, should not Erase the real Background, but maybe the DoubleBuffer?

Paul Ishenin

2009-02-08 13:06

manager   ~0025188

StatusBar flicks because SB_SETTEXT call cause invalidate of statusbar. MSDN suggests to wait WM_PAINT message and set statusbar text there to reduce amounts of invalidate.

Paul Ishenin

2009-02-09 16:01

manager   ~0025227

Please test and close if ok.

Issue History

Date Modified Username Field Change
2008-12-19 16:57 Andrea Mauri New Issue
2008-12-19 16:57 Andrea Mauri Widgetset => Win32
2008-12-20 11:51 Martin Friebe Note Added: 0023881
2009-01-19 13:47 Vincent Snijders LazTarget => 1.0
2009-01-19 13:47 Vincent Snijders Status new => acknowledged
2009-01-19 13:47 Vincent Snijders Target Version => 1.0.0
2009-02-08 13:06 Paul Ishenin Note Added: 0025188
2009-02-09 16:01 Paul Ishenin Fixed in Revision => 18619
2009-02-09 16:01 Paul Ishenin Status acknowledged => resolved
2009-02-09 16:01 Paul Ishenin Fixed in Version => 0.9.27 (SVN)
2009-02-09 16:01 Paul Ishenin Resolution open => fixed
2009-02-09 16:01 Paul Ishenin Assigned To => Paul Ishenin
2009-02-09 16:01 Paul Ishenin Note Added: 0025227
2009-06-13 12:09 Marc Weustink Status resolved => closed