Остановить и восстановить обновление в TScrollBox?
Поскольку 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
?
2 ответа
Я использовал следующий код довольно надежно (с 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/ кроме и поймать / записать ошибку. Это может дать дополнительное понимание того, в чем заключается проблема...
Первое, что я бы попробовал, это заменить ваш вызов RedrawWindow на вызов WC.Invalidate.
Я должен предположить, что TWinControl делает некоторые вещи в дополнение к перерисовке API, которая не выполняется надежно, когда вы вызываете RedrawWindow напрямую.