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

Вариант 2.  Обновление окна-списка происходит не по таймеру, а по завершению процедуры DrawProc любым из рисующих потоков.

Вариант 3.  Количество нарисованных за один цикл активности прямоугольников в режиме взаимного исключения для четырех потоков относятся как 1:2:3:4.

Вариант 4.  Третий дочерний поток игнорирует режим взаимного исключения.

Вариант 5.  Таймер срабатывает каждые 0,2 с.

Вариант 6.  Дочерние окна не меняют своего размера при изменении размера главного окна.

Вариант 7.  Вызов процедуры DrawProc происходит не из дочерних потоков, а из главного, по таймеру; при этом порядок активизации окон фиксирован.

Вариант 8.  Каждый цикл рисования прямоугольников в процедуре DrawProc завершается очисткой соответствующего дочернего окна.

Вариант 9.  Вызов процедуры DrawProc происходит не из дочерних потоков, а из главного, по таймеру; при этом порядок активизации окон случаен.

Вариант 10.  Появляется ровно 1 прямоугольник секунду в случайно выбранном дочернем окне.

Теоретические сведения для выполнения контрольной работы

Программа Threads являет собой пример приложения, предоставляющего графический интерфейс пользователя и использующего системные вызовы Win32 API. Данные пример демонстрирует стандартные приемы для решения следующих практических задач:

– создание главного окна с меню и обеспечение основного цикла взаимодействия с пользователем;

– создание дочерних окон и их размещение в главном окне;

– создание дочерних потоков и управление ими;

– использование таймера;

– отображение графических примитивов;

– создание и использование взаимно исключающего семафора;

– использование стандартного окна-списка;

– форматированный вывод текста.

Главное окно и основной цикл взаимодействия с пользователем.

При разработке приложения на языках С, С++, код приложения должен содержать  функцию с именем main, являющуюся главной функцией приложения. В случае приложения, использующего  Win32 API, такую же роль играет функция WinMain. Она запускается операционной системой при запуске приложения, и окончание её выполнения соответствует завершению работы программы.

Большую часть времени работы программы главный поток выполняет описанный в главной функции стандартный цикл обработки сообщений операционной системы

while (GetMessage …

 Причем большую часть времени выполнения цикла главный поток находится в состоянии блокировки при выполнении системного вызова GetMessage – ожидание и получение очередного сообщения. Последующий системный вызов DispatchMessage невидимым в пределах кода приложения образом обращается к зарегистрированным приложением обработчикам сообщений.

До начала цикла обработки сообщений выполняется инициализация приложения, основная цель которой – создание главного окна приложения. Для создания главного окна используется функция CreateWindow с флагом WS_OVERLAPPEDWINDOW и дескриптором меню, ранее подгруженного при помощи вызова LoadMenu. Команды UpdateWindow и ShowWindow делают окно обновленным и видимым.

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

Имя обработчика сообщений главного окна может быть выбрано произвольно. В Threads он называется Main_WndProc. Также, как и в случае с главной функцией WinMain, число, порядок, тип и смысл параметров фиксированы, так как определяются стандартным интерфейсом между приложением и операционной системой. Имена параметров, вообще говоря, произвольны, хотя большинство программистов придерживаются единого стиля их именования. Первый параметр типа HWND позволяет различать различные окна, принадлежащие одному и  тому же классу в пределах данного приложения. В случает Threads, такое окно всего одно. Второй параметр содержит номер сообщения. По нему и происходит выбор конкретной функции-обработчика при помощи конструкции switch. HANDLE_MSG является не системным вызовом, а директивой препроцессора, скрывающей детали передачи параметров функциям-обработчикам различных сообщений. Например, как следует из кода функции Main_WndProc,  сообщение таймера WM_TIMER будет обработано определяемой ниже функцией  Main_OnTimer, а сообщение о выборе пользователем любого пункта меню WM_COMMAND будет обработано определяемой ниже функцией  Main_OnCommand. Дополнительная информация, такая, как идентификатор конкретного пункта меню, номер таймера, или координаты мыши для сообщений от мыши содержатся в остальных параметрах обработчика сообщений.