C# для профессионалов. Том II
Шрифт:
Более подробно эти новые структуры и методы объекта Graphics будут рассмотрены позже.
Выполнение данного кода приведет к следующему результату:
Экран иллюстрирует два момента. Первое: можно ясно видеть, что понимается под клиентской областью окна. Это белая область, которая была задействована в результате задания свойства
На рисунке показано также, что код сработал правильно. Кажется, что рисование невозможно выполнить проще. К сожалению, если действительно выполнить этот пример, можно будет заметить, что форма ведет себя немного странно. Все нормально, если просто оставить ее на месте или перемещать по экрану с помощью мыши. Попробуйте минимизировать форму а затем восстановить ее. Окажется, что нарисованные формы просто исчезнут. То же самое произойдет, если протащить другое окно через окно этого примера. Еще интереснее будет, если закрыть форму другим окном, так что оно закроет только часть фигур, а затем убрать его снова. Окажется, что временно скрытая часть исчезла и осталась только часть эллипса и часть прямоугольника.
Что же делать? Проблема возникает, если окно или его часть становятся скрытыми по какой-либо причине (например, оно минимизируется или закрывается другим окном), Windows обычно немедленно отбрасывает всю информацию, относящуюся к тому, что там было изображено. Система должна это делать, иначе используемая память для хранения данных экрана будет слишком большой. Типичный компьютер может работать с видеоплатой, настроенной для вывода 1024×768 пикселей, возможно, в режиме с 24-битовым цветом. Мы покажем, что означает 24-битовый цвет позже, но в данный момент можно сказать, что каждый пиксель на экране занимает 3 байта, т. е. 2.25 Мбайт для изображения экрана. Однако нет ничего необычного, если пользователь имеет во время работы более 10 минимизированных окон в своей панели задач, в худшем сценарии 20, каждое из которых занимает весь экран, если оно не минимизировано. Если бы Windows действительно хранил визуальную информацию, которую содержат эти окна, готовую на случай, если пользователь захочет их восстановить, то речь шла бы о 45 Мбайт. Сегодня хорошая графическая карта может иметь 64 Мбайта памяти, но еще пару лет назад 4 Мбайта считалось большим объемом для графической платы, а избыточные данные необходимо было хранить в основной памяти компьютера. Множество людей все еще используют старые машины. Очевидно, что для Windows было бы непрактично управлять интерфейсом своих пользователей подобным образом.
В тот момент, когда какая-либо часть окна становится скрытой, эти пиксели пропадают. Windows замечает, что окно (или некоторая его часть) скрыто, и когда система обнаруживает, что эта область больше не является скрытой, она запрашивает приложение, которое владеет окном, чтобы оно перерисовало его содержимое. Существуют исключения из этого правила, обычно для случаев, когда небольшая часть окна скрыта очень недолго (хорошим примером является выбор элемента из основного меню, когда этот элемент меню раскрывается внизу, временно закрывая часть окна ниже). Однако можно ожидать, что, если часть окна становится скрытой, то приложению придется перерисовать его позже.
Это проблема для нашего примера приложения. Мы поместили код рисования в конструктор
В главе 9 при рассмотрении элементов управления нам ничего этого не нужно было знать, так как стандартные элементы управления достаточно развиты и могут правильно перерисовать себя, когда Windows об этом попросит. Это одна из причин, почему при программировании элементов управления вообще не нужно беспокоиться о реальном процессе рисования.
Рисование фигур с помощью OnPaint
Если приведенное выше объяснение заставило вас подумать, что рисование своего собственного пользовательского интерфейса будет очень сложной задачей, то не стоит волноваться. Это не так. Были приведены различные детали процесса, для того чтобы вы поняли, с какими проблемами столкнетесь. Но заставить приложение перерисовать себя, когда необходимо, — в действительности легкая задача.
Когда возникает необходимость, Windows уведомляет приложение, что требуется выполнить некоторую перерисовку изображения, инициируя событие
Отметим, что метод
В данной реализации метода
Для этого примера может оказаться, что удаление вызова