So, here is the discussion I have just read:
http://www.mail-archive.com/delphi@delphi.org.nz/msg02315.html
BeginUpdate and EndUpdate is not thi procedures I need …
Overriding API Call? I tried to get Update procedures code from ComCtrls unit, nut did not found…
Maybe you could post here a code to fix thi flicker of statusbar compoent if the only text changes in it? I mean – something like TextUpdate or some kind of TCanvas method or PanelsRepaint … ?
The flickering is caused by this code:
Repeat
BlockRead(Fp, BuffArrayDebug[LineIndex], DataCapac, TestByteBuff); // DataCapac = SizeOf(DWORD)
ProgressBar1.StepIt;
if RAWFastMode.Checked then begin // checks for fast mode and modifyies progressbar
if BuffArrayDebug[LineIndex] = 0 then begin ProgressBar2.Max := FileSize(Fp) - DataCapac; ProgressBar2.Position := (LineIndex + 1) * DataCapac; LineDecr := True; end;
end else begin ProgressBar2.Max := FileSize(Fp); ProgressBar2.Position := LineIndex * DataCapac end;
if PreviewOpn.Caption = '<' then begin // starts data copying to preview area if expanded
Memo1.Lines.BeginUpdate;
if (LineIndex mod DataCapac) > 0 then HexMerge := HexMerge + ByteToHex(BuffArrayDebug[LineIndex]) else
begin
Memo1.Lines.Add(HexMerge); HexMerge := '';
end;
Memo1.Lines.EndUpdate;
end;
StatusBar1.Panels[0].Text := 'Line: ' + Format('%.7d',[LineIndex]) + ' | Data: ' + Format('%.3d',[BuffArrayDebug[LineIndex]]) + ' | Time: ' + TimeToStr(Time - TimeVarStart); StatusBar1.Update;
if FindCMDLineSwitch(ParamStr(1)) then begin
TrayIcon.BalloonTitle := 'Processing ' + ExtractFileName(RAWOpenDialog.FileName) + ' and reading ...';
TrayIcon.BalloonHint := 'Current Line: ' + inttostr(LineIndex) + #10#13 + ' Byte Data: ' + inttostr(TestByteBuff) + #10#13 + ' Hex Data: ' + ByteToHex(TestByteBuff);
TrayIcon.ShowBalloonHint;
end;
Inc(LineIndex);
Until EOF(Fp);
Any ideas?
There was comment with this link ( http://www.stevetrefethen.com/blog/UsingTheWSEXCOMPOSITEWindowStyleToEliminateFlickerOnWindowsXP.aspx ) and there is procedure that works ( no flickering whastsoever ), BUT IT IS VVVVVVVEEEEEERRRRRRYYYYYY SLOW!
1 type
2 TMyForm = class(TForm)
3 protected
4 procedure CreateParams(var Params: TCreateParams); override;
5 end;
6
7 ...
8
9 procedure TMyForm.CreateParams(var Params: TCreateParams);
10 begin
11 inherited;
12 // This only works on Windows XP and above
13 if CheckWin32Version(5, 1) then
14 Params.ExStyle := Params.ExStyle or WS_EX_COMPOSITED;
15 end;
16
Also – the target is not the form, but the StatusBar … how to assign this method to statusbar?
The most important advise I can give you is to limit the number of status bar updates to maybe 10 or 20 per seconds. More will just cause unnecessary flicker, without any benefit for the user – they can’t process the information that fast anyway.
OK, with that out of the way: If you want to use the
WS_EX_COMPOSITEDextended style for the status bar you have basically three options:Create a descendent class that overrides the
CreateParams()method and either install this into your IDE or (if you don’t want to have it as its own component in the IDE) create the status bar at runtime.Create a descendent class with the same name
TStatusBarin another unit, override theCreateParams()method, and add this unit afterComCtrlsto the form units using status bar controls. This will create an instance of your ownTStatusBarclass instead of the one inComCtrls. See this answer for another example of the technique, hopefully its clear enough.Use the vanilla
TStatusBarclass and set theWS_EX_COMPOSITEDextended style at runtime.I prefer the third option as the easiest one to experiment with, so here’s the sample code:
Edit:
If you want your code to properly support recent Windows versions and visual styles you should not even think of handling
WM_ERASEBKGNDyourself – the usual technique involves an empty handler for that method, and drawing the background in theWM_PAINThandler. This doesn’t really work for standard controls likeTStatusBar, as the background has to be drawn somewhere. If you just skip the background drawing in theWM_ERASEBKGNDhandler you will need to use owner-drawn panels spanning all of the status bar, otherwise the background simply won’t be drawn, and the window underneath will shine through. Besides, the code for the owner-drawn panel would probably be very complex.Again, a much better course of action would be to untangle the mess in your posted code, properly separate worker from display code, and reduce the update speed of your status bar texts to something reasonable. There just isn’t any sense at all in going past the number of monitor updates per second, and even this is sensible only for games and similar visualizations.