Winapi hdc что это

Winapi hdc что это

Все, что необходимо начинающему и опытному программисту

Данные типа HDC представляют собой 32-разрядное целое беззнаковое число. После получения дескриптора контекста программа может использовать функции графического интерфейса, такие как TextOut и DrawText.
Указывать шрифт, цвет текста, цвет фона и расстояние между отдельными символами не нужно, поскольку эти атрибуты являются частью контекста устройства. Если по каким-либо причинам необходимо изменить один из этих атрибутов, то нужно вызвать соответствующую функцию. Перед началом рисования программа должна получить дескриптор контекста устройства. По окончании рисования программа должна освободить дескриптор. После освобождения дескриптор становится недействительным и использоваться не должен. Корректно работающая программа должна получать и освобождать дескриптор во время обработки каждого отдельного сообщения.

Дескриптор контекста устройства может быть получен одним из двух способов: • при обработке сообщений WM_PAINT. В этом случае используются функции BeginPaint и EndPaint. В качестве параметров эти функции принимают дескриптор,окна и адрес структуры PAINTSTRUCT, обычно именуемой как ps. Оконная процедура вызывает функцию BeginPaint в обработчике сообщения WM_PAINT. Функция возвращает в качестве результата дескриптор контекста в переменной типа нос, именуемой обычно hdc. После получения дескриптора контекста можно использовать функции рисования, например, TextOut или DrawText. Вызов функции EndPaint освобождает дескриптор контекста устройства. Процесс обработки сообщения WMPAINT, например в программе HELLOW ИЗ главе 4, будет выглядеть так, как представлено в листинге 5.1.
Листинг 5.1. Обработка сообщения WM PAINT
cmp uMsg, WM_PAINT
j ne next_l
lea EDX, ps
push EDX
push hWnd
call BeginPaint
mov hdc, EAX
push lenText
push offset textMes
push 100
push 100
push hdc
call TextOut
lea EDX, ps
push EDX
push hWnd
call EndPaint
ret

В случае, если сообщение WM_PAINT не обрабатывается, то оно должно передаваться в процедуру обработки сообщений по умолчанию DefWindowProc. Процедура DefWindowProc обрабатывает сообщения WM_PAINT, ВЫЗВаВ ПОДрЯД фуНКЦИИ BeginPaint И EndPaint, как ПОКазаНО в следующем фрагменте кода:
lea EDX, ps
push EDX
push hWnd
call BeginPaint
mov hdc, EAX
lea EDX, ps
push
push hWnd
EDX
call EndPaint
ret

• при обработке сообщений, отличных от WMPAINT, если возникает необходимость рисования, вызвав функцию GetDC.
Освободить дескриптор контекста можно с помощью функции WIN API ReieaseDC. Функция GetDC в качестве параметра принимает дескриптор окна приложения. Функция ReieaseDC в качестве параметров принимает дескриптор окна и дескриптор контекста, ранее созданный через вызов GetDC. Вывод текста и работу с контекстом устройства рисования с помощью функций WIN API BeginPaint и EndPaint мы рассмотрели в главе 4. Поэтому проанализируем второй метод получения дескриптора контекста. Для этого модифицируем наше приложение HELLOW.

Пусть требуется вывести строку текста при нажатии в окне приложения левой кнопки мыши. В этом случае в оконную процедуру необходимо включить обработчик сообщения WMLBUTTONDOWN. ИСХОДНЫЙ текст программы (назовем ее DRAWTEXT) приведен в листинге 5.2.
Листинг 5.2. Исходный текст программы DRAWTEXT
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\gdi32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\gdi32.lib

Для читателей, предпочитающих классический ассемблер без высокоуровневых структур, таких как if-else, while и invoke; приводим исходный текст только что рассмотренного примера. В листинге 5.3 приведен текст программы, где используются только команды ассемблера.

Источник

iVARIOUS

Блог незаурядного человека

Developer от Бога

четверг, 6 июля 2017 г.

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

HPEN CreatePen(
int fnPenStyle,
int nWidth,
COLORREF crColor
);

HGDIOBJ SelectObject(
HDC hdc,
HGDIOBJ hgdiobj
);

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

BOOL MoveToEx(
HDC hdc,
int X,
int Y,
LPPOINT lpPoint
);

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

BOOL LineTo(
HDC hdc,
int nXEnd,
int nYEnd
);

В целом, чтоб нарисовать простую линию, достаточно разместить эти строчки в любом месте откуда видна переменная hwnd, в которой хранится дескриптор окна:

HDC hDC = GetDC (hwnd);

HPEN hPen = CreatePen (PS_SOLID, 3, RGB(255, 0, 0));

Источник

Winapi hdc что это

Типы данных Windows

Типы данных, поддерживаемые Microsoft ® Windows ® используются для определения возвращаемых значений функциями, параметров функций и сообщений и членов структур. Они определяют размер и значение этих элементов.

Булева переменная (должна быть ИСТИНА (TRUE) или ЛОЖЬ (FALSE)). Этот тип объявлен в Windef.h как показано ниже:

Булева переменная (должна быть ИСТИНА (TRUE) или ЛОЖЬ (FALSE)). Этот тип объявлен в Winnt.h как показано ниже:

Байт (8 бит). Этот тип объявлен в Windef.h как показано ниже:

Соглашение о вызовах для функций повторного вызова. Этот тип объявлен в Windef.h как показано ниже:

Переменная, значение которой остается постоянным в ходе выполнения программы. Этот тип объявлен в Windef.h как показано ниже:

32-разрядное беззнаковое целое число. Этот тип объявлен в Windef.h как показано ниже:

DWORDLONG64-разрядное беззнаковое целое число. Этот тип объявлен в Winnt.h как показано ниже:

Тип беззнаковый дальний для точности указателя. Используется тогда, когда производится приведение указателя к дальнему типу, чтобы выполнить арифметические операции над указателями.( Также обычно используется для общих 32-разрядных параметров, которые были расширены до 64 битов в 64-разрядном Windows ).

Источник

Графический интерфейс GDI в Microsoft Windows

2.1. Получение и освобождение контекста отображения

Каждый из перечисленных выше контекстов имеет свои особенности и свое назначение.

Общий контекст отображения

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

Функция BeginPaint возвращает контекст отображения для окна hwnd:

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

Структура PAINTSTRUCT и указатели на нее (различных типов) описаны в файле windows.h:

Рассмотрим назначение отдельных полей структуры PAINTSTRUCT.

Поле hdc после возврата из функции будет содержать идентификатор полученного контекста отображения, который должен передаваться в качестве параметра функциям интерфейса GDI, выполняющим рисование. Можно использовать также значение идентификатора контекста, возвращенное функцией BeginPaint, так как эти значения одинаковые.

Анализируя содержимое поля fErase, приложение может определить, нужно ли перерисовывать фон окна. Если в этом поле находится значение TRUE, фон окна должен быть перерисован. Такая необходимость может возникнуть в том случае, если в классе, на базе которого создано окно, при регистрации не была выбрана кисть для закрашивания фона (поле hbrBackground структуры WNDCLASS).

Мы уже говорили вам в 11 томе «Библиотеки системного программиста», что при обработке сообщения WM_PAINT приложение должно суметь перерисовать все окно или любую его часть. Сообщение WM_PAINT может попасть в функцию окна в том случае, если все окно или его часть требуют перерисовки. Поле rcPaint в структуре PAINTSTRUCT содержит координаты прямоугольной области, расположенной в окне и требующей перерисовки.

Остальные поля зарезервированы для Windows и не используются приложениями.

Контекст отображения, полученный при помощи функции BeginPaint, необходимо освободить перед завершением обработки сообщения WM_PAINT, вызвав функцию EndPaint :

Функции EndPaint передаются те же параметры, что и функции BeginPaint.

Обычно обработчик сообщения WM_PAINT выглядит следующим образом:

Подобный фрагмент кода вы можете найти в приложениях, описанных в одном из предыдущих томов «Библиотеки системного программиста».

