На этом шаге мы рассмотрим организацию работы с таймером в приведенной на 51 шаге программы.
Благодаря таймеру Windows, использованному в предыдущей программе GDI, пользователь может установить программу в автоматический режим, а затем наблюдать, как программа проделывает всю работу по выбору координат и рисованию выбранного контура. Каждый раз при получении программой сообщения WM_TIMER, OWL вызывает функцию отклика на сообщение EvTimer():
void TWndw::EvTimer(UINT) { // Рисует объект только при выполнении программы // в автоматическом режиме, и если окно не минимизировано. if ((operation == automatic) && (!IsIconic())) { // Получить размер рабочей области окна. TRect rect = GetClientRect(); // Вычислить случайное положение на экране. int xpos = random(rect.right); int ypos = random(rect.bottom); // Рисует объект. DrawObject (TPoint(xpos, ypos)); } }
Функция EvTimer() сначала проверяет установку автоматического режима выполнения программы и отсутствия минимизации приложения. Функция IsIconic(), унаследованная от TWindow, возвращает TRUE, если программа была минимизирована. Вы можете удивиться - какое отличие вносит минимизация программы? В режиме ручного управления здесь нет никакого отличия, так как, когда программа свернута в пиктограмму, пользователь не может вводить команды рисования. Однако в автоматическом режиме программа автоматически выполняет рисование в ответ на срабатывания таймера. Программа работает в линейном режиме, но без проверки результата IsIconic() с помощью EvTimer().
Если программа выполняется в автоматическом режиме, и окно не было минимизировано, то EvTimer() вызывает GetClientRect(), чтобы получить размер рабочей области окна. Затем программа вычисляет случайные координаты хpos и уpos, дважды вызывая random(), один раз в качестве максимально допустимого значения используется rect.right, a второй раз rect.bottom.
Хотя в этих случайных координатах не учитываются высота и ширина рисуемых контуров, Windows выполняет для программы все задачи отсечения, запрещая рисование вне рабочей области. Вы могли бы чуть упорядочить программу, убедившись, что каждая случайная координата допускает изображение всей фигуры. Конечно, при этом подразумевается, что ширина и высота каждой рисуемой программой фигуры известны, а соответствующие значения ширины и высоты вычитаются из xpos и ypos, если координаты таковы, что для размещения фигуры в окне не хватает места.
Наконец, после вычисления новых координат фигуры EvTimer() вызывает DrawObject() с заданными координатами, преобразуя координаты в объект класса TPoint.
На следующем шаге мы рассмотрим рисование GDI-контуров.