- •Содержание
- •Часть 1. Общие сведения о технологии программирования 5
- •Часть 2. Windows программирование 24
- •Введение
- •Часть 1. Общие сведения о технологии программирования
- •1. Задачи технологии программирования
- •1.1. Базовые определения
- •1.2. Невозможность доказательства отсутствия программных ошибок
- •1.3. Надежность программного средства
- •1.4. Технология программирования как способ создания надежных программных средств
- •1.5. Этапы развития технологии программирования
- •1.6. Технология программирования и информатизация общества
- •2. Общие принципы разработки программных средств
- •2.1. Специфика разработки программных средств
- •2.2. Основные подходы при создании пс
- •2.3. Жизненный цикл программного средства
- •2.4. Понятие качества программного средства
- •2.5. Обеспечение надежности – основной критерий разработки программных средств
- •2.5.1. Методы борьбы со сложностью
- •2.5.2. Обеспечение точности перевода
- •2.5.3. Преодоление барьера между пользователем и разработчиком
- •2.5.4. Контроль принимаемых решений
- •3. Архитектура программного средства
- •3.1. Понятие архитектуры программного средства
- •3.2. Основные классы архитектур программных средств
- •3.3. Архитектурные функции
- •4. Тестирование и отладка программного средства
- •4.1. Основные понятия
- •4.2. Принципы и виды отладки программного средства
- •4.3. Заповеди отладки программного средства
- •4.4. Автономная отладка программного средства
- •4.5. Комплексная отладка программного средства.
- •Часть 2. Windows программирование
- •5. Основные характеристики Windows платформ
- •5.1. Краткая история Windows
- •5.2. Отличия и общие свойства Windows платформ
- •5.2.1. Общие свойства Windows платформ
- •5.2.2. Отличия Win32 платформ
- •5.2.3. Окна и сообщения
- •5.2.4. Приложения, потоки и окна
- •5.2.5. Классы окон
- •5.2.6. Венгерская нотация
- •5.2.7. Типы сообщений
- •5.2.8. Сообщения и многозадачность
- •5.2.9. Очереди сообщений
- •5.2.10. Процессы и потоки
- •5.2.11. Потоки и сообщения
- •5.2.12. Оконная функция – функция обратного вызова
- •5.2.13. Синхронные и асинхронные сообщения
- •5.2.14. Функции Windows
- •5.2.15. Другие api
- •6. Структура Windows приложений
- •6.1. Файлы заголовков
- •6.2. Глабальные переменные
- •6.3. Точка входа в приложение
- •6.4. Необходимые переменные
- •6.5. Регистрация класса окна
- •6.6. Создание главного окна
- •6.7. Отображение главного окна
- •6.8. Цикл обработки сообщений
- •6.9. Функция окна
- •7. Обработка сообщений в оконной функции
- •7.1. Создание окна wm_create
- •7.2. Определение размера окна wm_size
- •7.3. Отображение содержимого окна wm_paint
- •7.3.1. Случаи генерации сообщения wm_paint
- •7.3.2. Особенность сообщения wm_paint
- •7.3.3. Правила обработки wm_paint
- •7.3.4. Отрисовка вне wm_paint
- •7.3.5. Определение возможностей контекста устройства
- •7.3.6. Системные метрики
- •7.4. Определение расположения окна wm_move
- •7.5. Использование оконных полос прокрутки
- •7.5.1. Диапазон и положение полос прокрутки
- •7.5.2. Сообщения полос прокрутки
- •7.6. Клавиатурный ввод
- •7.6.1. Фокус ввода и активное окно
- •7.6.2. Генерация клавиатурных сообщений
- •7.6.3. Аппаратные сообщения
- •7.6.3.1. Системные аппаратные сообщения
- •7.6.3.2. Несистемные аппаратные сообщения
- •7.6.3.3. Битовые поля параметра lParam
- •7.6.3.4. Виртуальные коды клавиш
- •7.6.4. Символьные сообщения
- •7.6.5. Обработка сообщения wm_char
- •7.6.6. Определение состояния управляющих клавиш
- •7.6.7. Наборы символов
- •7.7. Системный таймер
- •7.7.1. Использование таймера. Первый способ
- •7.7.2. Использование таймера. Второй способ
- •7.8. Удаление окна, сообщение wm_destroy
- •8. Ресурсы приложения и их использование
- •8.1. Меню приложения
- •8.1.1. Виды меню
- •8.1.2. Возможные состояния пунктов меню
- •8.1.3. Сообщения от пунктов меню
- •8.1.4. Создание главного меню приложения
- •8.1.5. Функции для работы с меню
- •8.2. Стандартные элементы управления
- •8.2.1. Создание стандартных элементов управления
- •8.2.2. Разрушение элементов управления
- •8.2.3. Функции для работы с элементами управления
- •8.2.4. Сообщения дочерних окон
- •8.2.5. Сообщения родительского окна дочерним окнам
- •8.2.6. Расширенное управление дочерними окнами
- •8.2.7. Оконные процедуры элементов управления
- •8.2.8. Элемент управления кнопка
- •8.2.8.1. Стили кнопок
- •8.2.8.2. Сообщения от кнопок, получаемые родительским окном
- •8.2.8.3. Сообщения от родительского окна к кнопке
- •8.2.8.4. Кнопки-переключатели
- •8.2.8.5. Сообщение от переключателей
- •8.2.8.6. Сообщение от родительского окна к переключателям
- •8.2.9. Структура drawitemstruct
- •8.2.10. Стандартный элемент управления окно ввода
- •8.2.10.1. Стили окна редактирования
- •8.2.10.2. Сообщения от редактора к родительскому окну
- •8.2.10.3. Сообщения от родительского окна к редактору
- •8.2.11. Стандартный элемент управления статический текст
- •8.2.11.1. Стили элемент управления static
- •8.2.11.2. Сообщения от статического элемента управления
- •8.2.11.3. Сообщения от родительского окна к static
- •8.2.12. Стандартный элемент управления список
- •8.2.12.1. Стили элемента управления список
- •8.2.12.2. Сообщения от списка к родительскому окну
- •8.2.12.3. Сообщения от родительского окна к списку
- •8.2.13. Стандартный элемент управления список с вводом
- •8.2.13.1. Стили элемента управления combobox
- •8.2.13.2. Сообщения от combobox к родительскому окну
- •8.2.13.3. Сообщения от родительского окна к combobox
- •9. Создание и использование диалоговых окон
- •9.1. Этапы создания диалога
- •9.1.1. Создание шаблона диалога
- •9.1.2. Функция диалога
- •9.1.2.1. Сходства между диалоговой функцией и оконной процедурой
- •9.1.2.2. Различия между диалоговой функцией и оконной процедурой
- •9.2. Типы диалоговых панелей
- •9.3. Создание модального диалога
- •9.4. Закрытие модального диалога
- •9.5. Окна сообщений.
- •9.6. Немодальные диалоги
- •9.7. Диалоговые окна общего пользования
- •10. Управление файлами
- •10.1. Доступ к файловой системе
- •10.2. Потоковый ввод/вывод
- •10.3. Функции ядра Windows для работы с файлами
- •10.4. Специализированные функции для работы с файлами
- •11. Печать документов
- •11.1. Последовательность печати документа
- •11.2. Контекст устройства принтера
- •11.3. Диалог отмены печати
- •11.4. Запуск процесса печати
- •11.5. Печать страницы документа
- •11.6. Завершение печати документа
- •12. Процессы и потоки
- •12.1. Диспетчеризация потоков
- •12.2. Проблемы многопоточной технологии
- •12.3. Создание рабочего потока
- •12.4. Организация взаимодействия потоков
- •12.4.1. Рабочий поток – процесс
- •12.4.2. Процесс – рабочий поток
- •12.5. Общая схема взаимодействия потоков
- •13. Приложение "Тестер файлов"
- •13.1. Функция WinMain()
- •13.2. Функция главного окна
- •13.3. Вспомогательные функции
- •13.4. Функция рабочего потока
- •Литература к первой части
- •Литература ко второй части
5.2.11. Потоки и сообщения
Как было уже сказано, окно обязательно принадлежит какому-либо потоку. В этом случае поток должен иметь свою очередь сообщений, в которую операционная система и будет помещать сообщения, адресованные окну данного потока. Однако это не означает, что поток всегда должен иметь окно и содержать цикл сообщений. Потоки могут не владеть окном и, следовательно, не обрабатывать сообщений.
В Win32 можно установить отдельный поток, выполняющий, например, длительные операции, в то время как главный поток приложения, владеющий окном, будет обрабатывать все сообщения, принимаемые приложением.
Поток называется рабочим потоком, если он не имеет ни окон, ни очереди сообщений, ни цикла обработки сообщений. Обычно такие потоки предназначены для выполнения интенсивных вычислений. Поток, владеющий хотя бы одним окном и, следовательно, предназначенный для обработки сообщений, именуется потоком пользовательского интерфейса.
5.2.12. Оконная функция – функция обратного вызова
Чтобы понять, что такое функция обратного вызова, вспомним, что в любой операционной системе вызов большинства функций предназначен для запроса некоторого сервиса у операционной системы. Например, для открытия файла используется вызов функции fopen(). Другими словами, вашей программе нужен какой-либо сервис, и он запрашивается у операционной системы вызовом соответствующей функции, код которой располагается в одной из системных библиотек. Это – обычные функции, и большинство Win32 API функций принадлежит к данному классу.
Однако операционная система Windows включает функции, поведение которых определено с точностью наоборот. Ваше приложение должно содержать тело оконной функции, которую ваша программа никогда не вызывает. Обращаться к этой функции может только ядро Windows. Такие функции именуются функциями обратного вызова.
Оконная функция (именуется также оконной процедурой) связанна с классом окна, который приложение регистрирует при своем запуске. С этого момента ядро Windows “знает” адрес оконной функции и может ее вызывать, использую данный адрес. При этом все вызовы функции окна имеют форму сообщений.
5.2.13. Синхронные и асинхронные сообщения
Одни и те же Windows сообщения могут быть как синхронными (queued), так и асинхронными (nonqueued). Асинхронными сообщениями называются сообщения, помещаемые Windows в очередь сообщений приложения, и которые затем извлекаются и диспетчеризируются в цикле обработки сообщений. Синхронные сообщения передаются непосредственно окну, когда Windows вызывает оконную процедуру. В результате оконная процедура получает все предназначенные для окна сообщения, как синхронные, так и асинхронные.
Асинхронные сообщения помещаются в очередь сообщений в одно время, а обрабатываться могут в другое. Синхронные – посылаются напрямую в оконную процедуру и тут же обрабатываются.
Асинхронными становятся сообщения, в основном, тогда, когда они являются результатом пользовательского ввода, путем нажатия клавиатурных клавиш, например, WM_KEYDOWN и WM_KEYUP; как результат движения мыши или щелчков кнопок мыши. Также к асинхронным сообщениям относятся сообщения таймера WM_TIMER или сообщение завершения цикла обработки сообщений WM_QUIT. Порой асинхронные сообщения являются результатом синхронных сообщений, и наоборот.
Очевидно, что процесс этот сложен, но большая часть сложностей ложится на саму Windows, а не на пользовательские программы. Дело в том, что ваша оконная процедура может что-либо сделать с поступающими сообщениями, а может и проигнорировать их, передавая назад Windows на обработку по умолчанию.
Некоторые сообщения являются результатом вызова определенных функций Win32 API. Например, когда ваше приложение создает окно, вызывает функцию CreateWindowEx(), Windows отправляет оконной процедуре синхронное сообщение WM_CREATE. Когда же вы вызываете функцию UpdateWindow(), Windows помещает в очередь приложения асинхронное сообщение WM_PAINT.
Во время обработки оконной процедурой одного сообщения, приложение не может быть прервано другим сообщением. Только в единственном случае, если оконная процедура сама вызывает функцию, которая становится источником нового синхронного сообщения, то оконная процедура начнет обрабатывать это новое сообщение еще до того, как она вернет управление Windows. Таким образом, оконная процедура должна быть реентерабельной (reentrant), т.е. повторно-входимой.
Часто возникает необходимость того, чтобы оконная функция сохраняла информацию, полученную в одном сообщении, и использовала ее при обработке другого сообщения. Такую информацию следует описывать в оконной процедуре в виде статических переменных.