06. Организация графического пользовательского интерфейса в операционных системах

Тема 6. Организация графического пользовательского интерфейса в операционных системах

Введение и цели лекции

📌 Слайд 1: Организация графического пользовательского интерфейса в операционных системах

  • Курс: Системное программирование
  • Тема 6 (4 академических часа)
  • Лектор: каф. Системного программирования

Графический пользовательский интерфейс (Graphical User Interface, GUI) в современных операционных системах представляет собой многоуровневую систему абстракций, связывающую прикладную логику, оконный менеджер, подсистему рендеринга и драйверы графических адаптеров. Если консольное приложение взаимодействует с операционной системой через последовательные потоки байтов (stdin, stdout, stderr), то GUI-приложение встроено в событийную модель и разделяет общий экранный буфер и устройства ввода с десятками других параллельных процессов.

В рамках системного программирования создание GUI требует понимания того, как операционная система:

  1. Регистрирует оконные классы (WNDCLASSEXW), связывает дескрипторы окон HWND с оконными процедурами и инкапсулирует объекты ядра в пользовательском режиме.
  2. Создает окна верхнего уровня и дочерние элементы управления через системную фабрику CreateWindowExW, передавая параметры инициализации (CREATESTRUCTW) и связывая контекст ООП-объектов через GWLP_USERDATA.
  3. Изолирует и связывает графические ресурсы процесса (дескрипторы окон HWND, меню HMENU, контексты устройств HDC, графические объекты HGDIOBJ).
  4. Преобразует декларативные описания интерфейса (сценарии ресурсов .rc) в скомпилированные двоичные секции исполняемого модуля (.rsrc).
  5. Управляет жизненным циклом модальных и немодальных форм, диспетчеризацией сообщений элементов управления и маршрутизацией команд.
  6. Осуществляет отрисовку: от классического растрирования на CPU через GDI до аппаратного композитинга через Desktop Window Manager (DWM) и Direct2D/Direct3D.

📌 Слайд 2: Учебные вопросы лекции

  1. Архитектура графической подсистемы Windows: GDI, DWM, Direct2D, драйверная модель WDDM.
  2. Оконные классы (WNDCLASSEXW) и фабрика окон CreateWindowExW.
  3. Ресурсы приложений: компиляция .rc, секция .rsrc, иконки, акселераторы.
  4. Меню и маршрутизация команд: главное меню, контекстные меню, сообщение WM_COMMAND.
  5. Диалоговые окна: шаблоны DIALOGEX, модальные vs немодальные диалоги, цикл IsDialogMessage.
  6. Процедура диалога (DLGPROC) и системные элементы управления.
  7. Графический конвейер вывода: контекст устройства (HDC), перья, кисти, шрифты, паттерн SelectObject.
  8. Обработка WM_PAINT, валидация областей окна и устранение мерцания через двойную буферизацию.
  9. Эволюция подсистемы вывода: Direct2D, аппаратно-ускоренный рендеринг и композитинг.

1. Архитектура графической подсистемы операционной системы

📌 Слайд 3: Архитектура графической подсистемы ОС

  • Разделение уровней: Ring 3 (User Mode) и Ring 0 (Kernel Mode).
  • Подсистемы user32.dll (оконный менеджер) и gdi32.dll (графический вывод).
  • Ядерный компонент win32k.sys (в современных ОС разделен на win32kbase.sys, win32kfull.sys).
  • Desktop Window Manager (DWM) и композитная архитектура вывода.
  • Драйверная модель WDDM (Windows Display Driver Model) и GPU.

Исторически в операционных системах семейства Windows NT графическая подсистема претерпела фундаментальную эволюцию. В ранних версиях NT 3.51 оконная подсистема функционировала в виде процесса пользовательского режима (csrss.exe). Переключение контекста между приложением, процессом сервера подсистемы и драйвером видеоадаптера создавало неприемлемые накладные расходы при частой отрисовке и перемещении окон. Начиная с Windows NT 4.0, оконный менеджер (USER) и графический движок (GDI) были перенесены в режим ядра — драйвер win32k.sys, что многократно ускорило системные вызовы за счет устранения межпроцессных переключений Ring 3 $\leftrightarrow$ Ring 3.

