Как сделать paint на c

Обновлено: 07.07.2024

прежде чем рисовать линии и фигуры, отображать текст или отображать изображения с помощью GDI+, необходимо создать Graphics объект. Graphicsобъект представляет GDI+ поверхность рисования, а — объект, используемый для создания графических изображений.

Работа с графикой состоит из двух этапов.

Использование Graphics объекта для рисования линий и фигур, отображения текста или отображения изображений и управления ими.

Создание графического объекта

Графический объект может быть создан различными способами.

Создание графического объекта

Получение ссылки на графический объект в составе PaintEventArgs Paint события формы или элемента управления. Обычно это способ получения ссылки на графический объект при создании кода рисования для элемента управления. Аналогично, объект Graphics можно также получить как свойство объекта PrintPageEventArgs при обработке PrintPage события для PrintDocument .

Вызовите CreateGraphics метод элемента управления или формы, чтобы получить ссылку на Graphics объект, представляющий поверхность рисования этого элемента управления или формы. Используйте этот метод, если требуется рисовать на форме или элементе управления, который уже существует.

Создайте Graphics объект из любого объекта, наследующего от Image . Этот подход удобен, если требуется изменить уже существующий образ.

Следующие разделы содержат сведения о каждом из этих процессов.

PaintEventArgs в обработчике событий Paint

При программировании PaintEventHandler для элементов управления или PrintPage для PrintDocument объект Graphics предоставляется как одно из свойств PaintEventArgs или PrintPageEventArgs .

получение ссылки на объект Graphics из PaintEventArgs в событии Paint

Назначьте переменную для ссылки на Graphics объект, передаваемый как часть PaintEventArgs .

Вставка кода для заполнения формы или элемента управления.

В следующем примере показано, как ссылаться на Graphics объект из PaintEventArgs в Paint событии.

Метод CreateGraphics

Можно также использовать CreateGraphics метод элемента управления или формы для получения ссылки на Graphics объект, представляющий поверхность рисования этого элемента управления или формы.

Создание графического объекта с помощью метода CreateGraphics

Вызовите CreateGraphics метод формы или элемента управления, для которого требуется отобразить графические объекты.

Создание из объекта Image

Кроме того, можно создать графический объект из любого объекта, производного от Image класса.

Создание графического объекта из изображения

Вызовите Graphics.FromImage метод, указав имя переменной изображения, из которой нужно создать Graphics объект.

В следующем примере показано, как использовать Bitmap объект:

Объекты можно создавать только Graphics из неиндексированных .bmp файлов, таких как 16-разрядные, 24-разрядные и 32-разрядные .bmp файлы. Каждый пиксель неиндексированных .bmp файлов содержит цвет, в отличие от точек индексированных .bmp файлов, которые содержат индекс для таблицы цветов.

Рисование фигур и изображений и управление ими

После создания Graphics объект может использоваться для рисования линий и фигур, отображения текста или отображения изображений и управления ими. Объекты Principal, используемые с Graphics объектом:

PenКласс, используемый для рисования линий, структурирования фигур или визуализации других геометрических представлений.

BrushКласс, используемый для заливки областей графических объектов, таких как заполненные фигуры, изображения или текст.

FontКласс — содержит описание фигур, используемых при отрисовке текста.

ColorСтруктура — представляет различные отображаемые цвета.

Использование созданного объекта Graphics

Для рисования нужного объекта выполните действия с соответствующим объектом, приведенным выше.


Всю сознательную программистскую деятельность я увлекался созданием игр и не любил делать редакторы и прочие утилиты. Главным моим редактором почти всегда был Paint. Но для игр, в которых уровень статичен и состоит из тайлов (Марио подобные и прочие танчики), это более-менее оправдано, т.к. одному пикселю из файла уровня, созданного в Paint, соответствует тайл в игре. А что если требуется создать игру, где нет тайлов, а игровая локация состоит из неровных скалистых пещер. Или игру, в которой много движущихся элементов (летающие платформы, лифты, циркулярные пилы, вращающиеся по окружности).

Создавать редактор для таких целей мне по-прежнему не хотелось. О том, как я это решил с помощью Paint опишу в этой статье.

Я не буду приводить названия игр и давать ссылки на них, потому что это не демонстрация и не реклама игр, а описание метода, который в них применяется.

Неровная карта

