Обработчик сообщения 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 (черный, тонкий, сплошной по умолчанию).
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.