Функция GetDC возвращает контекст отображения для окна с идентификатором hwnd:

Полученный таким образом контекст отображения можно использовать для рисования во внутренней области окна (window client region).

Функция ReleaseDC освобождает контекст отображения hdc, полученный для окна hwnd:

Мы еще раз обращаем ваше внимание на необходимость своевременного освобождения общего контекста отображения.

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

Контекст отображения для класса окна

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

В отличие от общего контекста отображения, приложения, однажды получив контекст отображения для класса окна, могут не освобождать его. То есть для контекста этого типа после функций BeginPaint и GetDC можно не вызывать функции EndPaint и ReleaseDC. Если же приложение вызовет функцию EndPaint или ReleaseDC, они не будут ничего делать и сразу вернут управление. Для уменьшения вероятности ошибки мы рекомендуем вам всегда освобождать контекст отображения, даже если это и не требуется для данного типа контекста.

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

Дело в том, что при получении контекста отображения для окна в нем устанавливаются атрибуты области ограничения и начало системы физических координат устройства отображения. Если на базе нашего класса создано несколько окон, при получении ими контекста отображения эти атрибуты «настраиваются» на окно, получившее контекст отображения. Но если на базе класса стиля CS_CLASSDC приложение создало только одно окно, оно может получить контекст отображения для класса окна один раз и не освобождать его.

Зачем используется контекст отображения класса окна?

Личный контекст отображения

Личный контекст отображения можно, получив один раз, никогда не освобождать. Вы можете один раз настроить атрибуты контекста отображения сразу после получения самого контекста и использовать полученный контекст без изменений до завершения работы приложения.

Однако не будет ошибкой, если приложение будет использовать личный контекст отображения как общий, то есть каждый раз при обработке сообщения WM_PAINT (или другого сообщения, обработчик которого занимается рисованием) оно будет получать контекст и затем отдавать его. Соответствующие функции (BeginPaint, EndPaint, GetDC, ReleaseDC) будут возвращать управление, не выполняя никаких действий.

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

Родительский контекст отображения

Родительский контекст отображения используется для дочерних окон. Он позволяет дочерним окнам «унаследовать» атрибуты контекста отображения у родительского окна, что во многих случаях упрощает процедуру настройки этих атрибутов. Например, дочернее окно может использовать для вывода текста тот же шрифт и цвета, что и родительское окно.

Для использования родительского контекста отображения в классе, на базе которого создается дочернее окно, перед регистрацией необходимо указать стиль CS_PARENTDC :

Контекст отображения для окна

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

Особенностью данного контекста является то, что в нем выбрана система координат, начало которой находится в левом верхнем углу окна (всего окна, а не его внутренней области).

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

Контекст физического устройства

В отличие от контекста отображения, контекст физического устройства не получается, а создается, для чего используется функция CreateDC :

Параметр lpszDriver является указателем на строку символов, содержащую имя драйвера, обслуживающего физическое устройство. Имя драйвера совпадает с именем файла *.drv, содержащего сам драйвер и расположенного в системном каталоге Windows.

Параметр lpszOutput указывает на структуру данных типа DEVMODE, используемую при инициализации устройства вывода. Если при работе с устройством нужно использовать параметры, установленные при помощи приложения Control Panel, параметр lpszOutput следует указать как NULL.

Более подробно вопросы работы с принтером будут рассмотрены в отдельной главе этого тома.

В приведенном ниже примере создается контекст устройства для лазерного принтера HP Laserjet III, подключенного к порту LPT1:, причем в системном каталоге Windows для этого принтера установлен драйвер hppcl5a.drv:

Аналогично, для принтера Epson FX-850, подключенного к порту LPT2:, и работающему через драйвер epson9.drv:

Созданный при помощи функции CreateDC контекст устройства следует удалить (но не освободить), вызвав функцию DeleteDC:

Эта функция возвращает TRUE при нормальном завершении и FALSE при возникновении ошибки.

Контекст для устройства DISPLAY

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

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

Есть еще два способа получения контекста для экрана.

Приложение может получить контекст отображения для всего экрана при помощи функции GetDC, указав в качестве параметра значение NULL:

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

Еще один способ связан с использованием функции GetDCEx, описание которой будет приведено ниже.

Информационный контекст

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

Контекст для памяти

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

Созданный таким образом контекст памяти удаляется при помощи функции DeleteDC.

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

Контекст для метафайла

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

Для создания контекста метефайла используется функция CreateMetaFile :

Параметр lpszFileName должен указывать на строку, содержащую путь к имени файла, в который будут записаны команды GDI, или NULL. В последнем случае создается метафайл в оперативной памяти.

После выполнения рисования в контексте метафайла следует закрыть метафайл, вызвав функцию CloseMetaFile :

Эта функция закрывает метафайл для контекста hdc и возвращает идентификатор метафайла. Идентификатор закрытого метафайла использовать нельзя, так как он не содержит никакой полезной информации.

Что можно сделать с полученным идентификатором метафайла?

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

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

Наконец, при помощи функции DeleteMetaFile можно удалить метафайл:

Удаление метафайла с помощью функции DeleteMetaFile делает недействительным идентификатор метафайла hmf и освобождает оперативную память, занятую метафайлом. Если метафайл был создан как обычный дисковый файл, функция DeleteMetaFile не удаляет его с диска.

Функция GetDCEx

Функция возвращает идентификатор полученного контекста отображения или NULL при ошибке.

Параметр hwnd задает идентификатор окна, для которого необходимо получить контекст отображения.

С помощью параметра hrgnClip можно определить область ограничения вывода. Эта область может иметь произвольную форму и являться комбинацией нескольких областей ограничения. Использование областей ограничения будет подробно описано дальше в этой главе.

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

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

Источник

Управление состоянием приложения

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

Самый простой подход — просто поместить все в глобальные переменные. Это хорошо подходит для небольших программ, и многие из примеров пакета SDK используют этот подход. Однако в большой программе она приводит к распространению глобальных переменных. Кроме того, у вас может быть несколько окон, каждая из которых имеет собственную процедуру окна. Отслеживание того, какое окно должно иметь доступ, какие переменные становятся запутанными и подвержены ошибкам.

Функция CreateWindowEx предоставляет способ передачи любой структуры данных в окно. При вызове этой функции в оконную процедуру отправляются следующие два сообщения:

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

Сообщение WM _ Нккреате и WM _ CREATE отправляются до того, как окно станет видимым. Это делает их хорошим местом для инициализации пользовательского интерфейса, например, для определения первоначального макета окна.

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

Winapi hdc что это. appstate01. Winapi hdc что это фото. Winapi hdc что это-appstate01. картинка Winapi hdc что это. картинка appstate01

Элемент лпкреатепарамс структуры CREATESTRUCT является исходным указателем void, указанным в CreateWindowEx. Получите указатель на собственную структуру данных путем приведения лпкреатепарамс.

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

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

Теперь можно написать процедуру окна следующим образом.

Object-Orientedный подход

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

Другими словами, мы хотели бы проделать следующее:

Единственная проблема заключается в том, как подключить MyWindow::WindowProc метод. Функция registerClass ждет, что процедура окна является указателем на функцию. Нельзя передать указатель на функцию-член (не статическую) в этом контексте. Однако можно передать указатель на статическую функцию-член, а затем делегировать ее функции-члену. Ниже приведен шаблон класса, демонстрирующий этот подход:

BaseWindow Класс является абстрактным базовым классом, от которого наследуются определенные классы окон. Например, ниже приведено объявление простого класса, производного от BaseWindow :

Чтобы создать окно, вызовите BaseWindow::Create :

BaseWindow::HandleMessage Для реализации процедуры окна используется чистый виртуальный метод. Например, следующая реализация эквивалентна процедуре окна, показанной в начале модуля 1.

многие из существующих Windows платформ программирования, таких как Microsoft Foundation Classes (MFC) и библиотека atl, используют подходы, похожие на показанные здесь. Конечно, полностью обобщенная платформа, такая как MFC, сложнее, чем этот сравнительно простой пример.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *