- •Содержание
- •Глава 1 README.TXT
- •Вызов, брошенный программистам
- •Основные правила
- •Краткая история Windows
- •Краткая история этой книги
- •Начнем
- •Глава 2 Hello, Windows 95
- •Отличительная особенность Windows
- •Графический интерфейс пользователя
- •Концепции и обоснование GUI
- •Содержимое интерфейса пользователя
- •Преимущество многозадачности
- •Управление памятью
- •Независимость графического интерфейса от оборудования
- •Соглашения операционной системы Windows
- •Вызовы функций
- •Объектно-ориентированное программирование
- •Архитектура, управляемая событиями
- •Оконная процедура
- •Ваша первая программа для Windows
- •Что в этой программе неправильно?
- •Файлы HELLOWIN
- •Make-файл
- •Вызовы функций Windows
- •Идентификаторы, написанные прописными буквами
- •Новые типы данных
- •Описатели
- •Венгерская нотация
- •Точка входа программы
- •Регистрация класса окна
- •Создание окна
- •Отображение окна
- •Цикл обработки сообщений
- •Оконная процедура
- •Обработка сообщений
- •Воспроизведение звукового файла
- •Сообщение WM_PAINT
- •Сообщение WM_DESTROY
- •Сложности программирования для Windows
- •Не вызывай меня, я вызову тебя
- •Синхронные и асинхронные сообщения
- •Думайте о ближнем
- •Кривая обучения
- •Глава 3 Рисование текста
- •Рисование и обновление
- •Сообщение WM_PAINT
- •Действительные и недействительные прямоугольники
- •Введение в графический интерфейс устройства (GDI)
- •Контекст устройства
- •Структура информации о рисовании
- •Получение описателя контекста устройства. Второй метод
- •Функция TextOut. Подробности
- •Системный шрифт
- •Размер символа
- •Метрические параметры текста. Подробности
- •Форматирование текста
- •Соединим все вместе
- •Не хватает места!
- •Размер рабочей области
- •Полосы прокрутки
- •Диапазон и положение полос прокрутки
- •Сообщения полос прокрутки
- •Прокрутка в программе SYSMETS
- •Структурирование вашей программы для рисования
- •Создание улучшенной прокрутки
- •Мне не нравится пользоваться мышью
- •Глава 4 Главное о графике
- •Концепция GDI
- •Структура GDI
- •Типы функций
- •Примитивы GDI
- •Другие аспекты
- •Контекст устройства
- •Получение описателя контекста устройства
- •Программа DEVCAPS1
- •Размер устройства
- •О цветах
- •Атрибуты контекста устройства
- •Сохранение контекста устройства
- •Рисование отрезков
- •Ограничивающий прямоугольник
- •Сплайны Безье
- •Использование стандартных перьев
- •Создание, выбор и удаление перьев
- •Закрашивание пустот
- •Режимы рисования
- •Рисование закрашенных областей
- •Функция Polygon и режим закрашивания многоугольника
- •Закрашивание внутренней области
- •Режим отображения
- •Координаты устройства (физические координаты) и логические координаты
- •Системы координат устройства
- •Область вывода и окно
- •Работа в режиме MM_TEXT
- •Метрические режимы отображения
- •Ваши собственные режимы отображения
- •Программа WHATSIZE
- •Прямоугольники, регионы и отсечение
- •Работа с прямоугольниками
- •Случайные прямоугольники
- •Создание и рисование регионов
- •Отсечения: прямоугольники и регионы
- •Программа CLOVER
- •Пути
- •Создание и воспроизведение путей
- •Расширенные перья
- •Bits and Blts
- •Цвета и битовые образы
- •Файл DIB
- •Упакованный формат хранения DIB
- •Отображение DIB
- •Преобразование DIB в объекты "битовые образы"
- •Битовый образ — объект GDI
- •Создание битовых образов в программе
- •Формат монохромного битового образа
- •Формат цветного битового образа
- •Контекст памяти
- •Мощная функция BitBlt
- •Перенос битов с помощью функции BitBlt
- •Функция DrawBitmap
- •Использование других ROP кодов
- •Дополнительные сведения о контексте памяти
- •Растяжение битовых образов с помощью функции StretchBlt
- •Кисти и битовые образы
- •Метафайлы
- •Простое использование метафайлов памяти
- •Сохранение метафайлов на диске
- •Расширенные метафайлы
- •Делаем это лучше
- •Базовая процедура
- •Заглянем внутрь
- •Вывод точных изображений
- •Текст и шрифты
- •Вывод простого текста
- •Атрибуты контекста устройства и текст
- •Использование стандартных шрифтов
- •Типы шрифтов
- •Шрифты TrueType
- •Система EZFONT
- •Внутренняя работа
- •Форматирование простого текста
- •Работа с абзацами
- •Глава 5 Клавиатура
- •Клавиатура. Основные понятия
- •Игнорирование клавиатуры
- •Фокус ввода
- •Аппаратные и символьные сообщения
- •Аппаратные сообщения
- •Системные и несистемные аппаратные сообщения клавиатуры
- •Переменная lParam
- •Виртуальные коды клавиш
- •Использование сообщений клавиатуры
- •Модернизация SYSMETS: добавление интерфейса клавиатуры
- •Логика обработки сообщений WM_KEYDOWN
- •Посылка асинхронных сообщений
- •Символьные сообщения
- •Сообщения WM_CHAR
- •Сообщения немых символов
- •Каретка (не курсор)
- •Функции работы с кареткой
- •Программа TYPER
- •Наборы символов Windows
- •Набор символов OEM
- •Набор символов ANSI
- •Наборы символов OEM, ANSI и шрифты
- •Международные интересы
- •Работа с набором символов
- •Связь с MS-DOS
- •Использование цифровой клавиатуры
- •Решение проблемы с использованием системы UNICODE в Windows NT
- •Глава 6 Мышь
- •Базовые знания о мыши
- •Несколько кратких определений
- •Сообщения мыши, связанные с рабочей областью окна
- •Простой пример обработки сообщений мыши
- •Обработка клавиш <Shift>
- •Сообщения мыши нерабочей области
- •Сообщение теста попадания
- •Сообщения порождают сообщения
- •Тестирование попадания в ваших программах
- •Гипотетический пример
- •Пример программы
- •Эмуляция мыши с помощью клавиатуры
- •Добавление интерфейса клавиатуры к программе CHECKER
- •Использование дочерних окон для тестирования попадания
- •Дочерние окна в программе CHECKER
- •Захват мыши
- •Рисование прямоугольника
- •Решение проблемы — захват
- •Программа BLOKOUT2
- •Глава 7 Таймер
- •Основы использования таймера
- •Система и таймер
- •Таймерные сообщения не являются асинхронными
- •Использование таймера: три способа
- •Первый способ
- •Второй способ
- •Третий способ
- •Использование таймера для часов
- •Позиционирование и изменение размеров всплывающего окна
- •Получение даты и времени
- •Обеспечение международной поддержки
- •Создание аналоговых часов
- •Стандартное время Windows
- •Анимация
- •Класс кнопок
- •Создание дочерних окон
- •Сообщения дочерних окон родительскому окну
- •Сообщения родительского окна дочерним окнам
- •Нажимаемые кнопки
- •Флажки
- •Переключатели
- •Окна группы
- •Изменение текста кнопки
- •Видимые и доступные кнопки
- •Кнопки и фокус ввода
- •Дочерние окна управления и цвета
- •Системные цвета
- •Цвета кнопок
- •Сообщение WM_CTLCOLORBTN
- •Кнопки, определяемые пользователем
- •Класс статических дочерних окон
- •Класс полос прокрутки
- •Программа COLORS1
- •Интерфейс клавиатуры, поддерживаемый автоматически
- •Введение новой оконной процедуры
- •Закрашивание фона
- •Окрашивание полос прокрутки и статического текста
- •Класс редактирования
- •Стили класса редактирования
- •Коды уведомления управляющих окон редактирования
- •Использование управляющих окон редактирования
- •Сообщения управляющему окну редактирования
- •Класс окна списка
- •Стили окна списка
- •Добавление строк в окно списка
- •Выбор и извлечение элементов списка
- •Получение сообщений от окон списка
- •Простое приложение, использующее окно списка
- •Список файлов
- •Утилита Head для Windows
- •Компиляция ресурсов
- •Значки и курсоры
- •Редактор изображений
- •Получение описателя значков
- •Использование значков в вашей программе
- •Использование альтернативных курсоров
- •Битовые образы: картинки в пикселях
- •Использование битовых образов и кистей
- •Символьные строки
- •Использование ресурсов-символьных строк
- •Меню
- •Структура меню
- •Шаблон меню
- •Ссылки на меню в вашей программе
- •Меню и сообщения
- •Образец программы
- •Этикет при организации меню
- •Сложный способ определения меню
- •Третий подход к определению меню
- •Независимые всплывающие меню
- •Использование системного меню
- •Изменение меню
- •Другие команды меню
- •Использование в меню битовых образов
- •Два способа создания битовых образов для меню
- •Контекст памяти
- •Создание битового образа, содержащего текст
- •Масштабирование битовых образов
- •Соберем все вместе
- •Добавление интерфейса клавиатуры
- •Быстрые клавиши
- •Зачем нужны быстрые клавиши?
- •Некоторые правила назначения быстрых клавиш
- •Таблица быстрых клавиш
- •Преобразование нажатий клавиш клавиатуры
- •Получение сообщений быстрых клавиш
- •Программа POPPAD, имеющая меню и быстрые клавиши
- •Разрешение пунктов меню
- •Обработка опций меню
- •Глава 11 Окна диалога
- •Модальные окна диалога
- •Создание окна диалога About
- •Шаблон окна диалога
- •Диалоговая процедура
- •Вызов окна диалога
- •Дополнительная информация о стиле окна диалога
- •Дополнительная информация об определении дочерних окон элементов управления
- •Более сложное окно диалога
- •Работа с дочерними элементами управления окна диалога
- •Кнопки OK и Cancel
- •Позиции табуляции и группы
- •Рисование в окне диалога
- •Использование с окном диалога других функций
- •Определение собственных окон управления
- •Окна сообщений
- •Информация во всплывающих окнах
- •Немодальные окна диалога
- •Различия между модальными и немодальными окнами диалога
- •Новая программа COLORS
- •Программа HEXCALC: обычное окно или окно диалога?
- •Творческое использование идентификаторов дочерних окон элементов управления
- •Диалоговые окна общего пользования
- •Модернизированная программа POPPAD
- •Изменение шрифта
- •Поиск и замена
- •Программа для Windows, содержащая всего один вызов функции
- •Основы элементов управления общего пользования
- •Инициализация библиотеки
- •Создание элементов управления общего пользования
- •Стили элементов управления общего пользования
- •Уведомляющие сообщения от элементов управления общего пользования
- •Элементы управления главного окна
- •Панели инструментов
- •Создание панели инструментов
- •Строка состояния
- •Программа GADGETS
- •Наборы страниц свойств
- •Создание набора страниц свойств
- •Процедуры диалогового окна страницы свойств
- •Программа PROPERTY
37
Сложности программирования для Windows
Даже с учетом авторских пояснений структура и принципы работы программы Hellowin, вполне вероятно, так и останутся для вас немного загадочными. В короткой программе на С, написанной для обычной среды, вся программа целиком может поместиться в функции main. В HELLOWIN WinMain содержит только надстройку программы, необходимую для регистрации класса окна, создания окна и получения и передачи сообщений из/в очередь сообщений.
Все основные действия программы происходят в оконной процедуре. В HELLOWIN этих действий немного — это просто воспроизведение звука и вывод в окно строки текста. Но в следующих главах вы обнаружите, что почти в каждой программе для Windows работа с сообщениями происходит в оконной процедуре. Это основная концептуальная особенность, которую вы должны усвоить, чтобы начать писать программы для Windows.
Не вызывай меня, я вызову тебя
Как уже упоминалось, программисты хорошо знакомы с понятием вызова операционной системы для выполнения каких-то действий. Например, программисты на С используют функцию fopen для открытия файла. Библиотечные функции, поставляемые с компилятором, содержат код, который фактически вызывает для открытия файла операционную систему. Здесь все просто.
Но операционная система Windows ведет себя иначе. Хотя в Windows имеется свыше тысячи доступных программисту функций, Windows также и сама посылает вызовы вашей программе, особенно оконной процедуре, которую мы назвали WndProc. Оконная процедура связана с классом окна, который программа регистрирует с помощью вызова функции RegisterClassEx. Окно, создаваемое на основе этого класса, использует оконную процедуру для обработки всех сообщений окна. Windows посылает сообщения окну, вызывая оконную процедуру.
Windows вызывает WndProc первый раз при создании окна. Windows вызывает WndProc при последующем удалении окна. Windows вызывает WndProc при изменении размеров окна, при его перемещении, при его свертывании. Windows вызывает WndProc при выборе пункта меню. Windows вызывает WndProc при манипуляциях с полосами прокрутки или с мышью. Windows вызывает WndProc, чтобы сообщить ей о необходимости перерисовать рабочую область.
Все эти вызовы имеют форму сообщений. В большинстве программ для Windows, основная часть программы направлена на обработку этих сообщений. Свыше 200 различных сообщений, которые Windows может отправить оконной процедуре, идентифицируются именами, которые начинаются с букв "WM" и определяются в заголовочных файлах Windows.
Фактически, идея функции, находящейся в программе, но которая вызывается не из самой программы, не является абсолютно новой в традиционном программировании. Функция signal в С может перехватить <Ctrl>+<Break>. Вы можете иметь опыт с перехватом аппаратных прерываний с помощью языка ассемблера или одной из конструкций ON в Microsoft BASIC. Драйвер мыши фирмы Microsoft позволяет работать с этой мышью программам, сделанным не для Windows.
В Windows эта идея расширена и пронизывает всю систему. Любое событие, относящееся к окну, передается оконной процедуре в виде сообщения. Затем оконная процедура соответствующим образом реагирует на это сообщение или передает сообщение в DefWindowProc для обработки его по умолчанию.
Параметры wParam и lParam оконной процедуры не используются в HELLOWIN кроме как параметры для DefWindowProc. Эти параметры дают оконной процедуре дополнительную информацию о сообщении. Значение этих параметров зависит от самого сообщения.
Давайте рассмотрим пример. Когда меняется размер рабочей области окна, Windows вызывает оконную процедуру. Параметр hwnd оконной процедуры — это описатель окна, изменившего размер. Параметр iMsg равен WM_SIZE. Параметр wParam для сообщения WM_SIZE равен одной из величин SIZENORMAL, SIZEICONIC, SIZEFULLSCREEN, SIZEZOOMSHOW или SIZEZOOMHIDE (определяемых в заголовочных файлах Windows как числа от 0 до 4). Параметр wParam показывает, будет ли окно свернуто, развернуто или скрыто (в результате развертывания другого окна). Параметр lParam определяет новый размер окна. Новая ширина (16-разрядное значение) и новая высота (16-разрядное значение) объединяются вместе в 32-разрядный параметр lParam. В заголовочных файлах Windows имеется макрос, который позволяет выделить оба эти значения из lParam. Мы это проделаем в следующей главе.
Иногда, в результате обработки сообщения функцией DefWindowProc, генерируются другие сообщения. Например, предположим, что вы запускаете HELLOWIN и выбираете Close из системного меню программы, используя клавиатуру или мышь. DefWindowProc обрабатывает эту информацию. Когда она определяет, что вы выбрали опцию Close, то отправляет сообщение WM_SYSCOMMAND оконной процедуре. WndProc передает это сообщение DefWindowProc. DefWindowProc реагирует на него, отправляя сообщение WM_CLOSE оконной процедуре. WndProc снова передает это сообщение DefWindowProc. DefWindowProc реагирует на сообщение
38
WM_CLOSE, вызывая функцию DestroyWindow. DestroyWindow заставляет Windows отправить сообщение WM_DESTROY оконной процедуре. И наконец, WndProc реагирует на это сообщение, вызывая функцию PostQuitMessage путем постановки сообщения WM_QUIT в очередь сообщений. Это сообщение прерывает цикл обработки сообщений в WinMain и программа заканчивается.
Синхронные и асинхронные сообщения
Ранее было рассказано о передаче окну сообщений, что означает вызов операционной системой Windows оконной процедуры. Но в программах для Windows имеется цикл обработки сообщений, который берет сообщения из очереди сообщений, вызывая функцию GetMessage, и отправляет их оконной процедуре, вызывая функцию
DispatchMessage.
Так что же, буферизуются ли сообщения для Windows-программы (так же как в обычной программе буферизуется ввод с клавиатуры) и затем пересылаются дальше, или она (программа для Windows) получает сообщения непосредственно снаружи? И так, и этак.
Одни и те же сообщения могут быть и "синхронные" (queued), и "асинхронные" (nonqueued)1. Синхронными сообщениями называются сообщения, которые Windows помещает в очередь сообщений программы, и которые извлекаются и диспетчеризуются в цикле обработки сообщений. Асинхронные сообщения передаются непосредственно окну, когда Windows вызывает оконную процедуру. В результате оконная процедура получает все предназначенные для окна сообщения, как синхронные, так и асинхронные. Структура программ для Windows очень проста, поскольку у них имеется только одно центральное место обработки сообщений. Говорят, что синхронные сообщения помещаются в очередь сообщений (post), а асинхронные посылаются прямо в оконную процедуру (send).
Синхронными становятся сообщения, в основном, тогда, когда они являются результатом пользовательского ввода путем нажатия клавиш (например, WM_KEYDOWN и WM_KEYUP), это символы, введенные с клавиатуры
(WM_CHAR), результат движения мыши (WM_MOUSEMOVE) и щелчков кнопки мыши (WM_LBOTTONDOWN).
Кроме этого синхронные сообщения включают в себя сообщение от таймера (WM_TIMER), сообщение о необходимости плановой перерисовки (WM_PAINT) и сообщение о выходе из программы (WM_QUIT). Сообщения становятся асинхронными во всех остальных случаях. Часто асинхронные сообщения являются результатом синхронных. При передаче асинхронного сообщения в DefWindowProc из оконной процедуры, Windows часто обрабатывает сообщение, отправляя оконной процедуре другие асинхронные сообщения.
Очевидно, что процесс этот сложен, но к счастью большая часть сложностей ложится на Windows, а не на наши программы. С позиции оконной процедуры, эти сообщения проходят через нее упорядочено или синхронно. Оконная процедура может что-то сделать с этими сообщениями, а может и проигнорировать их. По этой причине оконную процедуру назвали "конечным пунктом обработки" (ultimate hook). Сообщения извещают оконную процедуру почти обо всем, что влияет на окно.
Часто асинхронные сообщения являются результатом вызова определенных функций Windows или непосредственным результатом вызова функции SendMessage. (Кроме этого, сообщения могут помещаться в очередь сообщений посредством вызова функции PostMessage.)
Например, когда WinMain вызывает функцию CreateWindow, Windows создает окно и для этого отправляет оконной процедуре асинхронное сообщение WM_CREATE. Когда WinMain вызывает ShowWindow, Windows отправляет оконной процедуре асинхронные сообщения WM_SIZE и WM_SHOWWINDOW. Когда WinMain вызывает UpdateWindow, Windows отправляет оконной процедуре асинхронное сообщение WM_PAINT.
Сообщения не похожи на аппаратные прерывания. Во время обработки в оконной процедуре одного сообщения программа не может быть прервана другим сообщением. Только в том случае, если оконная процедура вызвала функцию, которая сама стала источником нового сообщения, то оконная процедура начнет обрабатывать это новое сообщение еще до того, как функция вернет управление программе.
1Необходимо уточнить дальнейшее использование атрибутов сообщения "синхронное" и "асинхронное". Ставится сообщение в очередь или не ставится, определяется способом его отправки. В оригинальном тексте книги для указания конкретного способа отправки сообщения используются слова send (функция SendMessage) и post (функция PostMessage). Если для отправки сообщения используется функция SendMessage, то оно не ставится в очередь, оконная процедура вызывается непосредственно, а функция возвращает управление только после обработки сообщения оконной процедурой. Если для отправки сообщения используется функция PostMessage, то оно ставится в очередь, а функция возвращает управление немедленно.
Таким образом, используя терминологию автора, можно сказать:
•если сообщение отправляется с помощью функции SendMessage, то оно является асинхронным;
•если сообщение отправляется с помощью функции PostMessage, то оно является синхронным.
(Прим. перев.).
39
Цикл обработки сообщений и оконная процедура работают не параллельно. Когда оконная процедура обрабатывает сообщение, то это результат вызова функции DispatchMessage в WinMain. DispatchMessage не завершается до тех пор, пока оконная процедура не обработала сообщение.
Но заметьте, что оконная процедура должна быть повторно-входимой (reentrant). Это означает, что Windows часто вызывает WndProc с новым сообщением, как результат вызова функции DefWindowProc в WndProc с предыдущим сообщением. В большинстве случаев повторная входимость оконной процедуры не создает проблем, но об этом следует знать.
Например, предположим, что вы вводите переменную в процесс обработки сообщения оконной процедурой и затем вызываете функцию Windows. Можете ли вы быть уверены в том, что после возврата функцией своего значения, ваша переменная осталась той же самой? Конечно, нет — в том случае, если конкретная функция Windows, которую вы вызвали, стала источником другого сообщения, и оконная процедура изменила вашу переменную при обработке этого второго сообщения. Это одна из причин того, что при компиляции программ для Windows необходимо отключать некоторые возможности оптимизации.
Часто возникает необходимость того, чтобы оконная процедура сохраняла информацию, полученную в сообщении, и использовала ее при обработке другого сообщения. Тогда эту информацию следует описывать в оконной процедуре в виде статических переменных, либо хранить в глобальных переменных.
Все вышеизложенное станет более понятным, когда вы прочитаете в следующих главах об оконных процедурах, способных обрабатывать большое число сообщений.
Думайте о ближнем
Windows 95 — это вытесняющая многозадачная среда. Это означает, что если программа работает слишком долго, то Windows может разрешить пользователю переключиться на другую программу. Это удобная вещь и одно из преимуществ Windows 95 по сравнению с предыдущими, основанными на DOS, версиями Windows.
Однако, поскольку Windows сконструирована определенным образом, эта вытесняющая многозадачность не всегда работает так, как бы вам хотелось. Например, предположим, что ваша программа тратит на обработку отдельного сообщения минуту или больше. Да, пользователь может переключиться на другую программу. Но пользователь ничего не в состоянии сделать с вашей программой. Пользователь не может переместить окно вашей программы, изменить его размер, закрыть его, т. е. вообще ничего. Так происходит потому, что, хотя ваша оконная процедура и должна выполнять все эти задачи, но она занята выполнением слишком долгой работы. Конечно, может показаться, что оконная процедура не выполняет операций по изменению размера и перемещению собственного окна, но, тем не менее, она это делает. Это часть работы функции DefWindowProc, которую, в свою очередь, необходимо считать частью оконной процедуры.
Если для вашей программы необходимо долго обрабатывать отдельные сообщения, то в главе 14 описан удобный способ сделать это. Даже при наличии вытесняющей многозадачности, не слишком хорошо оставлять ваше окно безвольно висящим на экране. Оно мешает пользователям, и они просто вашу программу будут ругать.
Кривая обучения
Да, как вы, несомненно, поняли из этой главы, программирование для Windows определенно отличается от программирования для общепринятой среды типа MS-DOS. Никто не станет утверждать, что программировать для
Windows легко.
При первом изучении программирования для Windows обычно делают то, что всегда делается при изучении новой операционной системы или нового языка программирования — пишется простая программа для вывода на экран содержимого файла. В общепринятой среде MS-DOS такая программа включает в себя обработку командной строки, простейший файловый Ввод/Вывод и форматирование вывода на экран. В отличии от этого, аналогичная программа для Windows превращается в монстра. Она требует изучения меню, окон диалога, полос прокрутки и т. д. Так как это ваша первая программа для Windows, то из-за необходимости сразу усвоить слишком большой объем материала, она обычно оказывается совершенно неправильной.
Когда работа над программой подходит к концу, она уже совершенно отличается от любой программы, которую вы когда-либо писали. Вместо командной строки для ввода имени файла, программа WINDUMP (назовем ее так) предлагает на экране список всех файлов текущего каталога. Вместо последовательной печати на экране содержимого файла, как это происходит в обычном телетайпе, WINDUMP имеет полосы прокрутки, и можно перемещаться в любую часть файла. И как особая награда, можно запустить две копии WINDUMP и сравнить два находящихся рядом файла. Короче говоря, из всех ранее написанных программ для вывода содержимого файла на экран WINDUMP первая, которой можно действительно гордиться.
Выясните для себя следующий вопрос: нужно ли, чтобы в ваших программах использовался современный и удобный пользовательский интерфейс, включающий в себя меню, окна диалога, полосы прокрутки и графику?
40
Если да, тогда еще один вопрос: хотите ли вы сами программировать все эти меню, окна диалога, полосы прокрутки и графику? Или было бы лучше воспользоваться уже подготовленными для этого программами Windows? Другими словами, что проще: узнать, как использовать более 1000 функций, или писать их самому? Что проще: направить свои силы на изучение управляемой сообщениями архитектуры Windows, или бороться с разнообразными вариантами организации пользовательского ввода в традиционной модели программирования?
Если вы собираетесь создавать собственную логику интерфейса, вам было бы лучше закрыть эту книгу и заняться своим делом. Тем временем другим читателям предстоит в следующей главе выяснить, как вывести на экран окно с текстом и просмотреть там этот текст.