- •Содержание
- •Глава 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
Глава 11 Окна диалога 11
Наиболее часто окна диалога или диалоговые окна используются для получения от пользователя дополнительной информации сверх той, которую может обеспечить меню. Программист показывает, что выбор какого-то пункта меню вызывает появления окна диалога, с помощью многоточия (...) после текста этого пункта меню.
Окно диалога обычно имеет вид всплывающего окна с разнообразными дочерними окнами элементов управления внутри. Размер и расположение этих дочерних окон задается в шаблоне окна диалога (dialog box template) в файле описания ресурсов программы. Microsoft Windows 95 обеспечивает возможность создания всплывающих окон диалога и дочерних окон элементов управления в нем, и возможность обработки оконной процедурой сообщений окна диалога (включая все сообщения клавиатуры и мыши). Тот код внутри Windows, который дает возможность все это сделать, иногда называют менеджером окна диалога (dialog box manager).
Многие сообщения, которые обрабатываются оконной процедурой окна диалога внутри Windows, также передаются и в вашу собственную программу в функцию, называемую процедурой окна диалога (dialog box procedure) или просто процедурой диалога (dialog procedure). Эта функция похожа на обычную оконную процедуру, но она имеет некоторые важные особенности. Как правило, внутри процедуры диалога не реализуется слишком много функций. Исключение составляют лишь инициализация дочерних окон элементов управления при создании окна диалога, обработка сообщений от дочерних окон элементов управления и завершение работы с окном диалога.
Рассмотрение окон диалога обычно бывает одним из самых объемных, поскольку оно включает в себя и описание дочерних окон элементов управления. Однако, материал о дочерних окнах элементов управления был представлен в главе 8. При использовании дочерних окон элементов управления, менеджер окна диалога Windows берет на себя решение многих из тех задач, с которыми нам пришлось столкнуться в главе 8. Например, проблемы, имевшие место в программе COLOR1 при передаче фокуса ввода от одной полосы прокрутки к другой, в окнах диалога не возникают. Windows управляет всей логикой переключения фокуса ввода между дочерними окнами элементов управления в окне диалога.
Тем не менее добавление в программу окна диалога – это непростая задача. Она требует внесения изменений в несколько файлов: шаблон окна диалога помещается в файл описания ресурсов, процедура окна диалога – в файл с исходными кодами программы, а идентификаторы, которые используются в окне диалога, часто вносятся в заголовочный файл программы. Для того чтобы почувствовать взаимозависимость всех этих составляющих, начнем с простого окна диалога.
Модальные окна диалога
Окна диалога бывают модальными (modal) или немодальными (modeless). Чаще всего встречаются модальные окна диалога. Если программа выводит на экран модальное окно диалога, то пользователь программы не может переключаться между окном диалога и другими окнами программы. Пользователь должен сначала закончить работу с окном диалога, это обычно делается путем щелчка на кнопке, помеченной либо OK, либо Cancel. Но, несмотря на наличие на экране окна диалога, пользователь может переключаться на другие программы. Некоторые окна диалога (называемые системными модальными окнами) этого делать не позволяют. Системное модальное окно диалога вынуждает пользователя, перед тем как он получит возможность сделать что-либо другое в Windows, завершить работу с ним.
Создание окна диалога About
Даже в тех программах для Windows, в которых ввод не требуется, окно диалога будет появляться достаточно часто, оно вызывается опцией About меню большинства программ. В этом окне диалога на экран выводится имя и значок программы, сведения об авторских правах, кнопка с надписью OK и, может быть, еще какая-то
356
информация. Предлагаемая вашему вниманию программа не делает ничего, кроме отображения окна диалога About. Программа ABOUT1 представлена на рис. 11.1.
ABOUT1.MAK
#----------------------
# ABOUT1.MAK make file
#----------------------
about1.exe : about1.obj about1.res
$(LINKER) $(GUIFLAGS) -OUT:about1.exe about1.obj about1.res $(GUILIBS)
about1.obj : about1.c about1.h $(CC) $(CFLAGS) about1.c
about1.res : about1.rc about1.h about1.ico $(RC) $(RCVARS) about1.rc
ABOUT1.C
/*------------------------------------------ |
|
|
|
ABOUT1.C |
-- About Box Demo Program No. 1 |
||
|
|
(c) Charles Petzold, 1996 |
|
------------------------------------------ |
|
|
*/ |
#include <windows.h> |
|
||
#include "about1.h" |
|
||
LRESULT CALLBACK WndProc |
(HWND, UINT, WPARAM, LPARAM); |
||
BOOL |
CALLBACK AboutDlgProc(HWND, UINT, WPARAM, LPARAM); |
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
PSTR szCmdLine, int iCmdShow) |
{ |
|
static char |
szAppName[] = "About1"; |
MSG |
msg; |
HWND |
hwnd; |
WNDCLASSEX |
wndclass; |
wndclass.cbSize |
= sizeof(wndclass); |
wndclass.style |
= CS_HREDRAW | CS_VREDRAW; |
wndclass.lpfnWndProc |
= WndProc; |
wndclass.cbClsExtra |
= 0; |
wndclass.cbWndExtra |
= 0; |
wndclass.hInstance |
= hInstance; |
wndclass.hIcon |
= LoadIcon(hInstance, szAppName); |
wndclass.hCursor |
= LoadCursor(NULL, IDC_ARROW); |
wndclass.hbrBackground |
=(HBRUSH) GetStockObject(WHITE_BRUSH); |
wndclass.lpszMenuName |
= szAppName; |
wndclass.lpszClassName |
= szAppName; |
wndclass.hIconSm |
= LoadIcon(hInstance, szAppName); |
RegisterClassEx(&wndclass);
hwnd = CreateWindow(szAppName, "About Box Demo Program", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL);
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
357
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
static WNDPROC lpfnAboutDlgProc; static HINSTANCE hInstance;
switch(iMsg)
{
case WM_CREATE :
hInstance =((LPCREATESTRUCT) lParam)->hInstance; return 0;
case WM_COMMAND : switch(LOWORD(wParam))
{
case IDM_ABOUT :
DialogBox(hInstance, "AboutBox", hwnd, AboutDlgProc); return 0;
}
break;
case WM_DESTROY : PostQuitMessage(0); return 0;
}
return DefWindowProc(hwnd, iMsg, wParam, lParam);
}
BOOL CALLBACK AboutDlgProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
switch(iMsg)
{
case WM_INITDIALOG : return TRUE;
case WM_COMMAND : switch(LOWORD(wParam))
{
case IDOK : case IDCANCEL :
EndDialog(hDlg, 0); return TRUE;
}
break;
}
return FALSE;
}
ABOUT1.RC
/*---------------------------
ABOUT1.RC resource script
---------------------------*/
#include <windows.h> #include "about1.h"
About1 ICON about1.ico
About1 MENU
{
358
POPUP "&Help" |
|
|
|
|
|
{ |
|
|
|
|
|
|
MENUITEM "&About About1...", |
|
IDM_ABOUT |
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
AboutBox DIALOG 20, 20, 160, 80 |
|
|
|
||
STYLE WS_POPUP | WS_DLGFRAME |
|
|
|
||
{ |
|
|
|
|
|
CTEXT "About1" |
|
-1, |
0, 12, 160, |
8 |
|
ICON "About1" |
|
-1, |
8, 8, 0, |
0 |
|
CTEXT "About Box Demo Program" |
-1, |
0, 36, 160, |
8 |
||
CTEXT "(c) Charles Petzold, 1996" |
-1, |
0, 48, 160, |
8 |
||
DEFPUSHBUTTON "OK" |
IDOK, |
64, 60, 32, 14, WS_GROUP |
|||
} |
|
|
|
|
|
ABOUT1.H |
|
|
|
|
|
/*---------------------- |
|
|
|
||
ABOUT1.H header file |
|
|
|
||
----------------------*/ |
|
|
|
||
#define IDM_ABOUT |
1 |
|
|
|
|
ABOUT1.ICO |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Рис. 11.1 Программа ABOUT1
Шаблон окна диалога
Первой задачей, которую нужно решить для добавления в программу окна диалога, является создание шаблона окна диалога. Этот шаблон может быть помещен прямо в файл описания ресурсов, или он может быть создан в отдельном файле, для которого по договоренности используется расширение .DLG (dialog). При создании для шаблона отдельного файла, в файл описания ресурсов включается строка:
rcinclude filename.dlg
Шаблон окна диалога можно создавать вручную с помощью текстового редактора или можно использовать какойнибудь инструмент для автоматизации этого процесса. Поскольку результат работы таких инструментов не может быть приведен здесь, то те шаблоны окон диалога, которые здесь показаны, будут выглядеть так, как будто они создавались вручную.
Шаблон окна диалога программ ABOUT1 выглядит следующим образом:
AboutBox DIALOG 20, 20, 160, 80 |
|
|
STYLE WS_POPUP | WS_DLGFRAME |
|
|
{ |
|
|
CTEXT "About1" |
-1, 0, 12, 160, 8 |
|
ICON "About1" |
-1, 8, 8, 0, |
0 |
CTEXT "About Box Demo Program" |
-1, 0, 36, 160, 8 |
|
CTEXT "(c) Charles Petzold, 1996" |
-1, 0, 48, 160, 8 |
|
DEFPUSHBUTTON "OK" |
IDOK,64,60, 32, |
14, WS_GROUP |
} |
|
|
В первой строке окну диалога дается имя (в данном случае AboutBox). Как и для других ресурсов, вместо имени можно использовать число. За именем следует ключевое слово DIALOG и четыре числа. Первые два — являются координатами х и у верхнего левого угла окна диалога относительно рабочей области родительского окна при вызове окна диалога программой. Вторые два числа — это ширина и высота окна диалога.
Эти координаты и размеры даются не в пикселях. Значения координат и размеров базируются на специальной системе координат, используемой только для шаблонов окон диалога. Числа основываются на размере символа системного шрифта: координата х и ширина выражены в единицах, равных 1/4 средней ширины символа; координата у и высота выражены в единицах, равных 1/8 высоты символа. Таким образом, для данного приведенного окна диалога верхний левый угол окна диалога находится на расстоянии 5 символов от левого края