ПРЕДОТВРАЩЕНИЕ МЕРЦАНИЯ В ПРИЛОЖЕНИЯХ WINDOWS FORMS
Руслан Гибадуллин (КНИТУ-КАИ)

Видео демонстрирует рецепт того, как приготовить приложение, в котором отсутствует эффект мерцания в ходе частой перерисовки окна приложения Windows Forms на C#.

✅ ИСХОДНЫЕ КОДЫ https://bitbucket.org/landwatersun/foru … 210126.zip
✅ РЕКОМЕНДУЕМАЯ КНИГА C#. Справочник. Полное описание языка | Албахари Бен, Албахари Джозеф https://www.ozon.ru/context/detail/id/145563645/

🔹 Двойная буферизация (по первому слайду)
Когда генерируется событие для перерисовки, то сначала окно "стирается" – т.е. все пиксели окрашиваются цветом фона. Затем окрашиваются только те пиксели, цвет которых отличается от цвета фона. Такой двухшаговый алгоритм довольно удобен, поскольку мы перерисовываем только то, что нужно, не беспокоясь о других пикселях. Но, к сожалению, этот алгоритм является основной причиной возникновения мерцания. Например, если пользователь изменяет размеры окна, область окна под дочерними элементами формы сначала полностью очищается, а затем выполняется рисование дочерних элементов. Особенно ярко эффект мерцания проявляется, когда оконная система вынуждена часто обновлять содержимое формы в динамике изменения состояния графических элементов, поскольку в этом случае элементы многократно стираются и рисуются. Первый подход, на пути к устранению мерцания, это предотвращение стирание окна перед вызовом события Paint. При таком подходе важно, чтобы обработчик события Paint явно окрашивал все пиксели графических элементов. Любой из пикселей, который явно не был окрашен нужным цветом, сохранит свой прежний цвет, причем этот цвет не обязательно будет цветом фона. Второй подход, который мы с вами далее применим, это окрашивать каждый из пикселей только один раз. Самый простой способ выполнить это требование – рисовать дочерние элементы сначала в памяти, а затем копировать полученный рисунок. При таком подходе уже не важно – сколько раз окрашивался тот или иной пиксель, поскольку рисование проходит не на экране. Этот прием называется двойной буферизацией.

🔹 Класс Form (по второму слайду)
Класс Form отвечает за представление окна или диалогового окна, которое составляет пользовательский интерфейс приложения. В показанном примере на втором слайде видео создается новый экземпляр класса Form и вызывается метод ShowDialog для вывода формы в виде диалогового окна. Пояснение к некоторым строкам программы:
- свойство FormBorderStyle получает или задает стиль границы формы;
- свойства MaximizeBox и MinimizeBox отвечают за отображение кнопок «Развернуть» и «Свернуть» соответственно в строке заголовка формы;
- свойства AcceptButton и CancelButton задают кнопки в форме, которые сработают при нажатии клавиши «Enter» и «Esc» соответственно;
- методы form1.Controls.Add(button1) и form1.Controls.Add(button2) добавляют элементы button1 и button2 в коллекцию элементов управления формы.
Для справки:
- Windows Forms – интерфейс программирования приложений (API), отвечающий за графический интерфейс пользователя и являющийся частью Microsoft .NET Framework. Данный интерфейс упрощает доступ к элементам интерфейса Microsoft Windows за счет создания обёртки для существующего Win32 API в управляемом коде. Причем управляемый код – классы, реализующие API для Windows Forms, не зависят от языка разработки. То есть программист одинаково может использовать Windows Forms как при написании ПО на C#, С++, так и на VB.Net, J# и др.
- Приложение Windows Forms представляет собой событийно-ориентированное приложение, поддерживаемое Microsoft .NET Framework. В отличие от пакетных программ, большая часть времени тратится на ожидание от пользователя каких-либо действий, как, например, ввод текста в текстовое поле или клика мышкой по кнопке.

🔹 Свойство CreateParams (по третьему слайду)
Свойство CreateParams возвращает параметры, необходимые для создания дескриптора элемента управления. Может показаться забавным, но возвращает оно параметры в формате класса того же имени, что и имя самого свойства. Для справки: дескриптор элемента управления – это уникальный идентификатор, который Windows дает элементу управления в графическом интерфейсе любой программы. Одно из свойств экземпляра класса CreateParams является ExStyle, которое поддерживает расширенные значения внешнего вида и начального состояния, применяемые к элементу управления. Например, задание данному свойству значения 0x2000000 /*WS_EX_COMPOSITED*/, позволит прорисовать всех потомков окна в порядке отрисовки снизу вверх с использованием двойной буферизации. Двойная буферизация позволяет рисовать окно и его дочерние элементы без мерцания.