由于Vcl.Forms.TScrollBox
没有BeginUpdate
/ EndUpdate
方法,我使用此代码来减少在TScrollBox
容器的子节点的查看器中加载文档时的闪烁:
procedure MyLockWinControl(const WC: Vcl.Controls.TWinControl; ALock: Boolean);
begin
if (not Assigned(WC)) or (WC.Handle = 0) then EXIT;
if ALock then
WC.Perform(WM_SETREDRAW, 0, 0)
else
begin
WC.Perform(WM_SETREDRAW, 1, 0);
RedrawWindow(WC.Handle, nil, 0, RDW_ERASE or RDW_FRAME or RDW_INVALIDATE or RDW_ALLCHILDREN);
end;
end;
procedure TFormMain.LoadDocFile(const ADocFile: string);
begin
Screen.Cursor := crHourGlass;
try
MyLockWinControl(ScrollBox, True);
try
DoLoadDocFile(ADocFile);
finally
MyLockWinControl(ScrollBox, False);
end;
finally
Screen.Cursor := crDefault;
end;
end;
除了在MyLockWinControl(ScrollBox, False);
所以我的问题是:MyLockWinControl
中是否存在错误,或者是否有更好的方法来停止和恢复TScrollBox
中的更新?
答案 0 :(得分:0)
我已经非常可靠地使用了以下代码(使用TScrollBox):
SendMessage(scrollbox.Handle, WM_SETREDRAW, 0, 0);
try
//do some stuff with the scrollbox here
finally
SendMessage(scrollbox.Handle, WM_SETREDRAW, 1, 0);
RedrawWindow(scrollbox.Handle, nil, 0, RDW_ERASE or RDW_INVALIDATE or RDW_FRAME or RDW_ALLCHILDREN);
end;
您的代码(通过MyLockWinControl程序)似乎基本上做同样的事情 - 除了使用Perform(直接向控件发送消息)而不是SendMessage(使用Windows消息队列)。你还提到过你使用的不是TScrollBox的组件,而是一个后代 - 所以这个问题也很适合。
我唯一可以建议的是在代码周围放置一个try / except块并捕获/记录错误。这可以进一步了解问题所在......
答案 1 :(得分:-1)
我尝试的第一件事是通过调用WC.Invalidate替换您对RedrawWindow的调用。
我必须假设TWinControl正在做一些其他的东西,除了API重绘,当你直接调用RedrawWindow时,它不能可靠地完成。