所以,这是我刚读过的讨论: http://www.mail-archive.com/delphi@delphi.org.nz/msg02315.html
BeginUpdate和EndUpdate不是我需要的程序......
覆盖API调用?我试图从ComCtrls单元获取更新程序代码,但没有找到坚果......
如果唯一的文字发生变化,也许你可以在这里发布一个代码来修复状态栏compoent的闪烁?我的意思是 - 像TextUpdate或某种TCanvas方法或PanelsRepaint ......?
闪烁是由此代码引起的:
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);
有什么想法吗?
有这个链接评论(http://www.stevetrefethen.com/blog/UsingTheWSEXCOMPOSITEWindowStyleToEliminateFlickerOnWindowsXP.aspx)并且有程序可行(没有任何闪烁),但是它是VVVVVVVEEEEEERRRRRRYYYYYY慢!
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
另外 - 目标不是表单,而是StatusBar ...如何将此方法分配给状态栏?
答案 0 :(得分:2)
您应该检查将 TWinControl.DoubleBuffered 属性设置为TStatusBar组件的 True 是否可以正常工作。您也可以尝试将此属性启用到状态栏的父组件(可能是TForm)。这是一个盲目的镜头 - 从这里无法访问编译器。另一个想法是覆盖 WM_ERASEBKGND 消息而不调用继承的。使用谷歌后找到的第一个例子:here。
-----作者评论后更新
我终于可以访问编译器了,现在它正在运行。我们可以使用WS_EX_COMPOSITED解决方案。您所需要的只是基于TCustomStatusBar创建自己的自定义组件,或者只是创建一个类包装器并在运行时创建状态栏实例。像这样:
TMyStatusBar = class( TCustomStatusBar )
protected
{ Flickering work-around }
procedure CreateParams( var Params : TCreateParams ) ; override ;
end ;
TForm1 = class( TForm )
// (...)
private
FStatusBar : TMyStatusBar ;
// (...)
end ;
-------------
procedure TMyStatusBar.CreateParams( var Params : TCreateParams ) ;
begin
inherited ;
if CheckWin32Version( 5,1 ) then
Params.ExStyle := Params.ExStyle or WS_EX_COMPOSITED ;
end ;
-------------
{ Creating component in runtime }
procedure TForm1.FormCreate( Sender : TObject ) ;
begin
FStatusBar := TMyStatusBar.Create( Self ) ;
FStatusBar.Parent := Self ;
FStatusBar.Panels.Add ;
end ;
它对我有用。祝你好运!
答案 1 :(得分:2)
我能给你的最重要的建议是将状态栏更新的数量限制为每秒10或20。更多只会造成不必要的闪烁,对用户没有任何好处 - 他们无法处理快速的信息。
好的,这样就可以了:如果你想为状态栏使用WS_EX_COMPOSITED
扩展样式,你基本上有三种选择:
创建一个覆盖CreateParams()
方法的后代类,并将其安装到IDE中(如果您不希望将其作为IDE中自己的组件),请创建状态栏。运行时。
在另一个单元中创建一个名为TStatusBar
的后代类,覆盖CreateParams()
方法,并使用状态栏控件将ComCtrls
之后的单位添加到表单单元。这将创建您自己的TStatusBar
类的实例,而不是ComCtrls
中的实例。有关该技术的另一个示例,请参阅this answer,希望它足够清楚。
使用vanilla TStatusBar
类并在运行时设置WS_EX_COMPOSITED
扩展样式。
我更喜欢第三个选项作为最容易实验的选项,所以这里是示例代码:
procedure TForm1.FormCreate(Sender: TObject);
var
SBHandle: HWND;
begin
// This only works on Windows XP and above
if CheckWin32Version(5, 1) then begin
// NOTE: the following call will create all necessary window handles
SBHandle := StatusBar1.Handle;
SetWindowLong(SBHandle, GWL_EXSTYLE,
GetWindowLong(SBHandle, GWL_EXSTYLE) or WS_EX_COMPOSITED);
end;
end;
修改强>
如果您希望代码正确支持最近的Windows版本和视觉样式,您甚至不应该考虑自己处理WM_ERASEBKGND
- 通常的技术涉及该方法的空处理程序,并在{{中绘制背景1}}处理程序。这不适用于WM_PAINT
等标准控件,因为必须在某处某处绘制背景。如果您只是跳过TStatusBar
处理程序中的背景图,则需要使用所有状态栏中所有状态栏的所有者绘制的面板,否则将无法绘制背景,并且下面的窗户将闪耀。此外,所有者绘制的面板的代码可能非常复杂。
同样,更好的做法是解决发布代码中的混乱问题,将工作人员与显示代码正确分开,并将状态栏文本的更新速度降低到合理的水平。在每秒超过监视器更新数量方面没有任何意义,即使这对于游戏和类似的可视化也是明智的。