Доступ к объекту Graphics вне обработчика Paint

Доступ к объекту Graphics вне обработчика Paint

В некоторых редких случаях может понадобиться доступ к объекту Graphics вне контекста обработчика события Paint. Предположим, например, что нужно перерисовать небольшой круг с центром в точке (х, у), где был выполнен щелчок кнопки мыши. Чтобы получить действительный объект Graphics в рамках контекста обработчика событий MouseDown, можно, например, вызвать статический метод Graphics.FromHwnd(). Имея опыт использования Win32, вы можете знать, что HWND является структурой данных, представляющей окно Win32. В рамках платформы .NET наследуемое свойство Handle извлекает соответствующую структуру HWND, которую затем можно использовать в качестве параметра для Graphics. FromHwnd().

private void MainForm_MouseDown(object sender, MouseEventArgs e) {

 // Получение объекта Graphics через Hwnd.

 Graphics g = Graphics.FromHwnd(this.Handle);

 // Рисование круга 10*10 по щелчку мыши.

 g.FillEllipse(Brushes.Firebrick, e.X, e.Y, 10, 10);

 // Освобождение объектов Graphic, созданных напрямую.

 g.Dispose();

}

Эта логика отображает круг за пределами обработчика OnPaint(), но очень важно понимать, что когда выполняется обновление формы, все такие круги стираются! Это разумно, поскольку соответствующая визуализация выполнялась в контексте события MouseDown. Значительно лучшим подходом Является создание в обработчике события MouseDown нового типа Point, который добавляется к некоторой внутренней коллекции (например, List‹T›), и только затем вызывается Invalidate(). Тогда обработчик события Раint может просто "пройти" по коллекции и перерисовать каждый Point.

public partial class MainForm: Form {

 // Используется для хранения всех Point.

 private List‹Point› myPts = new List‹Point›();

 publiс MainForm() {

  …

  this.MouseDown += new MouseEventHandler(MainForm_MouseDown);

 }

 private void MainForm_MouseDown(object sender, MouseEventArgs e) {

  // Добавление в коллекцию.

  myPts.Add(new Point(e.X, e.Y));

  Invalidate();

 }

 private void MainForm_Paint(object sender, PaintEventArgs e) {

  Graphics g = e.Graphics;

  g.DrawString("Привет GDI+", new Font("Times New Roman", 20), new SolidBrush(Color.Black), 0, 0);

  foreach(Point p in myPts) g.FillEllipse(Brushes.Firebrick, p.X, p.Y, 10, 10);

 }

}

При таком подходе уже отображенные круги будут оставаться на месте, поскольку графическая визуализация обрабатывается в рамках события Paint. На рис. 20.1 показано окно тестового запуска этого приложения.

Рис 20.1. Простое графическое приложение

Исходный код. Проект BasiсPaintForm размещен в подкаталоге, соответствующем главе 20.

Поделитесь на страничке

Следующая глава >

Похожие главы из других книг

Tux Paint

Из книги 200 лучших программ для Linux автора Яремчук Сергей Акимович

Tux Paint Tux Paint (http://www.tuxpaint.org/) – это простая и интересная программа для рисования, ориентированная на детей от трех лет. Изначально она была создана для Linux, но сейчас портирована и на другие системы – Microsoft Windows, Mac OS X и BeOS. Интерфейс сделан ярким и максимально понятным ребенку,


Paint

Из книги Работа на ноутбуке автора Садовский Алексей

Paint Есть в Windows и графический редактор, хотя лучше применить выражение «простейшая программа для рисования». Называется она Paint (рис. 17.4). Рис. 17.4. Программа Microsoft PaintОна так же стара, как и сама Windows. С первой версии в Paint, конечно, были внесены определенные изменения, однако


Класс Graphics

Из книги Язык программирования С# 2005 и платформа .NET 2.0. [3-е издание] автора Троелсен Эндрю

Класс Graphics Класс System.Drawing.Graphics – это "вход" в функциональные возможности визуализации GDI+. Этот класс не только представляет поверхность, на которой вы хотите разместить изображение (например, поверхность формы, поверхность элемента управления или область в памяти), но


Сеансы Paint

Из книги Windows Vista. Мультимедийный курс автора Мединов Олег

Сеансы Paint Наиболее общий способ получения объекта Graphics заключается во взаимодействии с событием Paint. Вспомните из предыдущей главы о том, что класс Control определяет виртуальный метод с именем OnPaint(). Чтобы форма отображала графические данные на своей поверхности, вы можете


Освобождение объекта Graphics

Из книги Эффективное использование C++. 55 верных способов улучшить структуру и код ваших программ автора Мейерс Скотт

Освобождение объекта Graphics Если вы внимательно читали несколько последних страниц, то могли заметить, что в некоторых примерах программного кода непосредственно вызывается метод Dispose() объекта Graphics, тогда как в других примерах этого не делается. Поскольку тип Graphics


Paint

Из книги Основы объектно-ориентированного программирования автора Мейер Бертран

Paint Первой в группе Стандартные расположена программа Paint, которая позволяет создавать, просматривать и редактировать рисунки (рис. 6.1). Рис. 6.1. Окно программы PaintВ левой части рабочего окна расположена панель, включающая 16 инструментов. Чтобы выбрать инструмент, нужно


Правило 49: Разберитесь в поведении обработчика new

Из книги UNIX: взаимодействие процессов автора Стивенс Уильям Ричард

Правило 49: Разберитесь в поведении обработчика new Когда оператор new не может удовлетворить запрос на выделение памяти, он возбуждает исключение. Когда-то он возвращал нулевой указатель, и некоторые старые компиляторы все еще так и поступают. Вы можете столкнуться с таким


Присоединение ссылки к объекту

Из книги Системное программирование в среде Windows автора Харт Джонсон М

Присоединение ссылки к объекту Классы, появляющиеся в этой лекции, не имели подпрограмм - у них были только атрибуты. Как отмечалось, такие классы почти бесполезны, так как у них нет способа изменить значение атрибутов. Необходимы способы модификации ссылок, не


Пример: уведомление с использованием sigwait вместо обработчика

Из книги Программирование на языке Ruby [Идеология языка, теория и практика применения] автора Фултон Хэл

Пример: уведомление с использованием sigwait вместо обработчика Хотя программа из предыдущего примера работает правильно, можно повысить ее эффективность. Программа использует sigsuspend для блокировки в ожидании прихода сообщения. При помещении сообщения в пустую очередь


Выполнение обработчика завершения и выход из него

Из книги Справочник по PHP автора

Выполнение обработчика завершения и выход из него Обработчик завершения, или блок __finally, выполняется в контексте блока или функции, работу которых он отслеживает. Управление может переходить от оператора завершения к следующему оператору. Существует и другая


11.2.1. Отправка объекту явного сообщения

Из книги Введение в QNX/Neutrino 2. Руководство по программированию приложений реального времени в QNX Realtime Platform автора Кёртен Роб

11.2.1. Отправка объекту явного сообщения В статическом языке вы считаете очевидным, что имя вызываемой функции «зашито» в программу, это часть исходного текста. Динамический язык обладает в данном отношении большей гибкостью.При любом вызове метода вы посылаете объекту


Установка пользовательского обработчика ошибок

Из книги Разработка ядра Linux автора Лав Роберт

Установка пользовательского обработчика ошибок set_error_handlerУстановка пользовательского обработчика ошибок.Синтаксис:string set_error_handler(string error_handler)Функция возвращает имя функции, ранее определенной в качестве обработчика ошибок (или FALSE при ошибке), и устанавливает, в


Отключение обработчика прерывания

Из книги автора

Отключение обработчика прерывания Когда вы закончили с обработчиком прерывания, вы можете пожелать уничтожить связь между ним и вектором:int InterruptDetach(int id);Я сказал «можете», потому что обрабатывающие прерывания потоки, как правило, используются в серверах, а серверы


Регистрация обработчика прерывания

Из книги автора

Регистрация обработчика прерывания Ответственность за обработчики прерываний лежит на драйверах устройств, которые управляют определенным типом аппаратного обеспечения. С каждым устройством связан драйвер, и если устройство использует прерывания (а большинство


Освобождение обработчика прерывания

Из книги автора

Освобождение обработчика прерывания Для освобождения линии прерывания необходимо вызвать функциюvoid free_irq(unsigned int irq, void *dev_id);Если указанная линия не является совместно используемой, то эта функция удаляет обработчик и запрещает линию прерывания. Если линия запроса на


Написание обработчика прерывания

Из книги автора

Написание обработчика прерывания Следующее описание является типичным для обработчика прерывания.static irqreturn_t intr_handler(int irq, void *dev_id, struct pt_regs *regs);Заметим, что оно должно соответствовать аргументу, который передается в функцию request_irq(). Первый параметр, irq, — это численное