Например, я должен отключить две кнопки во времени выполнения. После того, как я отключил первую кнопку, это стало серым, второе - это также стало серым. Но я не знаю, как сделать перекрашивание одновременным!
Мне нужно что-то как этот:
Как реализовать это?
Посмотрите сообщение Win32 API WM_SETREDRAW
. Например:
SendMessage(Handle, WM_SETREDRAW, False, 0);
Button1.Enabled := False;
Button2.Enabled := False;
SendMessage(Handle, WM_SETREDRAW, True, 0);
InvalidateRect(Handle, nil, True);
Сообщения не могут быть обработаны, пока ваше приложение снова не войдет в цикл сообщений, поэтому любая попытка изменить/обновить состояние элемента управления, которая полагается на обработку сообщений, не будет работать в рамках одной последовательности кода, которая не "перекачивает" сообщения.
К счастью, элементы управления VCL обычно предоставляют средства для принудительной перерисовки без ожидания обработки сообщений, с помощью метода Update:
Button1.Enabled := False;
Button2.Enabled := False;
Button1.Update;
Button2.Update;
Это работает независимо от необходимости отключения перерисовки формы. Форма все равно не будет перерисовываться, пока ваше приложение не перейдет в цикл обработки сообщений, поэтому отключение перерисовки формы и повторное включение в рамках одной процедуры, которая сама по себе не вызывает обработки сообщений, является пустой тратой времени.
Возможно, это не совсем одновременное перерисовывание двух кнопок, но действительно одновременное перерисовывание двух отдельных элементов управления невозможно без многопоточного кода рисования GUI, который, как мне кажется, выходит за рамки данной проблемы. Вызов Update на двух кнопках таким образом будет настолько близким к одновременному, насколько вам нужно.
Это может помочь: API LockWindowUpdate(Handle: HWND) блокирует отрисовку для хэндла и дочерних элементов.
ex:
procedure TForm1.ColorButtons(); begin LockWindowUpdate(Self.Handle); // Make some stuff LockWindowUpdate(0); end;
После сброса заблокированного хэндла компонент перерисовывается