Первая игра не блещет разнообразием геймплея: играем за некий подводный кораблик, двигающийся с помощью реактивного двигателя, и уворачиваемся от скал и прочих врагов:


Извиняюсь за качество видео, снимали на телефон

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

Уровень из видео показан слева (увеличено в 4 раза):

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

  • Слой объектов, с которыми игрок взаимодействует: земля, эмиттеры и ежики, а также стартовая позиция и выход. Ориентация эмиттеров (могут стрелять в одном из четырех направлений) не задается, она вычисляется при загрузке, исходя из соседних «земельных» пикселей
  • Слой воды (это аркада, поэтому закон сообщающихся сосудов здесь не действует)
  • Слой с бекграундом


Если это сейчас просто так взять и отрендерить (потайлово), то локация будет состоять из гигантских квадратов. Да и количество таких тайлов достаточно велико (61х69 для этой карты). Поэтому был применён другой способ рендеринга (нетайловый), при котором можно отобразить карту за один вызов (на самом деле за три: отдельно воду, бекграунд и финальная склейка). Это благодаря тому, что весь уровень помещается в одну единственную текстуру, назовём её tex_level. И натягивается она на полноэкранный квад (полигон, размером с экран). Перед этим выставляются текстурные координаты в зависимости от виртуальной камеры, которая привязана к персонажу.

Слева – примерно так выглядит текстура tex_level и охват виртуальной камеры. Справа – назначенные текстурные координаты для полноэкранного квада, т. о. на экран попадает кусочек текстуры tex_level.

Вначале текстуру tex_level надо подготовить. Для этого заведём массив под пиксели этой текстуры:

где w – ширина файла с уровнем, h – высота, деленная на 3 (т.к. три слоя).

Теперь в цикле считываем каждый пиксель исходной карты из каждого слоя и в зависимости от цвета (он же и тип тайла) заполняем соответствующие цветовые каналы в пикселе pix, а именно:


Техническая особенность: на самом деле w и h равны ближайшей в сторону увеличения степени двойки для ширины и высоты карты, недостающие пиксели замащиваются красным цветом (земля), а этот цикл можно считать псевдокодом.


Видно, что один и тот же пиксель в массиве может содержать землю, воду и бекграунд. На основе массива pix создается текстура tex_level, сам массив pix нам ещё пригодится.

Слева готовая текстура tex_level, а справа она же, но в игре. Камера в стартовой позиции.

Чтобы было удобнее продвигаться дальше, будем выводить только R канал из tex_level, т.е. только землю.


Для начала нужно избавиться от этих гигантских квадратов. Для этого массив pix перед тем, как его передать в текстуру tex_level следует размыть по Гауссу (радиус размытия подбирался опытным путем). Теперь всё та же локация выглядит уже куда лучше:

Слева земля до размытия, справа после.
Техническая деталь: перед размытием надо растянуть в 2 раза массив pix так, чтобы исходный пиксель занимал бы уже 2х2 пикселя в растянутом массиве.

Но граница земли здесь очень размыта. Для понимания процесса превращения размытой границы в четкую (назовём этот процесс фильтр четкой границы) рассмотрим одномерный случай, т.к. он аналогичный. Тогда размытая граница земли будет выглядеть примерно так:



Вычтем из этого графика 0.5, домножим на какое-нибудь большое число (в данном проекте это 50) и обрежем (операция clamp) по границе [0; 1], т.е. всё, что меньше 0 превращается в 0, а всё, что больше 1 превращается в 1:

В итоге белый цвет не мгновенно переходит в черный (это важно).

Теперь проделаем все эти операции с нашей текстурой tex_level. Пусть в level_color хранится выборка из этой текстуры, тогда фильтр выглядит так: clamp((level_color.r – 0.5) * 50.0, 0.0, 1.0)



Гораздо лучше, а если внимательно присмотреться, то можно увидеть, что на границе раздела двух сред отсутствует алиасинг. Но такая граница слишком гладкая и плавная, давайте же добавим к ней немного шума. Для этого была сгенерирована текстура с шумом Перлина (параметры шума подбирались опытным путем), назовём её noise. Текстурные координаты для выборки из текстуры шума больше во много раз, чем текстурные координаты для tex_level. Это означает, что пока мы в игре видим лишь кусочек текстуры tex_level, шумовая текстура повторяется несколько раз в пределах экрана. Теперь просто сложим выборки из текстуры шума и из tex_level и только потом применим фильтр четкой границы:


В левой части tex_level + noise, в правой части фильтр четкой границы.

Техническая деталь: диапазон значений в текстуре noise от 0 до 1, поэтому к выборке из tex_level следует прибавлять (noise — 0.5) * k, где k – коэффициент возмущения границы (в проекте он равен 0.3).

Теперь осталось просто наложить текстуры. Текстура земли уже есть (это просто обычная текстура), а вот воды еще нет, нужно её сперва подготовить.

Алгоритм абсолютно такой же, как и с землей, только вместо выборки из R канала следует делать выборку из B канала, т.к. именно там и содержится вода. Еще одно отличие – это вместо обычного шума применяется анимированный шум (плавно меняющийся во времени) для создания волн на границе воды и воздуха. Создание анимированного шума выходит за рамки данной статьи. В этом этапе применяем текстуру неба, а роль воды выполняет синий цвет (подбирался опытным путем). Все шаги этапа получения слоя с водой проиллюстрированы ниже:


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

Следующий этап – это рендеринг бекгруанда. На этот раз выборку из tex_level производим из G канала. В этом этапе ничего принципиально нового нет: получаем маску бекграунда и интерполируем текстуру камней (это в данном случае) и текстуру воды из предыдущего этапа. Конечно, есть свои тонкости: на подводную часть бекграунда накладываются дополнительные фильтры, то же самое и для самой воды для придания эффекта толщи воды, но это выходит за рамки статьи. В этом же этапе рендерятся декоративные элементы: рыбки и водоросли. Окончательно слой с бекграундом выглядит так:


Технические подробности: для придания эффекта «шевелящихся водорослей» из-за подводных течений использовалось смещение x-компоненты текстурных координат при рендеринге спрайта с водорослями. Величина этого смещения считывалась всё из той же текстуры с анимированным шумом.

И последний этап – склейка. Получив в начале статьи маску земли, применяем её для интерполяции текстуры земли и слоя с бекграундом. Финальный результат выглядит так:


Развитие идеи. Что если требуется накладывать несколько текстур на землю, тогда просто добавляем ещё один слой, в котором пиксели земли раскрашиваем в 4 разных цвета (можно меньше, но не больше). Из этого слоя создается отдельная текстура-маска (4 цвета в слое – 4 цветовых канала в маске), но тогда придется делать дополнительные пять текстурных выборок вместо одной (одна из маски и 4 из соответствующих текстур земли).

Определение коллизий

Если в тайловых играх коллизии определяются достаточно просто: делаем выборку из массива тайлов и проверяем, попал/не попал в непроходимый тайл. То здесь это будет слишком грубо, т.к. теперь визуально нет тайлов, а есть поверхности под разными углами. Кстати, маска земли в сишном коде недоступна (она является всего лишь одним из этапов вычисления на видеокарте). Но у нас есть массив pix, размытый по Гауссу. В элементах этого массива интересен только младший байт, т.к. именно там хранится земля. Визуально этот массив выглядит так (приведён лишь фрагмент массива, попадающий в камеру, на самом деле в массиве содержится вся карта):


Это отличается от картинки с размытой границей, потому что там применялась билинейная фильтрация, а тут лишь сырые значения массива после размытия.

Значения из этого массива напоминают карту высот, можно подобрать такое значение высоты, которое примерно совпадает с визуальной границей земли (подбираем опытным путем). Для более точного определения высоты необходимо использовать билинейную интерполяцию. А если вычислить три высоты в окрестностях некой точки, то можно довольно точно определить градиент в этой точке, а он совпадает с нормалью к визуальной поверхности земли. Нормаль в этой игре использовалась лишь в одном месте – для огибания реактивной струёй поверхности земли:


Динамичная карта

Итак, первая проблема, поставленная в начале статьи, решена: никаких тайлов не видно, одни неровные скалистые пейзажи. А как быть с движущимися элементами? Это покажет вторая игра – аналог super meat boy:

Здесь много подвижных элементов: циркулярные пилы, двигающиеся по прямой или вращающиеся вокруг центра, перемещающаяся платформа с шипом и пилой, двери, рассыпающиеся тайлы. А пилы ещё имеют разный размер.


Процесс рендеринга полностью аналогичен первой игре, поэтому ограничимся рассмотрением формата карты. Карта из видео выглядит так (увеличено в 5 раз):

