Блокировка перерисовки окна на время обновления его дочерних окон.
(+) Неудачный эффект WM_SETREDRAW.
(+)(+) Существует реализация WM_SETREDRAW по умолчанию, но вы можете сделать и лучше.
В нашем "фреймворке" это достигается несколько иначе:
https://bitbucket.org/lulinalex/mindstream/src/1fab802d0af4a7a2166f7181501dd79b86f989ce/Examples/1160/afwBaseControl.pas?at=B284&fileviewer=file-view-default
https://bitbucket.org/lulinalex/mindstream/src/580b4f9e3aeba03a771bf30bc270037f071c37d9/Examples/1160/vcmBase.pas?at=B284&fileviewer=file-view-default
Цитирую:
(+) Неудачный эффект WM_SETREDRAW.
(+)(+) Существует реализация WM_SETREDRAW по умолчанию, но вы можете сделать и лучше.
В нашем "фреймворке" это достигается несколько иначе:
https://bitbucket.org/lulinalex/mindstream/src/1fab802d0af4a7a2166f7181501dd79b86f989ce/Examples/1160/afwBaseControl.pas?at=B284&fileviewer=file-view-default
https://bitbucket.org/lulinalex/mindstream/src/580b4f9e3aeba03a771bf30bc270037f071c37d9/Examples/1160/vcmBase.pas?at=B284&fileviewer=file-view-default
{$If not defined(NoVCL)} procedure TafwBaseControl.WndProc(var Message: TMessage); //#UC START# *47E136A80191_48BD1975029B_var* var PS: TPaintStruct; //#UC END# *47E136A80191_48BD1975029B_var* begin //#UC START# *47E136A80191_48BD1975029B_impl* // Два case тут для удобства отладки case Message.Msg of WM_ERASEBKGND, WM_NCPAINT, WM_PAINT: begin case Message.Msg of WM_ERASEBKGND: if InUpdating then begin Message.Result := 1; {don't erase background} Exit; end;//InUpdating WM_NCPAINT: if InUpdating then Exit; WM_PAINT: if InUpdating then begin BeginPaint(Handle, PS); EndPaint(Handle, PS); Exit; end;//InUpdating end;//case Message.Msg inherited; end;//WM_ERASEBKGND else inherited; end;//case Message.Msg //#UC END# *47E136A80191_48BD1975029B_impl* end;//TafwBaseControl.WndProc {$IfEnd} //not NoVCL function TafwBaseControl.InUpdating: Boolean; //#UC START# *48C6C421015B_48BD1975029B_var* //#UC END# *48C6C421015B_48BD1975029B_var* begin //#UC START# *48C6C421015B_48BD1975029B_impl* Result := HandleAllocated AND Visible AND afw.IsObjectLocked(Self); // без проверки на видимость, WM_PAINT'ы приходят невидимым контролам, в результате // имеем прогрузку дерева при ненужной отрисовке, например. //#UC END# *48C6C421015B_48BD1975029B_impl* end;//TafwBaseControl.InUpdating ... class function TvcmAFW.IsObjectLocked(aControl : TObject = nil): Boolean; //override; {-} begin Result := ((g_Dispatcher <> nil) AND g_Dispatcher.FormDispatcher.Locked){ OR ((g_MenuManager <> nil) AND g_MenuManager.UnlockInProgress)}; if Result and (aControl <> nil) then g_Dispatcher.FormDispatcher.AddControlForInvalidate(aControl); end; ...
Цитирую:
WM_PAINT: if InUpdating then begin BeginPaint(Handle, PS); EndPaint(Handle, PS); Exit; end;//InUpdating
WM_PAINT:
ОтветитьУдалитьif InUpdating then
begin
BeginPaint(Handle, PS);
EndPaint(Handle, PS);
Exit;
Это для валидации? А нельзя ли использовать ValidateRect?
bq. Это для валидации? А нельзя ли использовать ValidateRect?
УдалитьНу по-другому мне не удалось заставить Windows не слать WM_PAINT снова. Я вроде ValidateRect пытался использовать. Не помогало. Точно - не помню уже.
А вообще идея понятна. Я как раз тоже дошёл до этого :)
ОтветитьУдалитьНу т.е. глобальные процедуры:
BeginUpdate(AWinControl)/EndUpdate(AWinControl), которые подменяют WndProc для контрола и сохраняют счётчик (чтобы можно было использовать вложенные вызовы). Пока как черновик, ещё не тестировал..
Ну как-то так :-) Я просто решил поделиться своими наработками. Раз уж тема всплыла.
Удалить