- •Методические рекомендации
- •План лекции
- •Интерфейс графического устройства
- •Программирование, основанное на ресурсах
- •Управления памятью
- •Документы и их представление
- •Контрольные вопросы
- •Редактирование функций.
- •Изучение работы приложения.
- •Самостоятельная работа.
- •Добавление своего класса.
- •Домашняя работа.
- •Лекция 2. Основы программирования. Работа с классом Вид. Методические рекомендации:
- •Интерфейс графического устройства
- •Работа с gdi объектами
- •Пример создания нового gdi объекта
- •Режимы преобразования координат
- •Режимы преобразования координат с постоянным масштабом
- •Режимы преобразования координат с переменным масштабом
- •Замечание
- •Координатные пространства mfc
- •Пример использования режимов преобразования координат
- •Работа с окнами, содержащими полосы прокрутки
- •Линейки прокрутки
- •Различные способы прокрутки
- •Прием ввода с клавиатуры
- •Контрольные вопросы
- •Обработка сообщений от мыши.
- •Задание для самостоятельной домашней разработки.
- •Лекция 3. Меню. Панели инструментов и строки состояния Методические рекомендации
- •Меню Windows
- •Обновление командного пользовательского интерфейса
- •Класс cMenu
- •Создание контекстных меню
- •Панели элементов управления и каркас приложений
- •Панель инструментов
- •Растровое изображение панели инструментов
- •Состояния кнопок Любая кнопка может находиться в следующих состояниях
- •Всплывающие подсказки
- •Строка состояния
- •Определение секций в строке состояния
- •Строка сообщений
- •Индикатор состояния
- •Управление строкой состояния
- •Контрольные вопросы:
- •Добавление переменных-членов.
- •Добавление функции OnMouseMove.
- •Программирование команд контекстного меню.
- •Программирование команд главного меню.
- •Домашняя работа.
- •Лекция 4. Диалоговые окна и стандартные элементы управления Методические рекомендации
- •Работа с модальным диалоговым окном
- •Стандартные элементы управления
- •Работа с немодальными диалоговыми окнами
- •Пользовательские сообщения
- •Принадлежность диалогового окна
- •Контрольные вопросы
- •Создание класса “диалогового окна”.
- •Добавление переменных-членов класса вашего диалогового окна.
- •Написание инициализирующего кода
- •Присваивание переменным начальных значений.
- •Самостоятельная работа.
- •Домашнее задание.
- •Лекция 5. Обработка сообщений Windows и программирование многопоточных приложений Методические рекомендации
- •Обработка сообщений в однопоточной программе
- •Передача управления
- •Таймеры
- •Обработка в периоды простоя
- •Программирование многопоточных приложений
- •Функция рабочего потока и запуск потока
- •Общение основного потока с рабочим
- •Общение рабочего потока с основным
- •Синхронизация потоков с использованием событий
- •Блокировка потоков
- •Критические секции
- •Потоки пользовательского интерфейса
- •Контрольные вопросы
- •Домашнее задание.
- •Задание для самостоятельной работы
- •Управление процессом Пример 1.
- •2. Замена образа процеса Пример 2. Использование функции exec.
- •Пример 3. Использование неименованного канала.
- •Пример 4. Создание именованного канал с именем "fifo".
- •3. Сигналы.
- •Пример 5. Использование сигналов.
- •Пример 6. Сообщения.
- •Пример 7. Сообщения.
- •Пример 8. Разделение памяти.
- •Пример 9. Использование семафоров.
- •Пример 10. Создание процесса вWindows.
- •Пример 11. Использование неименованного канала.
- •Пример 12. Использование именованного канала.
- •Пример 13. Использование разделяемой памяти File Mapping.
- •Пример 14. Использование Mailslot.
- •Пример 15. Использование событий.
Передача управления
Что произойдет, если одна из функций-обработчиков окажется “жадной” и израсходует 10 секунд процессорного времени? Во времена 16-разрядной системы компьютер просто завис бы на это время. Разве что можно было бы перемещать курсор мыши, да исполнялись бы какие-то задачи, управляемые прерываниями. В Win32 многозадачность организована куда лучше. Благодаря вытесняющей многозадачности другие приложения не зависнут — Windows, когда сочтет это нужным, просто приостановит выполнение “жадной” функции. Однако даже в Win32 ваша программа на эти 10 секунд была бы заблокирована. Она не смогла бы обрабатывать какие-либо сообщения, так как DispatcbMessage не возвращает управление до тех пор, пока его не возвратит злополучный обработчик.
Однако есть способ обойти эту проблему. Он срабатывает как в Winl6, так и в Win32. Надо просто заставить “жадную” функцию вести себя дружелюбнее, т. е. периодически отдавать управление — а для этого вставить в ее основной цикл такие операторы:
MSG message; if (::PeekMessage(&message, NULL, 0, 0, PM_REMOVE)) { ::TranslateMessage(&message); ::DispatchMessage(&fflessage); } |
Функция PeekMessage работает так же, как и GetMessage — за исключением того, что возвращает управление немедленно, даже если для вашей программы нет никаких сообщений. В этом случае “жадная” функция продолжает поглощать процессорное время. Однако, как только появляется сообщение, вызывается обработчик, и по завершении его работы выполнение функции возобновляется. |
Таймеры
Таймер Windows — это полезный элемент, иногда устраняющий необходимость в многопоточном программировании. Таймер можно использовать и для управления анимацией, .поскольку он не зависит от тактовой частоты процессора.
Для работы с таймерами необходимо вызывать функцию CWnd::SetTimer с параметром — интервал времени, после чего с помощью ClassWizard нужно определить обработчик сообщения WM_TIMER. После запуска таймера с заданным интервалом в миллисекундах сообщения WM_TIMER постоянно посылаются окну приложения до тех пор, пока не будет вызвана CWnd::KillTiiner или уничтожено окно. При необходимости можно задействовать несколько таймеров, каждый из которых идентифицируется целым числом. Поскольку Windows не является операционной системой реального времени, интервал значительно менее 100 миллисекунд приводит к потере точности. |
Подобно другим сообщениям Windows, сообщения таймера могут заблокировать другие функции-обработчики в программе. К счастью, сообщения таймера не аккумулируются. Windows не ставит сообщения таймера в очередь, если в ней уже есть одно сообщение от данного таймера.
Обработка в периоды простоя
До появления многопоточности разработчики программ для Windows использовали периоды простоя (idle) для выполнения фоновых задач, например, разбивки документа на страницы. Теперь обработка во время простоя потеряла былое значение, но ей по-прежнему находится применение. Каркас приложений вызывает виртуальную функцию-член Onldle класса CWinApp, и Вы можете переопределить ее для выполнения фоновых вычислений Onldie вызывается из цикла обработки сообщений MFC-библиотеки, который на самом деле сложнее, чем приведенная выше простая последовательность GetMessage/TramlateMessage/Dispatch-Message. Обычно функция Onldle вызывается после того, как очередь сообщений у приложения опустеет, причем только один раз. Если Вы переопределяете ее, вызывается ваш код, но при отсутствии непрерывного потока сообщений это не происходит постоянно. Onldle в базовом классе обновляет кнопки панели инструментов и индикаторы состояния, а также “чистит” указатели на временные объекты. Имеет смысл переопределять эту функцию, если Вы хотите обновлять состояние элементов пользовательского интерфейса Ну, а то, что она не вызывается в отсутствие сообщений, значения не имеет, ведь пользовательский интерфейс и не должен в этом случае изменяться.
Переопределяя функцию CWinApp::Onldle, не забудьте вызвать Onldle базового класса. Иначе не произойдет ни обновления кнопок на панели инструментов, ни удаления временных объектов.
Onldle вообще не вызывается, если пользователь работает в модальном диалоговом окне или выбирает что-то в меню. При необходимости фоновой обработки модальных диалоговых окон или меню придется написать обработчик сообщения WM_ENTERIDLE, но его надо добавить в класс окна-рамки, а не в класс “вид”. Причина в том, что владельцем диалоговых окон всегда является основное окно-рамка приложения, а не окно представления.