Данная карта состоит из шести (!) слоёв (всего в игре есть пять разных типов слоёв, все они здесь представлены). В отличие от предыдущей игры количество слоёв здесь может быть любым. В левом верхнем углу есть набор пикселей (их ровно столько, сколько и слоёв). Они-то как раз и задают тип слоя (это позволяет не заботиться о порядке и количестве слоёв). Первые два слоя очевидны: слой объектов – взаимодействующие элементы с игроком (земля, шипы, пилы, старт, выход, рассыпающиеся тайлы) и слой бекграунда. Четвёртый слой тоже, как и первый, является слоем объектов (4-й пиксель в левом верхнем углу тоже черный). Пришлось вынести некоторые объекты в этот слой, потому что они пересекались с другими объектами (теоретически одинаковых слоёв может быть сколько угодно).

Техническая особенность: в текстуру tex_level помещается только замля и бекграунд (воды в этой игре нет), а все остальные объекты считываются из файла уровня в массив.

  • Перемещающаяся группа. Все тайлы этой группы синхронно перемещаются (зеленый цвет). Группа содержит один главный тайл (сине-зеленый цвет), для которого в другом слое назначается траектория и скорость. В этой карте одна большая группа, в которую входит земля (становится что-то вроде тележки) с шипом и пилой. И четыре одинарных – только одна пила перемещается в каждой из них.
  • Вращающаяся группа (серый цвет)

В пятом слое указываются размеры пил в градациях красного. Если для пилы отсутствует красный пиксель из этого слоя, то размер её берется по умолчанию. А в шестом слое находятся траектории и скорости для перемещающихся групп в градациях серого, ну и скорости и направления для вращающихся пил. В некоторых слоях есть посторонние цвета, которые в данном слое не участвуют, при загрузке карты они просто игнорируются (например, почти во всех слоях есть черные пиксели земли, они были нужны лишь при составлении карты, для навигации относительно них).

Развитие идеи. Теоретически с помощью Paint можно создать карту для 3D-шутера, файл карты будет состоять из матрицы слоёв. Строка этой матрицы соответствует высоте слоя в игре, а в столбцах содержатся слои одного типа. Например, в 1-м столбце будет геометрия карты (один слой – это срез карты на данной высоте), во 2-м столбце можно назначать текстуры с помощью ключевых цветов пеинта, в 3-м расставлять объекты и т.д.

Полный текст программы

PropertyGrid разбор полетов использования
Добрый день. Есть классы который я изменить не могу. Есть достаточно удобный для редактирования.

IComparer. Разбор полетов
Нигде не нашел толкового описания, как именно работает это дело, как расставляет приоритеты и т.п.


Простой векторный графический редактор (разбор полётов)
Всем привет! Меня зовут ashsvis и я программист. Я пытался бороться с этим "недугом", но эта.

Storm23, Техническое задание

  1. Рисовать кистью, карандашом
  2. Строить простые фигуры, такие как линия, прямоугольник, эллипс и т.д.
  3. Стирать произвольную область(Ластик)
  4. Отменять, возвращать последнее действие(undo/redo)
  5. Форматировать холст(растягивать, масштабировать)

Сразу скажу, что хочу разработать, потому что нравится и в целях обучения

Добавлено через 8 минут
Конечно, круто было бы еще добавить сюда заливку цветом, вывод координат в StatusStrip, и вообще двигать и форматировать фигуры, вставлять текст в изображение

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

Скорее это и имел в виду, ибо видел в paint'e

Добавлено через 43 минуты

  1. Model - модель данных, предоставляет данные и реагирует на команды контроллера(Tool), изменяя своё состояние
  2. Tool - текущий инструмент, который предназначен для изменения модели
  3. Canva - контейнер для графического представления данных модели
Модель - это конкретный набор классов. Их нужно разработать. Для начала хотя бы в общем виде.

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

Хорошо, пусть тогда будет абстрактный класс Object , от которого будут наследоваться все классы редактора типа Line, Curve и т. д.
Еще нужен класс, который будет задавать стиль фигурам, то есть прозрачность, толщину кисти.
Тогда делаем класс PaintStyle и наследуем классы Pen и Brush.

Хорошо, пусть тогда будет абстрактный класс Object , от которого будут наследоваться все классы редактора типа Line, Curve и т. д.

Нет, не нужно никаких Line, Curve и т.д.

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

Далее, предлагаю такую модель:

Есть документ - это объект верхнего уровня, и есть абстрактный класс Tool, который может изменять document.
Document хранит слой в виде битмапа.
Tool содержит два метода. Render - выводит текущее изображение, поверх которого рисуется эффект создаваемый tool (например линия). А метод Apply - должен отрисовать результат применения Tool на битмапе Document. Перед отрисовкой нужно создать точку восстановления в UndoRedoManager.

Такая модель думаю подойдет как для простейших инструментов (типа рисования), так и для более сложных (изменение яркости/контраста, выделение области, копирование/сдвиг области и т.д.)

Для пробы создайте один инструмент PenTool который будет рисовать линию (проводимую от руки).
PenTool будет хранить линию в виде GraphicsPath, а в методе Apply - отрисовывать этот GraphicsPath на битмапе.

Создайте эти классы в отдельном проекте, создайте также проект для тестов, также добавьте UndoRedoManager.

Для рисования графических примитивов в оконных приложениях используются 4 основных типа объектов:

  • точка (Pixel);
  • перо (Pen);
  • кисть (Brush);
  • фон (Background).

Точка

Цвет точки задается с помощью функции

COLORREF SetPixel(
_In_ HDC hdc, // дескриптор контекста устройства
_In_ int X, // x-координата точки
_In_ int Y, // y-координата точки
_In_ COLORREF crColor ); // цвет точки

В случае удачного завершения возвращаемое значение функции дублирует цвет точки, в случае ошибки возвращает -1.

RGB

Цвет точки представляет собой 32-битное число, заданное в системе RGB:

Можно также воспользоваться функцией

RGB(
_ Red As Integer, // красный
_ Green As Integer, // зеленый
_ Blue As Integer); // синий

Значения красного, зеленого и синего используются в диапазоне 0…255.

Перо используется для рисования линий и контуров замкнутых фигур. Цвет пера задается функцией

HPEN CreatePen(
_In_ int fnPenStyle, // стиль пера
_In_ int nWidth, // ширина пера (в пикселях)
_In_ COLORREF crColor ); // цвет пера

Стили пера fnPenStyle могут быть заданы согласно таблице

Кисть

Кисть используется для закрашивания замкнутых объектов. Цвет кисти задается с помощью функции

HBRUSH CreateSolidBrush(
_In_ COLORREF crColor ); // цвет кисти

Можно заранее создать несколько кистей и перьев, а затем выбирать нужные с помощью функции

HGDIOBJ SelectObject(
_In_ HDC hdc, // дескриптор контекста устройства
_In_ HGDIOBJ hgdiobj ); // дескриптор объекта

Рисование графических примитивов

Перемещение в указанную точку осуществляется функцией:

BOOL MoveToEx(
_In_ HDC hdc, // дескриптор контекста устройства
_In_ int X, // координата x точки
_In_ int Y, // координата y точки
_Out_ LP POINT lpPoint ); // указатель на структуру POINT

Координаты точки x и у определяются в пикселях относительно левого верхнего угла.
В случае успешного выполнения возвращает ненулевое значение.

Структура POINT имеет вид

typedef struct tag POINT <
LONG x;
LONG y; > POINT , *P POINT ;

Рисование отрезков осуществляется функцией:

BOOL LineTo(
_In_ HDC hdc, // дескриптор контекста устройства
_In_ int nXEnd, // координата x конечной точки
_In_ int nYEnd ); // координата y конечной точки

В случае успешного выполнения возвращает ненулевое значение.

Рисование прямоугольника осуществляется функцией:

BOOL Rectangle(
_In_ HDC hdc, // дескриптор контекста устройства
_In_ int nLeftRect, // x-координата верхнего левого угла
_In_ int nTopRect, // y-координата верхнего левого угла
_In_ int nRightRect, // x-координата нижнего правого угла
_In_ int nBottomRect); // координата нижнего правого угла

Рисование прямоугольника начинается из точки, в которую осуществлено перемещение с помощью функции MoveTo() .
В случае успешного выполнения возвращает ненулевое значение.

Рисование эллипса осуществляется функцией:

BOOL Ellipse(
_In_ HDC hdc, // дескриптор контекста устройства
_In_ int nLeftRect, // x-координата верхнего левого угла
_In_ int nTopRect, // y-координата верхнего левого угла
_In_ int nRightRect, // x-координата нижнего правого угла
_In_ int nBottomRect); // координата нижнего правого угла

Овал


В случае успешного выполнения возвращает ненулевое значение.

Рисование дуги осуществляется функцией:

BOOL ArcTo(
_In_ HDC hdc, // дескриптор контекста устройства
_In_ int nLeftRect, // x-координата верхнего левого угла
_In_ int nTopRect, // y-координата верхнего левого угла
_In_ int nRightRect, // x-координата нижнего правого угла
_In_ int nBottomRect, // y-координата нижнего правого угла
_In_ int nXRadial1, // x- координата конца первого радиуса
_In_ int nYRadial1, // y- координата конца первого радиуса
_In_ int nXRadial2, // x- координата конца второго радиуса
_In_ int nYRadial2 ); // y- координата конца второго радиуса

Дуга


В случае успешного выполнения возвращает ненулевое значение.

Вывод текста в окно

Для вывода текста в поле окна используется функция

BOOL TextOut(
_In_ HDC hdc, // дескриптор контекста устройства
_In_ int nXStart, // x-координата начала вывода текста
_In_ int nYStart, // y-координата начала вывода текста
_In_ LPCTSTR lpString, // указатель на строку текста
_In_ int cchString ); // количество символов для вывода

В случае успешного выполнения возвращает ненулевое значение.

Задать цвет фона под буквами можно с помощью функции

COLORREF SetBkColor(
_In_ HDC hdc, // дескриптор контекста устройства
_In_ COLORREF crColor ); // цвет

Задать цвет букв можно с помощью функции

COLORREF SetЕTextColor(
_In_ HDC hdc, // дескриптор контекста устройства
_In_ COLORREF crColor ); // цвет

В случае неудачного завершения эти функции возвращают константу CLR_INVALID=0xFFFF .

Использование графических функций

HDC BeginPaint(
_In_ HWND hwnd,
_Out_ L P PAINTSTRUCT lpPaint );

При обработке вызова BeginPaint() , Windows обновляет фон рабочей области с помощью кисти, заданной в поле hbrBackground структуры WNDCLASS , описанной здесь. Вызов BeginPaint() делает всю рабочую область действительной (не требующей перерисовки) и возвращает описатель контекста устройства. Контекст устройства описывает физическое устройство вывода информации (например, экран) и его драйвер. Описатель контекста устройства необходим для вывода в рабочую область окна текста и графики.

  • hwnd – дескриптор окна;
  • lpPaint – указатель на структуру PAINTSTRUCT .

Структура PAINTSTRUCT имеет вид

typedef struct tag PAINTSTRUCT <
HDC hdc;
BOOL fErase;
RECT rcPaint;
BOOL fRestore;
BOOL fIncUpdate;
BYTE rgbReserved[32]; > PAINTSTRUCT , * P PAINTSTRUCT ;

  • hdc – дескриптор контекста устройства.
  • fErase – ненулевое значение стирает фон.
  • rcPaint – структура RECT , определяющая верхний левый и нижний правый углы рабочей области.

typedef struct _ RECT <
LONG left; LONG top;
LONG right; LONG bottom; > RECT , * P RECT ;
BOOL EndPaint(
_In_ HWND hWnd,
_In_ const PAINTSTRUCT *lpPaint );

Функция EndPaint() освобождает описатель контекста устройства, после чего его значение нельзя использовать. Возвращает всегда ненулевое значение.

Получение дескриптора контекста устройства осуществляется вызовом функции:

hWnd – дескриптор окна, для которого используется контекст устройства.
Возвращаемое значение – дескриптор контекста устройства.

освобождает контекст устройства hDC для данного окна hWnd , после чего значение контекста устройства нельзя использовать. Возвращает всегда ненулевое значение.

Прошу прощения. Может я что-то не увидел, но какую библиотеку надо подключить? Здравствуйте, Елена, спасибо за Ваш сайт, много интересного. По поводу графики отмечу, что было бы хорошо, если бы здесь было бы упоминание про двойную буферизацию (это помогает избавиться от эффектов мерцания, если такие наблюдаются при рисовании). Вот часть кода из моей программы. 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
switch (message)
//.
case WM_PAINT :
PaintAll(hwnd);
return 0;
case WM_ERASEBKGND:
return 0;
//.
>
return DefWindowProc (hwnd, message, wparam, lparam);
>

namespace e
extern HWND hpicturebox; // это окно где что-то рисуется
>

Читайте также: