Графические функции api windows

Библиотека Интернет Индустрии I2R.ru

Малобюджетные сайты.

Продвижение веб-сайта.

Контент и авторское право.

Графика Windows и API. Создание векторного редактора. Часть 1

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

Как и где рисует Windows

В Windows есть понятия дескрипторов (Handle) окна, дескрипторов контекста устройства и дескрипторов объекта, соответственно английские термины handle window (hWND), handle device context (hDC) и handle object (это общее название). Под hWND понимаются такие элементы как форма, кнопки, панели и т.д., с помощью этого дескриптора элементам передаются сообщения и данные, а вот с помощью hDC производятся графические операции с содержимым самого объекта.

Контекст устройства — структура, которая определяет набор графических объектов, их свойств и способов воздействия на объект. Графические объекты включают перо (pen) для линии, кисть (brush) для заполнения, битовая плоскость (bitmap) для копирования или прокручивания частей экрана, палитра (palette) для определения набора доступных цветов, регион (region) для усечения областей и других действий.

Дескриптор объекта — это вообще независимая штука, она может существовать отдельно от hWND и hDC (эти же работают в паре). К дескрипторам объекта (далее hOBJ) относятся перья системы рисования (Pen — цвет пера, толщина и тип линии), кисть, заполняющая область (Brush — цвет кисти, стиль и вид шаблона заполнения) и т.д.

Для осуществления операций вы всегда должны, затребовать какой — либо дескриптор. Затребовав hDC, вы обязаны вернуть его системе, иначе по истечению времени Windows прекратит все операция рисования и просто зависнет.

Поясним на примере понятия дескрипторов. Лист бумаги назовем оконным элементом, т.е. он имеет hWND, чтобы что-либо на нем нарисовать необходимо, получить его hDC. У вас есть три карандаша разного цвета (красный, черный, зеленый). Взяв карандаш в руки, производится выбор объекта в контекст листа бумаги. Затем, используя методы перемещения карандаша, вы рисуете по поверхности. Вот в принципе и все.

Общий принцип работы (упрощенно) можно свести к следующему:

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

ВНИМАНИЕ! Когда вы создали объект и выбрали его в контекст, сохраните предыдущий объект. Затем после всех своих операций верните его в контекст и удалите созданный объект. Это очень важная операция.

Описание нашего редактора

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

Начинаем проектирование и программирование

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

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

А теперь от теорий перейдем к практике. Прочитайте описание функций и структур API графики, чтобы, далее понять работу программы.

Структуры и константы

Хранит координаты прямоугольника.

Public Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type

Хранит координаты точки.

Public Type POINTAPI
X As Long
Y As Long
End Type

Хранит параметры пера.

Public Type LOGPEN
lopnStyle As Long — стиль пера
lopnWidth As POINTAPI — толщина пера (это структура)
lopnColor As Long — цвет пера
End Type

Хранит параметры кисти.

Читайте также:  Озон windows 10 pro

Public Type LOGBRUSH
lbStyle As Long — стиль кисти
lbColor As Long — цвет кисти
lbHatch As Long — шаблон заполнения
End Type

Константы приведены не все, за полным списком обратитесь в SDK графики MSDN.

Public Const BS_SOLID = 0 — Полная заливка фигуры
Public Const BS_HATCHED = 2 — Стиль установки шаблона
Public Const HS_CROSS = 4 — Шаблон сетки
Public Const HS_BDIAGONAL = 3 — Диагональный шаблон
Public Const PS_SOLID = 0 — Сплошное перо
Public Const WHITENESS = &HFF0062 — Заливка шаблона белым цветом
Public Const SRCCOPY = &HCC0020 — Копирование битовых карт

Полную декларацию описания функций смотрите в исходном тексте. Где пропущено описание типа подразумевается тип Long.

GetDC (hwnd) — Получает дескриптор контекста устройства для указанного hWnd.

CreateCompatibleBitmap (HDC, nWidth, nHeight) — Создает совместимую битовую карту из контекста HDC размерами (nWidth, nHeight).

CreateCompatibleDC (HDC) — Создает совместимый дескриптор контекста из указанного HDC.

ReleaseDC (hwnd, HDC) — Удаляет дескриптор контекста HDC для дескриптора окна hWnd.

SelectObject (HDC, hObject) — Выбирает в контекст HDC объект, задаваемый дескриптором hObject.

PatBlt (HDC, x, y, nWidth, nHeight, dwRop) — Заполняет контекст HDC от координат (x,y,nWidth,hHeight) используя текущую кисть контекста в соответствии с операцией dwRop.

DeleteObject (hObject) — Удаляет дескриптор hObject.

DeleteDC (HDC) — Удаляет контекст HDC.

BitBlt (hDestDC, x, y, nWidth, nHeight, hSrcDC, xSrc, ySrc, dwRop) — Копирует битовую область, из контекста hSrcDC, начиная с координат (xSrc, ySrc) в соответствии с растровой операцией dwRop в битовую область контекста hDestDC в координаты (x, y, nWidth, nHeight).

InvalidateRect (hwnd, pRect As RECT, bErase) — Вызывает событие обновления поверхности окна для дескриптора окна hWnd в области прямоугольника, задаваемого координатами pRect. Если bErase равен истине, то производится очистка фона.

Rectangle (HDC, X1, Y1, X2, Y2) — Рисует прямоугольник в контексте HDC по координатам (X1, Y1, X2, Y2).

Ellipse (HDC, X1, Y1, X2, Y2) — Рисует окружность в контексте HDC по координатам (X1, Y1, X2, Y2).

Описание процедур программы

В форме Visual Basic свойство AutoRedraw установите в True, иначе при выводе виртуального окна будет происходить мерцание. Свойство ScaleMode установите в Pixels, т.к. все функции работаю с пикселями и для других единиц необходимо проводить преобразование.

Первым делом создаем виртуальное окно, процедурой CreateVirtualWindow. Вот её текст.

‘ В этой переменной хранится временный дескриптор контекста окна
Dim CDC As Long
‘ Получаем дескриптор контекста холста
CDC = GetDC(Me.hwnd)
‘ Создаем совместимый дескриптор
MDC = CreateCompatibleDC (CDC)
‘ Создаем совместимую битовую карту с картой битов холста
MBM = CreateCompatibleBitmap (CDC, RectForm.Right, RectForm.Bottom)
‘ Удаляем дескриптор
ReleaseDC Me.hwnd, CDC
‘ Выбираем битовую карту во временный контекст
SelectObject MDC, MBM
‘ Заливка области белым цветом (для простоты)
PatBlt MDC, 0, 0, RectForm.Right, RectForm.Bottom, WHITENESS

Пояснение. Используя функцию GetDC, получаем дескриптор контекста формы через hWND объекта Me. Затем нам надо создать совместимый контекст устройства для нашего виртуального окна, т.к. это должно быть два разных объекта, но с идентичными характеристиками. Все это производится функций CreateCompatibleDC, полученный hDC сохраняем в глобальной переменной MDC типа Long. Так как виртуальное окно, по сути битовая карта, то с помощью функции CreateCompatibleBitmap создаем битовую карту нашего окна с размерами указанными нами заранее (смотрите исходный текст в процедуру Form_Load) и полученный дескриптор сохраняем в глобальной переменной MBM типа Long. Затем, обратите внимание, удаляем временный дескриптор CDC через функцию ReleaseDC, это важная операция. Напоследок выбираем в наш контекст полученную битовую карту с помощью функции SelectObject. Очистку области производим с помощью функции PatBlt.

Уничтожение виртуального окна, производится процедурой DestroyVirtualWindow.

Sub DestroyVirtualWindow()
‘ Удалить битовую карту
DeleteObject MBM
‘ Удалить дескриптор
DeleteDC MDC
End Sub

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

Вывод виртуального окна на экран, процедурой InvalidateCanvas.

Sub InvalidateCanvas()
‘ Используем переменную RectForm, чтобы ускорить операцию получения координат.
‘ Маленькая оптимизация.
Call InvalidateRect(Me.hwnd, RectForm, False)
‘ Заливка области белым цветом (для простоты)
PatBlt MDC, 0, 0, RectForm.Right, RectForm.Bottom, WHITENESS
‘ Перерисовать фигуры
Call DrawFigures(MDC, SHAPE_RECT)
Call DrawFigures(MDC, SHAPE_ELLIPSE)
‘ Вывести виртуальное окно на форму
BitBlt Me.HDC, RectForm.Left, RectForm.Top, RectForm.Right, RectForm.Bottom, MDC, 0, 0, SRCCOPY
End Sub

Читайте также:  Управление лицензиями windows 10

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

Отображение фигуры на виртуальном окне, процедурой DrawFigures.

Sub DrawFigures(HDC As Long, IndexFigure As Byte)
‘ Дескрипторы пера
Dim NewPen, OldPen As Long
‘ Дескрипторы кисти
Dim NewBrush, OldBrush As Long
‘ Создаем перо из структуры заданной фигуры
NewPen = CreatePenIndirect(Figures(IndexFigure).Pen)
‘ Создаем кисть из структуры заданной фигуры
NewBrush = CreateBrushIndirect(Figures(IndexFigure).Brush)
‘ Выбираем созданные дескрипторы пера и кисти в контекст
OldPen = SelectObject(HDC, NewPen)
OldBrush = SelectObject(HDC, NewBrush)
Select Case Figures(IndexFigure).Shape
Case SHAPE_RECT:
Call ShapeRect(HDC, Figures(IndexFigure).Coord)
Case SHAPE_ELLIPSE:
Call ShapeEllipse(HDC, Figures(IndexFigure).Coord)
End Select
‘ Выбираем в контекст старые кисть и перо
‘ ЭТО ОЧЕНЬ ВАЖНАЯ ОПЕРАЦИЯ
SelectObject HDC, OldBrush
SelectObject HDC, OldPen
‘ Удаляем новые кисть и перо
‘ И ЭТО ОЧЕНЬ ВАЖНАЯ ОПЕРАЦИЯ
DeleteObject (NewBrush)
DeleteObject (NewPen)
End Sub

Пояснение. В данную процедуру передается дескриптор контекста и индекс типа фигуры, которую необходимо нарисовать. Далее используя функции CreatePenIndirect и CreateBrushIndirect, создаем из структур новое перо и кисть. Сохраняем полученные дескрипторы объектов в локальных переменных (после окончания процедуры они нам будут не нужны) NewPen и NewBrush типа Long. Выбираем новое перо и кисть в контекст, сохраняя при этом предыдущие значения в переменных OldPen и OldBrush, функцией SelectObject. Рисуем фигуры. Возвращаем предыдущие значения. Удаляем дескрипторы новых объектов. Все остальное вы поймете из исходных текстов, прилагаемых к статье.

Используя все вышеописанное, вы можете расширять возможности стандартных элементов Windows или писать свои. Например, добавить рисунки в ComboBox или ListBox. Поле для усовершенствований и оптимизации не ограниченно. Буду рад, если вы найдете интересные варианты и сообщите мне. В последующих статьях мы рассмотрим, как по щелчку мыши выбрать фигуру, переместить её или изменить размеры с помощью маркеров (как во всех векторных редакторах). Последняя статья будет посвящена разработке справочной системы для нашего проекта в двух стандартных системах справки — скомпилированном HTML и WinHelp.

Введение в создание оконных приложений

Программирование в Windows основывается на использовании функций API (Application Program Interface, т.е. интерфейс программного приложения).

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

Программный интерфейс приложений

Windows API (Application Programming Interfaces) — общее наименование целого набора базовых функций интерфейсов программирования приложений операционных систем семейств Microsoft Windows.

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

Все основные функции Windows объявляются в заголовочных файлах. Главный заголовочный файл называется WINDOWS.H, и в этом файле содержится множество ссылок на другие заголовочные файлы.

Основное отличие функций API от библиотечных функций С: код библиотечных функций связывается с кодом программы пользователя, а код функций API остается вне программы пользователя в динамически подключаемых библиотеках (DLL – Dynamic Link Library), что позволяет создавать более компактный и эффективный код приложений.

При запуске программы Windows она взаимодействует с операционной системой посредством процесса «динамического связывания». Большая часть динамических библиотек DLL расположена в каталоге WINDOWS\SYSTEM.

При компоновке программы для Windows, чтобы сделать ее исполняемой, необходимо связывать ее с «библиотеками импорта», поставляемыми в составе среды программирования (IDE – Integrated Development Environment), которой может являться, в частности, Microsoft Visual Studio. Библиотеки импорта содержат имена всех функций Windows из динамически подключаемых библиотек и ссылки на них. Компоновщик использует эту информацию для создания в исполняемом EXE-файле таблицы, которую Windows использует при загрузке программы для настройки адресов функций API.

Графический интерфейс пользователя

Графический интерфейс пользователя (Graphical User Interface, GUI) еще называют «визуальный интерфейс» или «графическая оконная среда».

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

Читайте также:  Windows 10 professional 10240 что это

Пользователям не надо тратить слишком много времени на то, чтобы научиться пользоваться компьютером и составлять новые программы. Система Windows способствует этому, поскольку все программы для Windows выглядят и воспринимаются одинаково.

Любая программа для Windows имеет окно — прямоугольную область на экране, в котором приложение отображает информацию и получает реакцию от пользователя. Окно идентифицируется заголовком. Большинство функций программы запускается посредством меню. Слишком большой для экрана объем информации может быть просмотрен с помощью полос прокрутки. Некоторые пункты меню вызывают появление окон диалога, в которые пользователь вводит дополнительную информацию.

Программирование Windows-приложений тесно связано с понятиями объектно-ориентированного программирования. Главным объектом в операционной системе Windows является окно. Окно может содержать элементы управления: кнопки, списки, окна редактирования и др. Эти элементы, по сути, также являются окнами, но обладающими особыми свойствами.

Активное окно – окно, получающее реакцию от пользователя в данный момент.

Основными элементами окна являются

  • 1 — строка заголовка title bar
  • 2 — строка меню menu bar
  • 3 — системное меню system menu
  • 4 — кнопка сворачивания окна minimize box
  • 5 — кнопка разворачивания окна maximize box
  • 6 — рамка изменения размеров sizing border
  • 7 — клиентская область client area
  • 8 — горизонтальная и вертикальная полосы прокрутки scroll bars

Многозадачность

Многозадачность ( multitasking ) — свойство операционной системы обеспечивать возможность параллельной (или псевдопараллельной) обработки нескольких процессов.

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

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

Операционная система не сможет реализовать многозадачность без управления памятью. Так как одни программы запускаются, а другие завершаются, память фрагментируется. Операционная система Windows имеет средства управления фрагментами памяти.

Процессы и потоки

Процессом ( process ) называется экземпляр программы, загруженной в память. Экземпляр программы может создавать потоки ( thread ), которые представляют собой последовательность инструкций на выполнение.

Выполняются не процессы, а именно потоки. Любой процесс имеет хотя бы один поток. Этот поток называется главным (основным) потоком приложения .

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

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

Дескрипторы

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

Примеры дескрипторов, описанных в заголовочном файле windows.h

Контекст устройства

GDI – графический интерфейс устройства. Функции системной библиотеки GDI32.dll используются для вывода графики на экран.

Дескриптор контекста устройства — это паспорт конкретного окна для функций GDI. Контекст устройства фактически является структурой данных, которая внутренне поддерживается GDI. Он связан с конкретным устройством вывода информации (принтер, дисплей). Что касается дисплея, то в данном случае контекст устройства обычно связан с конкретным окном на экране.

Оцените статью