[Закрыто] Как сделать, чтобы не мигала картинка при перерисовке окна?

agent007new

В программировании гуя не очень силен. Написал вот такую программку на шарпе
 

protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
base.OnPaint(e);
e.Graphics.Clear(System.Drawing.Color.White);

e.Graphics.FillRectangle(System.Drawing.Brushes.Aqua, x, y, x_size, y_size);
}

protected override void OnMouseDown(System.Windows.Forms.MouseEventArgs e)
{
base.OnMouseDown(e);

if (e.X >= x && e.X <= x + x_size && e.Y >= y && e.Y <= y + y_size)
{
Cursor = System.Windows.Forms.Cursors.Hand;
x_mouse = e.X;
y_mouse = e.Y;
captured = true;
}
}

protected override void OnMouseUp(System.Windows.Forms.MouseEventArgs e)
{
base.OnMouseUp(e);
Cursor = System.Windows.Forms.Cursors.Default;
captured = false;
}

protected override void OnMouseMove(System.Windows.Forms.MouseEventArgs e)
{
base.OnMouseMove(e);
if (captured)
{
x += (e.X - x_mouse);
x_mouse = e.X;

y += (e.Y - y_mouse);
y_mouse = e.Y;

Invalidate;
}
}

private int x = 50;
private int y = 50;

private int x_size = 50;
private int y_size = 50;

private int x_mouse = 0;
private int y_mouse = 0;

private bool captured = false;

Здесь приведен кусок кода, который я добавил к стандартному WinForms проекту. Смысл этого кода в том, чтобы таскать закрашенный квадрат мышкой. Но при таскании окно "мигает". Как правильно нужно делать такую вещь, чтобы не было миганий?

agaaaa

Есть как минимум два пути:
- стирать старый квадрат, рисовать новый, при этом не трогать фон;
- рисовать в буфер, затем выводить;
П.С. мне казалось, что в последних версиях все контролы по умолчанию рисуются в буфер перед выводом, поэтому мерцание кажется странным

agent007new

- стирать старый квадрат, рисовать новый, при этом не трогать фон;
Этот вариант пробовал: полностью картинка не мигает, но квадрат все равно мигает

agent007new

Разобрался: по умолчанию отключена двойная буферизация, если ее включить, перестает мигать

kill-still

2ойная буферизация это не панацея и не решение.
это на твоём компе в данный момент времени при таких вот обстоятельствах не моргает.
а при других обстоятельствах она и на твоём компе может начать моргать, не говоря уже об абстракном юзвере в вакуумею.
все нормальные гуи рисуются сначала на конве, а потом уже на экран.
лучше подсмотри как это делается где-нибудь и сделай также.

Dasar

все нормальные гуи рисуются сначала на конве, а потом уже на экран.
а двойная буферизация делает это как-то по другому?

kill-still

Там много всяких нюансов.
даже если вся отрисовка исключительно OnPaint всё равно иногда моргает.

Dasar

Там много всяких нюансов.
пример?

kill-still

ну, допустим даже если отдельно взятый контрол сам по себе при отрисовке себя не моргает, ничто не сможет помешать моргать ему целиком когда ты их накидаешь десяток-другой на форму, загрузишь проц на 100%, и вот у тебя форма, начинаешь её ресайзить, а на ней на месте контрола то серый квадратик, то контрол появляются.

kill-still

Хотя конечно если каких-то объектов много, то стоит уже задуматься их целиковым классом делать с общей отрисовкой.

Serab

Тема нюансов не раскрыта. Неясно чем отличается от рисования в контекст в памяти с последующим битблт.

Serab

на конве
Oh, shi

Dasar

и вот у тебя форма, начинаешь её ресайзить, а на ней на месте контрола то серый квадратик, то контрол появляются.
так такое получается, если для контрола double-buffer-включили, а для формы забыли...

kill-still

В VCL (по крайней мере) double-buffered наследуется от овнера по дефолту. также как и шрифт, и т.д.
А в шарпе я ни бум-бум. Я про свой опыт общения с гуёвинами в целом.

Serab

В VCL (по крайней мере) double-buffered наследуется от овнера по дефолту. также как и шрифт, и т.д.
Что значит наследуется? Если включен у родителя, то включен и у дочернего окна. Так говорил как раз о том случае, когда у родителя выключен double-buffering, а у дочернего окна - включен.
ps. Владелец (owner) - не то же самое, что и родитель (parent от owner'а сомневаюсь, что что-то наследуется.
Оставить комментарий
Имя или ник:
Комментарий: