Device context windows что это

Device context windows что это

Чтобы дать возможность прикладным программам помещать вывод данных в память, а не отправлять их на реальное устройство (диск), используется специальный контекст устройства для операций с точечным рисунком, называемый контекст устройства в памяти (memory device context) . Контекст устройства (DC) в памяти дает возможность системе рассматривать часть памяти как виртуальное устройство. Это — массив битов в памяти, который приложение временно может использовать, чтобы сохранить данные о цвете для точечных рисунков, созданных на обычной поверхности для рисования . Поскольку точечный рисунок совместим с устройством, контекст устройства (DC) в памяти также иногда относится к совместимому контексту устройства (compatible device context) .

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

Исходный точечный рисунок в контексте устройства (DC) в памяти — просто символ — заместитель. Его размеры — цепь один пиксель за другим пикселем. Прежде, чем приложение может начать рисовать, оно должно выбрать точечный рисунок с соответствующей шириной и высотой в DC при помощи вызова функции SelectObject. Чтобы создать точечный рисунок соответствующих размеров, используйте функцию CreateBitmap, CreateBitmapIndirect или CreateCompatibleBitmap. После того, как точечный рисунок выбран в контексте устройства (DC) в памяти, система заменяет одноразрядный массив на массив, достаточно большой, чтобы сохранить информацию о цвете для заданного прямоугольника пикселей.

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

При отображении на экране аппратно-независимого (DIB) или аппратно-зависимого точечного рисунка (DDB), созданного из DIB палитрой устройства , Вы можете улучшить быстродействие, в котором образ рисуется, выстраивая логическую палитру, которая соответствует макету системной палитры. Чтобы сделать это, вызовите функцию GetDeviceCaps со значением NUMRESERVED , чтобы получить число зарезервированных цветов в системе. Затем вызовите функцию GetSystemPaletteEntries и заполните первые и последние NUMRESERVED /2 записи логической палитры соответствующими цветами системы. Например, если NUMRESERVED — 20, Вы должны заполнить первые и последние 10 записей логической палитры системными цветами. Затем заполнить оставшиеся 256- NUMRESERVED цвета логической палитры (в нашем примере, оставшиеся 236 цветов) цветами из DIB и установить флажок PC_NOCOLLAPSE на каждом из этих цветов.

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

GDI — Graphics Device Interface

Graphics device interface (GDI — графический интерфейс устройства) — это базовая система вывода двухмерной графики Windows. Под системой вывода графики мы будем понимать рисование геометрических фигур и вывод текста. Т.е. GDI отвечает за рисование картинок и вывод текста.

Читайте также:  Установка linux centos рядом с windows 10

GDI написана на winAPI, т.е. это просто набор функций и структур на чистом C. Сначала мы познакомимся с GDI, а потом рассмотрим более сложные системы вывода двухмерной графики: GDI+ и Direct2D.

Device context — контекст устройства

Контекст устройства (Device context) — это то место, куда рисуется графика, плюс средства рисования графики. Мы можем получить контекст устройства окна и тогда можем рисовать что-то в этом окне. Можно получить контекст устройства принтера и рисовать фигуры на печатаемой странице. Контекст устройства позволяет использовать кисти (brushes), перья (pens), картинки (bitmaps) для вывода графики.

Получение контекста устройства окна

Для получения контекста устройства окна используется описатель окна (HWND). Контекст устройства представлен в программе переменной типа HDC — переопределённый указатель на void. Для получения контекста устройства окна используется функция getDC:

!1?HDC hDC = GetDC(hWnd);?1!

После этого можно использовать переменную hDC для рисования в окне hWnd. После завершения рисования, нужно «отпустить» контекст устройства с помощью функции ReleaseDC. Давайте посмотрим на код, который рисует прямоугольник и выводит текстовую строку в окне:

!1?WNDCLASS wc; wc.style = CS_OWNDC; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)(6); wc.lpszMenuName = 0; wc.lpszClassName = L»class»; RegisterClass(&wc); HWND hWnd = CreateWindow(L»class», L»GDI», WS_OVERLAPPEDWINDOW, 100, 100, 300, 300, NULL, NULL, hInstance, NULL); ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); HDC hDC = GetDC(hWnd); // получение контекста устройства Rectangle(hDC, 50, 50, 200, 200); // рисование прямоугольника TextOut(hDC, 5, 5, L»Привет. «, 9); // вывод текста ReleaseDC(hWnd, hDC); // освобождение контекста устройства?1!

Функция Rectangle принимает следующие аргументы: контекст устройства, координаты левого верхнего угла, координаты правого нижнего угла.

Функция TextOut принимает аргументы: контекст устройства, координаты левого верхнего угла текста, текстовая строка, количество символов в текстовой строке.

Функция Release принимает аргументы: окно, контекст устройства.

В данном примере рисование происходит до основного цикла while. Т.е. рисование будет произведено только один раз. Если вы свернёте и развернёте окно, то нарисованное исчезнет. Просто нужно поместить рисование внутрь цикла while, как это сделано в прикреплённом проекте gdi_0.1, тогда окно будет перерисовываться при каждой итерации.

Вывод графики в нескольких окнах

Когда мы заполняем структуру WNDCLASS, чтобы зарегистрировать класс окна программы в Windows, мы заполняем поле style:

Данное поле задаёт стиль класса окон. Значение CS_OWNDC говорит, что для каждого окна данного класса будет создан свой контекст устройства.

Рассмотрим пример gdi_0.2. В данной программе создаётся два окна:

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

!1?HWND hWnd2 = CreateWindow(L»class», L»GDI2″, 0, 300, 100, 200, 200, NULL, NULL, hInstance, NULL);?1!

У каждого окна этой программы свой контекст устройства:

!1?HWND hWnd1 = CreateWindow(L»class», L»GDI», WS_OVERLAPPEDWINDOW, 100, 100, 200, 200, NULL, NULL, hInstance, NULL); HWND hWnd2 = CreateWindow(L»class», L»GDI2″, 0, 300, 100, 200, 200, NULL, NULL, hInstance, NULL); ShowWindow(hWnd1, nCmdShow); UpdateWindow(hWnd1); ShowWindow(hWnd2, nCmdShow); UpdateWindow(hWnd2); MSG msg; HDC hDC = GetDC(hWnd1); Rectangle(hDC, 50, 50, 100, 100); TextOut(hDC, 5, 5, L»Первое окно. «, 14); ReleaseDC(hWnd1, hDC); while (true) < if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) < if (msg.message == WM_QUIT) break; TranslateMessage(&msg); DispatchMessage(&msg); >hDC = GetDC(hWnd2); Rectangle(hDC, 50, 50, 100, 100); TextOut(hDC, 5, 5, L»Второе окно. «, 14); ReleaseDC(hWnd2, hDC); >?1!

Читайте также:  Стандартный блокнот windows возможности

Рисование в первом окне происходит до основного цикла. Поэтому, если свернуть, а затем развернуть окно, то всё нарисованное исчезнет. Рисование во втором окне происходит при каждой итерации основного цикла.

Заключение

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

В основном мы будем рисовать графику в главном цикле — такой вывод графики больше подходит для игр. Но это нехарактерно для программ Windows. Чуть позже мы познакомимся со стандартным способом использования GDI в Windows программах.

Контекст устройства отображения

В многозадачной операционной системе семейства Windows отсутствует возможность прямого бесконтрольного вывода на экран (как это было во времена MSDOS), тут все подчинено некоему регламенту. С целью обеспечения возможности вывода на устройство (экран, принтер, память) одновременно от множества источников (приложений), в Windows был создан специализированный механизм под названием контекст устройства (device context, DC) и подмножество обеспечивающих его работу функций. Указанные функции определяют размер клиентской области, шрифт, цвета и другие GDI-атрибуты и возвращают (предоставляют) приложению так называемый дескриптор контекста устройства (Device Context Descriptor). Поскольку контекст устройства является одним из основополагающих понятий в понимании механизмов вывода информации на устройство, я постараюсь дать некоторое количество определений для погружения в тему:

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

В операционной системе Windows существует несколько типов контекстов устройства, а именно:

  • Контекст устройства отображения (display);
  • Контекст устройства печати (printer);
  • Контекст устройства памяти (memory, CompatibleDC);
  • Контекст информационного устройства (information);
  • если приложение создает/получает собственный контекст для отрисовки в собственном окне, такой контекст называется контекстом устройства отображения.
  • если приложению необходимо выполнить операцию ввода-вывода на аппаратное устройство (экран, принтер, память), такой контекст называется контекстом устройства печати, контекстом устройства памяти или контекстом информационного устройства.

Нас же в рамках данной статьи интересует контекст устройства отображения:

Существует несколько типов контекста отображения:

  • Контекст отображения класса окна (class display context);
  • Общий контекст отображения (common display context);
  • Личный контекст отображения (private display context);
  • Контекст отображения окна (window display context);
  • Родительский контекст отображения (parent display context);

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

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

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

Читайте также:  Новое сочетание клавиш windows 10

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

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

Атрибут контекста Значение по умолчанию Функция для изменения Функция для получения
Режим отображения (Mapping mode) MM_TEXT SetMapMode GetMapMode
Начало координат окна (Window origin) (0,0) SetWindowOrgEx GetWindowOrgEx
Начало координат области вывода (Viewport Origin) (0,0) SetViewportOrgEx GetViewportOrgEx
Протяженность окна (Window extent) (1,1) SetWindowExtEx GetWindowExtEx
Протяженность области вывода (Viewport extent) (1,1) SetViewportExtEx , SetMapMode GetViewportExtEx
Перо (Pen) BLACK_PEN SelectObject SelectObject
Кисть (Brush) WHITE_BRUSH SelectObject SelectObject
Шрифт (Font) SYSTEM_FONT SelectObject SelectObject
Битовый образ (Bitmap) NOT SelectObject SelectObject
Текущая позиция пера (Current pen position) (0,0) MoveToEx , LineTo , PolylineTo , PolyBezierTo GetCurrentPositionEx
Режим фона (Background mode) OPAQUE SetBkMode GetBkMode
Цвет фона (Background color) Обычно Белый (по Панели управления) SetBkColor GetBkColor
Цвет текста (TextColor) Обычно Черный (по Панели управления) SetTextColor GetTextColor
Режим рисования (Drawing mode) R2_COPYPEN SetROP2 GetROP2
Режим растяжения (Stretching mode) BLACKONWHITE SetStrethBltMode GetStrethBltMode
Режим закрашивания многоугольников (Polygon filling mode) ALTERNATE SetPolyFillMode GetPolyFillMode
Межсимвольный интервал (Intercharacter spacing) 0 SetTextCharacterExtra GetTextCharacterExtra
Начало координат кисти (Brush origin) (0,0) SetBrushOrgEx GetBrushOrgEx
Область отсечения (Clipping region) Not . Окно (рабочая область) с обновляемым регионом обрезается. SelectObject , SelectClipRgn GetClipBox

Обычно данная структура содержит значения по умолчанию, определенные разработчиками из Microsoft.

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

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

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

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