В современной архитектуре Windows (Windows 10/11) графический стек разделен на следующие ключевые звенья:

  • Пользовательский режим (Ring 3):
    • user32.dll — управление окнами, меню, диалогами, мышью, таймерами и очередями сообщений.
    • gdi32.dll / gdi32full.dll — программный рендеринг векторных примитивов, шрифтов и растров.
    • d2d1.dll, d3d11.dll, d3d12.dll — библиотеки прямого аппаратного ускорения 2D/3D через GPU.
    • dwm.exe (Desktop Window Manager) — системный композитный оконный менеджер. Каждое окно рисует свой контент в изолированную закадровую поверхность (surface), а DWM собирает финальный кадр рабочего стола с использованием GPU-шейдеров, обеспечивая гладкое наложение, прозрачность и масштабирование без повреждения содержимого перекрытых окон.
  • Режим ядра (Ring 0):
    • win32kbase.sys и win32kfull.sys — ядерные обработчики оконных объектов, очередей сообщений и состояний ввода.
    • dxgkrnl.sys (DirectX Graphics Kernel Subsystem) — системный координатор видеопамяти, виртуализации GPU и диспетчеризации графических команд.
    • Дисплейный драйвер WDDM (KMD, Kernel Mode Driver) — низкоуровневый драйвер производителя видеоадаптера (NVIDIA, AMD, Intel), управляющий аппаратными командными буферами GPU.

📌 Слайд 4: Стек графической подсистемы Windows

  • Иллюстрация прохождения команд отрисовки и событий интерфейса.
  • Взаимодействие Ring 3 библиотек, DWM, Ring 0 ядра (win32k, dxgkrnl) и GPU.

center height:480px


2. Архитектура оконного класса и фабрика окон CreateWindowEx

📌 Слайд 5: Архитектура оконного класса: WNDCLASSEXW

  • Понятие оконного класса: шаблон атрибутов и регистрация в ядре win32k.
  • Структура WNDCLASSEXW: размер cbSize, стили класса style (CS_HREDRAW, CS_VREDRAW, CS_DBLCLKS, CS_OWNDC).
  • Указатель на оконную процедуру: поле lpfnWndProc.
  • Дополнительные байты: cbClsExtra и cbWndExtra.
  • Функция регистрации RegisterClassExW и уникальный атом класса ATOM.

Окно в операционной системе Windows не может существовать само по себе: любое окно создается на базе предварительно зарегистрированного оконного класса. Оконный класс представляет собой структуру ядра, которая определяет фундаментальные свойства окон данного типа: адрес функции обработки сообщений (lpfnWndProc), пиктограмму (hIcon), курсор мыши (hCursor), фоновую кисть заливки (hbrBackground) и меню по умолчанию (lpszMenuName).

 1WNDCLASSEXW wc = { 0 };
 2wc.cbSize        = sizeof(WNDCLASSEXW);
 3wc.style         = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
 4wc.lpfnWndProc   = MainWndProc;
 5wc.cbClsExtra    = 0;
 6wc.cbWndExtra    = sizeof(void*); // Резерв для указателя на C++ объект
 7wc.hInstance     = hInstance;
 8wc.hIcon         = LoadIconW(hInstance, MAKEINTRESOURCEW(IDI_APP_ICON));
 9wc.hCursor       = LoadCursorW(NULL, IDC_ARROW);
10wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
11wc.lpszMenuName  = MAKEINTRESOURCEW(IDR_MAIN_MENU);
12wc.lpszClassName = L"SystemProgrammingWindowClass";
13wc.hIconSm       = LoadIconW(hInstance, MAKEINTRESOURCEW(IDI_APP_ICON_SM));
14
15ATOM classAtom = RegisterClassExW(&wc);
16if (!classAtom) {
17    DWORD err = GetLastError();
18    // Обработка ошибки регистрации
19}

Стили оконного класса (Class Styles)

Поле style структуры WNDCLASSEXW задает системные флаги поведения всех окон, порождаемых данным классом:

  • CS_HREDRAW и CS_VREDRAW — принудительно инвалидируют всю клиентскую область окна при изменении его горизонтального или вертикального размера, генерируя WM_PAINT.
  • CS_DBLCLKS — включает генерацию сообщений двойного клика мыши (WM_LBUTTONDBLCLK). Без этого флага система посылает только два последовательных одиночных клика.
  • CS_OWNDC — выделяет каждому окну данного класса собственный постоянный контекст устройства (HDC), не освобождаемый в общий системный пул кэша.

📌 Слайд 6: Фабрика окон CreateWindowEx и стили окна

  • Функция создания окна: CreateWindowExW.
  • Расширенные стили (dwExStyle): WS_EX_COMPOSITED, WS_EX_LAYERED, WS_EX_TOPMOST.
  • Базовые стили (dwStyle): WS_OVERLAPPEDWINDOW, WS_POPUP, WS_CHILD, WS_VISIBLE.
  • Геометрия: экранные координаты, CW_USEDEFAULT, функция AdjustWindowRectEx.
  • Иерархия: родительское окно hWndParent, дескриптор hMenu.
  • Передача пользовательского контекста lpParam и структура CREATESTRUCTW.

После успешной регистрации класса приложение вызывает системную фабрику окон CreateWindowExW (или макрос CreateWindowW):

 1HWND hWnd = CreateWindowExW(
 2    WS_EX_WINDOWEDGE | WS_EX_ACCEPTFILES, // dwExStyle
 3    L"SystemProgrammingWindowClass",      // Имя зарегистрированного класса
 4    L"Прикладное окно WinAPI",            // Заголовок окна
 5    WS_OVERLAPPEDWINDOW,                  // dwStyle: рамка, кнопки минимизации/закрытия
 6    CW_USEDEFAULT, CW_USEDEFAULT,         // Начальные координаты X, Y
 7    800, 600,                             // Ширина и высота окна
 8    NULL,                                 // Родительское окно (hWndParent)
 9    NULL,                                 // Меню окна (или ID дочернего контрола)
10    hInstance,                            // Дескриптор экземпляра приложения
11    this                                  // lpParam: указатель на C++ объект окна
12);

Внутренний жизненный цикл CreateWindowExW

В процессе выполнения функции CreateWindowExW ядро операционной системы (win32k.sys):

  1. Выделяет ядерную структуру tagWND, сохраняет атрибуты стиля и размеры.
  2. Присваивает окну уникальный дескриптор HWND.
  3. Формирует структуру CREATESTRUCTW, помещая в нее переданный аргумент lpParam.
  4. Синхронно отправляет в оконную процедуру lpfnWndProc сообщения:
    • WM_NCCREATE — создание неклиентской части окна;
    • WM_CREATE — инициализация клиентской части окна (lParam содержит указатель на CREATESTRUCTW).
  5. Возвращает готовый дескриптор HWND в точку вызова. При создании окно создается невидимым, пока не будет явно вызвана функция ShowWindow(hWnd, nCmdShow) и UpdateWindow(hWnd).

Архитектурный мост C++ и WinAPI (GWLP_USERDATA)

