Практикум по курсу "Системное программное обеспечение": Учебное пособие (Программа курса, методические указания к изучению дисциплины, содержание и методические рекомендации к выполнению контрольной работы), страница 8

Обработчик сообщения WM_DESTROY должен вызвать системный вызов PostQuitMessage, чтобы закрытие главного окна вызвало завершение приложения. Иначе в оперативной памяти останется невидимое приложение-демон.

Дочерние окна.

Для создания дочерних окон также используется функция CreateWindow, но уже с флагом WS_CHILD и дескриптором ранее созданного главного окна в качестве родительского. Эта функция возвращает дескриптор вновь созданного окна, который может использоваться в дальнейшем для изменения его размеров, рисования на нем графических примитивов и любых других операций с окном. Размеры и координаты дочерних окон могут быть заданы при создании. Однако, в данном примере они задаются позднее системным вызовом MoveWindow из обработчика сообщения об изменении размеров главного окна WM_SIZE.

Дочерние потоки.

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

Четвертым параметром передается значение, которое запущенная в дочернем потоке главная функция потока получит в качестве параметра. В данном примере, это просто число 0, 1, 2 или 3, соответствующее порядковому номеру создаваемого дочернего потока.  В дальнейшем знание этого номера позволяет каждому потоку рисовать в своем дочернем окне. В принципе, все потоки выполняются в едином адресном пространстве и имеют доступ к одним и тем же ресурсам, в том числе, ко всем окнам приложения.

Возвращаемое функцией CreateThread значение дескриптора вновь созданного потока позволяет в дальнейшем приостанавливать, возобновлять или завершать его, вызовами SuspendThread, ResumeThread и TerminateThread соответственно, а также узнавать и менять его приоритет при помощи вызовов GetThreadPriority и SetThreadPriority.

Приоритеты главного и дочерних потоков могут принимать значения -2, -1, 0, 1, 2 относительно приоритета всего процесса в целом. Эти значения соответствуют именованным константам THREAD_PRIORITY_LOWEST, THREAD_PRIORITY_BELOW_NORMAL, THREAD_PRIORITY_NORMAL, THREAD_PRIORITY_ABOVE_NORMAL, THREAD_PRIORITY_HIGHEST. Выполнение не блокирующегося дочернего потока с приоритетом выше главного может привести в задержке реакции приложения на ввод пользователя.

Для завершения дочерних потоков можно выполнить вызов TerminateThread, или, как в данном примере, создать условия для завершения циклов в главных процедурах потоков.

Таймер.

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

Рисование.

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

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

PatBlt – закрашивание прямоугольной области на окне цветом текущей выбранной логической кисти (в данном примере, закрашивание всего окна белым цветом);

CreateSolidBrush и GetNearestColor для выбора более или менее произвольного цвета заливки из числа доступных данному окну;

Rectangle – рисование прямоугольника с фоном, определяемым предшествующим вызовом SelectBrush, и контуром, определяемым предшествующим вызовом SelectPen (черный, тонкий, сплошной по умолчанию).