Поскольку оконная процедура lpfnWndProc в Си обязана быть свободной или статической функцией, она не имеет неявного указателя this. Для объектно-ориентированной инкапсуляции указатель this передается в параметре lpParam и сохраняется в пользовательской области дескриптора окна:

 1LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
 2    if (msg == WM_CREATE) {
 3        CREATESTRUCTW* cs = (CREATESTRUCTW*)lParam;
 4        SetWindowLongPtrW(hWnd, GWLP_USERDATA, (LONG_PTR)cs->lpCreateParams);
 5        return 0;
 6    }
 7
 8    MyWindow* pThis = (MyWindow*)GetWindowLongPtrW(hWnd, GWLP_USERDATA);
 9    if (pThis) {
10        return pThis->HandleMessage(hWnd, msg, wParam, lParam);
11    }
12    return DefWindowProcW(hWnd, msg, wParam, lParam);
13}

📌 Слайд 7: Оконные классы и создание окон через CreateWindowEx

  • Схема регистрации класса WNDCLASSEXW в ядре.
  • Фабрика окон CreateWindowExW и посылка WM_CREATE.
  • Механизм связывания экземпляра C++ класса через GWLP_USERDATA.

center height:480px


3. Архитектура ресурсов Windows-приложений

📌 Слайд 8: Архитектура ресурсов Windows-приложений

  • Понятие ресурса: неизменяемые структурированные данные, отделенные от машинного кода.
  • Преимущества: локализация (i18n), модификация оформления без перекомпиляции C/C++, кэширование страниц памяти PE.
  • Конвейер компиляции: .rc + .h $\to$ rc.exe $\to$ .res $\to$ link.exe $\to$ секция .rsrc.
  • Типы ресурсов: RT_MENU, RT_DIALOG, RT_ICON, RT_CURSOR, RT_BITMAP, RT_ACCELERATOR, RT_STRING, RT_MANIFEST.

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

Преимущества изоляции ресурсов:

  1. Локализация (L10n / I18n): перевод интерфейса на другие языки осуществляется заменой секции ресурсов без модификации и перекомпиляции исходного кода на C++.
  2. Управление памятью: секция ресурсов .rsrc в PE-файле помечена как доступная только для чтения (IMAGE_SCN_MEM_READ) и разделяемая (IMAGE_SCN_MEM_SHARED). Операционная система отображает ее в память процесса через механизм страниц виртуальной памяти (Memory Mapped Files) и подгружает ресурсы по требованию (on-demand paging).
  3. Безопасность: ресурсы изолированы от исполняемого кода, предотвращая непреднамеренное повреждение структур данных интерфейса ошибками в логике указателей.

📌 Слайд 9: Синтаксис сценариев ресурсов (.rc)

  • Описание идентификаторов в заголовочном файле (resource.h).
  • Структура определения меню: блоки MENU, POPUP, MENUITEM.
  • Таблица акселераторов: маппинг горячих клавиш на команды (ACCELERATORS).
  • Таблица строк (STRINGTABLE): группировка по 16 строк в блоке для быстрого поиска.
  • Манифест приложения (RT_MANIFEST): стили элементов Common Controls v6 и DPI-awareness.
 1// app.rc
 2#include <windows.h>
 3#include "resource.h"
 4
 5IDI_APP_ICON ICON "res\\app.ico"
 6
 7IDR_MAIN_MENU MENU
 8BEGIN
 9    POPUP "&Файл"
10    BEGIN
11        MENUITEM "&Создать\tCtrl+N",   IDM_FILE_NEW
12        MENUITEM "&Открыть...\tCtrl+O", IDM_FILE_OPEN
13        MENUITEM SEPARATOR
14        MENUITEM "В&ыход",             IDM_FILE_EXIT
15    END
16    POPUP "&Справка"
17    BEGIN
18        MENUITEM "&О программе...",   IDM_HELP_ABOUT
19    END
20END
21
22IDR_ACCELERATORS ACCELERATORS
23BEGIN
24    "N", IDM_FILE_NEW,  VIRTKEY, CONTROL
25    "O", IDM_FILE_OPEN, VIRTKEY, CONTROL
26END

4. Архитектура меню и акселераторов клавиатуры

📌 Слайд 10: Меню и клавиатурные акселераторы

  • Дескриптор меню HMENU и древовидная структура оконного меню.
  • Типы меню: главное (Menu Bar), выпадающее подменю (Popup Menu), контекстное меню (Context Menu).
  • Подключение меню: через класс окна (lpszMenuName), при создании (CreateWindowEx), динамически (SetMenu).
  • Контекстные меню: расчет экранных координат и функция TrackPopupMenu.
  • Таблицы акселераторов: HACCEL, загрузка LoadAccelerators, интеграция в цикл сообщений.

Меню в Windows идентифицируется непрозрачным дескриптором HMENU. Главное меню располагается горизонтально в верхней неклиентской части окна (Menu Bar). Каждый пункт меню может представлять собой либо команду с числовым идентификатором, либо узел иерархии (подменю с флагом MF_POPUP).

📌 Слайд 11: Архитектура ресурсов и система меню

  • Схема компиляции .rc $\to$ .rsrc.
  • Иерархия дескриптора HMENU.
  • Преобразование акселератора в событие WM_COMMAND.

center height:480px

📌 Слайд 12: Диспетчеризация сообщения WM_COMMAND

  • Структура параметров wParam и lParam для различных источников.
  • Распаковка макросами LOWORD и HIWORD.
  • Различение источников: меню (HIWORD(wParam) == 0), акселератор (1), элемент управления (Notification Code).
  • Паттерн обработки switch-case в процедуре окна.

Спецификация сообщения WM_COMMAND:

  • LOWORD(wParam) — идентификатор команды или элемента управления (IDM_FILE_OPEN, IDC_BUTTON1).
  • HIWORD(wParam) — код источника (0 = меню, 1 = акселератор, уведомление элемента).
  • lParam — дескриптор HWND элемента (для меню и акселераторов NULL).
 1LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
 2    switch (msg) {
 3    case WM_COMMAND: {
 4        switch (LOWORD(wParam)) {
 5        case IDM_FILE_OPEN:
 6            DoFileOpen(hWnd);
 7            return 0;
 8        case IDM_FILE_EXIT:
 9            DestroyWindow(hWnd);
10            return 0;
11        default:
12            return DefWindowProc(hWnd, msg, wParam, lParam);
13        }
14    }
15    }
16    return DefWindowProc(hWnd, msg, wParam, lParam);
17}

5. Диалоговые окна: модальные и немодальные архитектуры

📌 Слайд 13: Диалоговые окна: концепция и шаблоны DIALOGEX

  • Назначение диалоговых окон: структурированный ввод параметров и взаимодействие с пользователем.
  • Шаблон диалога в .rc: директивы DIALOG и DIALOGEX.
  • Координатная сетка: диалоговые единицы (Dialog Template Units, DLU) vs пиксели.
  • Зависимость размеров диалога от системного экранного шрифта.
  • Декларативное размещение элементов: LTEXT, EDITTEXT, DEFPUSHBUTTON, COMBOBOX.

📌 Слайд 14: Модальные диалоговые окна

  • Функция DialogBoxParam: параметры создания и передача контекста через lParam.
  • Механизм блокировки: деактивация родительского окна через EnableWindow(hWndParent, FALSE).
  • Собственный внутренний цикл сообщений Windows внутри DialogBoxParam.
  • Завершение работы: вызов EndDialog(hDlg, result).
  • Опасность вызова DestroyWindow для модального диалога: блокировка потока навсегда.

📌 Слайд 15: Немодальные диалоговые окна

  • Функция создания: CreateDialogParam.
  • Немедленный возврат дескриптора HWND диалога.
  • Родительское окно остается активным и параллельно обрабатывает ввод.
  • Необходимость функции IsDialogMessage в основном цикле потока.
  • Завершение: DestroyWindow(hDlg) и обязательное обнуление дескриптора.

📌 Слайд 16: Модальные и немодальные диалоги: сравнение

  • Сравнительная таблица характеристик и функций управления.
  • Особенности цикла сообщений и уничтожения окон.

center height:480px


6. Процедура диалогового окна (DLGPROC) и элементы управления

📌 Слайд 17: Процедура диалогового окна (DLGPROC)

  • Сигнатура INT_PTR CALLBACK DlgProc(HWND, UINT, WPARAM, LPARAM).
  • Различия с WNDPROC: возвращает булево значение (TRUE / FALSE), а не LRESULT.
  • Отсутствие вызова DefWindowProc: возврат FALSE передает обработку системной процедуре по умолчанию.
  • Инициализация в WM_INITDIALOG: установка начальных значений элементов, возврат фокуса.
  • Обработка команд в WM_COMMAND: кнопки IDOK, IDCANCEL.
 1INT_PTR CALLBACK SettingsDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) {
 2    switch (msg) {
 3    case WM_INITDIALOG:
 4        SetDlgItemTextA(hDlg, IDC_EDT_HOST, "localhost");
 5        return TRUE;
 6    case WM_COMMAND:
 7        if (LOWORD(wParam) == IDOK) {
 8            EndDialog(hDlg, IDOK);
 9            return TRUE;
10        }
11        break;
12    }
13    return FALSE;
14}

7. Графический конвейер GDI и контекст устройства (HDC)

📌 Слайд 18: Контекст устройства (HDC) и графический конвейер GDI

  • Концепция контекста устройства (Device Context, HDC).
  • Инкапсуляция графического состояния: текущие цвета, координаты, режимы смешивания.
  • Типы HDC: контекст дисплея (окна), контекст в памяти (Memory DC), контекст принтера.
  • Способы получения: BeginPaint / EndPaint (только в WM_PAINT), GetDC / ReleaseDC (вне отрисовки).
  • Утечки дескрипторов: лимит 10 000 GDI-объектов на процесс в Windows.

📌 Слайд 19: Графические объекты GDI и паттерн SelectObject

  • Типы примитивов: HPEN, HBRUSH, HFONT, HBITMAP, HRGN.
  • Функция SelectObject: замена активного объекта и возврат старого дескриптора.
  • Обязательное сохранение и обратная подстановка исходного объекта перед вызовом DeleteObject.
  • Фатальная ошибка: удаление объекта, находящегося в текущий момент внутри контекста устройства.
  • Системные стоковые объекты: GetStockObject (не требуют вызова DeleteObject).
1HBRUSH hBr = CreateSolidBrush(RGB(220, 38, 38));
2HBRUSH hOld = (HBRUSH)SelectObject(hdc, hBr);
3Rectangle(hdc, 50, 50, 250, 150);
4SelectObject(hdc, hOld);
5DeleteObject(hBr);

8. Жизненный цикл перерисовки: сообщение WM_PAINT и двойная буферизация

📌 Слайд 20: Обработка перерисовки: WM_PAINT и PAINTSTRUCT

  • Механизм инвалидации клиентской области: InvalidateRect(hWnd, &rc, bErase).
  • Структура PAINTSTRUCT и регион повреждения (rcPaint).
  • Функция BeginPaint: получение HDC, валидация области окна, очистка внутреннего флага перерисовки.
  • Функция EndPaint: освобождение контекста отображения.
  • Почему недопустим GetDC внутри WM_PAINT: бесконечный шторм сообщений и загрузка CPU на 100%.

📌 Слайд 21: Устранение мерцания и двойная буферизация

  • Причина мерцания (flicker): поочередная очистка фона (WM_ERASEBKGND) и вывод примитивов на физический экран.
  • Принцип двойной буферизации (Double Buffering): вся отрисовка выполняется в закадровом растре памяти.
  • Создание закадрового контекста: CreateCompatibleDC(hdc).
  • Создание совместимого растра: CreateCompatibleBitmap(hdc, width, height).
  • Битовый перенос кадра: функция BitBlt (Bit Block Transfer).
  • Подавление WM_ERASEBKGND: возврат TRUE для блокировки очистки фона.

📌 Слайд 22: Контекст устройства (HDC) и конвейер GDI

  • Архитектурные шаги жизненного цикла HDC.
  • Паттерн SelectObject и корректная очистка дескрипторов.
  • Схема двойной буферизации в памяти и перенос через BitBlt.

center height:480px


9. Эволюция графики: Direct2D, DirectWrite и аппаратное ускорение

📌 Слайд 23: Современные графические API: Direct2D и аппаратное ускорение

  • Ограничения GDI: отсутствие субпиксельного сглаживания, альфа-прозрачности и поддержки GPU.
  • Direct2D: векторный аппаратно-ускоренный API поверх Direct3D 11/12.
  • Интеграция с DirectWrite: субпиксельный рендеринг шрифтов ClearType.
  • Целевые поверхности рендеринга (ID2D1RenderTarget, ID2D1HwndRenderTarget).
  • Композитная модель DWM: независимость окон от перерисовки соседних областей.

10. Итоги и системные принципы GUI

📌 Слайд 24: Итоги и системные принципы GUI

  • Оконный класс (WNDCLASSEXW) регистрирует общие параметры и оконную процедуру в ядре win32k.
  • Фабрика CreateWindowExW создает структуру окна HWND и посылает WM_CREATE.
  • Связывание C++ объекта окна выполняется сохранением this в GWLP_USERDATA.
  • Декларативное отделение ресурсов (.rsrc) от машинного кода обеспечивает локализацию.
  • Модальные диалоги запускают локальный цикл сообщений, немодальные требуют IsDialogMessage.
  • Строгий учет ресурсов GDI: лимит 10 000 дескрипторов на процесс.
  • Валидация областей окна через BeginPaint/EndPaint.
  • Двойная буферизация (BitBlt) устраняет мерцание экрана.
  • Композитинг DWM аппаратно изолирует кадры процессов в видеопамяти.

Контрольные вопросы и литература

📌 Слайд 25: Вопросы для самопроверки

  1. Какую роль играет оконный класс WNDCLASSEXW и почему окно нельзя создать без предварительной регистрации класса?
  2. Какие параметры передаются в функцию CreateWindowExW и как связать указатель C++ объекта окна через GWLP_USERDATA?
  3. В чем разница между базовыми стилями WS_* и расширенными стилями WS_EX_*?
  4. В чем заключается архитектурная роль win32k.sys и Desktop Window Manager (DWM) в формировании экрана?
  5. Каковы преимущества вынесения элементов интерфейса в секцию .rsrc PE-модуля?
  6. Каким образом клавиатурный акселератор преобразуется в сообщение WM_COMMAND?
  7. Чем отличается системная обработка модального диалога (DialogBoxParam) от немодального (CreateDialogParam)?
  8. Зачем в главном цикле сообщений при наличии немодальных диалогов необходима функция IsDialogMessage?
  9. Опишите последовательность паттерна SelectObject и причину, по которой нельзя удалять объект, выбранный в HDC.
  10. Как техника двойной буферизации (HDC в памяти + BitBlt) устраняет мерцание экрана?

📌 Слайд 26: Литература и рекомендуемые ресурсы

  1. Руссинович М., Соломон Д., Ионеску А. Внутреннее устройство Microsoft Windows. 7-е изд. — СПб.: Питер, 2019.
  2. Петзольд Ч. Программирование для Windows 95. В 2-х томах. — СПб.: BHV, 1997.
  3. Рихтер Дж. Windows для профессионалов: создание эффективных Win32-приложений. — СПб.: Питер, 2008.
  4. Microsoft Learn. Window Classes and Window Creation (DWM) in Win32 API Documentation.
← 05. Механизм сообщений в операционных … 07. Механизмы управления виртуальной и … →