- •Содержание
- •Глава 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
318
Как правило, в программах для Windows это сообщение передается DefWindowProc, которая обычно возвращает 0 в Windows, после чего Windows издает звуковой сигнал (гудок). Мы рассмотрим использование сообщения WM_MENUCHAR в программе GRAFMENU, которая представлена далее в этой главе.
Образец программы
Рассмотрим простой пример. В программе MENUDEMO, представленной на рис. 10.1, в главном меню имеется пять пунктов — File, Edit, Background, Timer и Help. В каждом из этих пунктов имеется всплывающее меню. В программе MENUDEMO демонстрируется простейший и наиболее частый способ обработки сообщений меню, который подразумевает перехват сообщений WM_COMMAND и анализ младшего слова параметра wParam.
MENUDEMO.MAK
#------------------------
# MENUDEMO.MAK make file
#------------------------
menudemo.exe : menudemo.obj menudemo.res
$(LINKER) $(GUIFLAGS) -OUT:menudemo.exe menudemo.obj \ menudemo.res $(GUILIBS)
menudemo.obj : menudemo.c menudemo.h $(CC) $(CFLAGS) menudemo.c
menudemo.res : menudemo.rc menudemo.h $(RC) $(RCVARS) menudemo.rc
MENUDEMO.C
/*----------------------------------------- |
|
MENUDEMO.C -- |
Menu Demonstration |
|
(c) Charles Petzold, 1996 |
----------------------------------------- |
*/ |
#include <windows.h> #include "menudemo.h"
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
char szAppName[] = "MenuDemo";
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{ |
|
|
HWND |
hwnd; |
|
MSG |
msg; |
|
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(NULL, IDI_APPLICATION); |
|
wndclass.hCursor |
= LoadCursor(NULL, IDC_ARROW); |
|
wndclass.hbrBackground |
=(HBRUSH) GetStockObject(WHITE_BRUSH); |
|
wndclass.lpszMenuName |
= szAppName; |
|
wndclass.lpszClassName |
= szAppName; |
|
wndclass.hIconSm |
= LoadIcon(NULL, IDI_APPLICATION); |
RegisterClassEx(&wndclass);
hwnd = CreateWindow(szAppName, "Menu Demonstration", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
319
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL);
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
static int
static int HMENU
switch(iMsg)
{
case WM_COMMAND :
hMenu = GetMenu(hwnd);
switch(LOWORD(wParam))
{
case IDM_NEW : case IDM_OPEN : case IDM_SAVE : case IDM_SAVEAS :
MessageBeep(0); return 0;
case IDM_EXIT :
SendMessage(hwnd, WM_CLOSE, 0, 0L); return 0;
case IDM_UNDO : case IDM_CUT : case IDM_COPY : case IDM_PASTE : case IDM_DEL :
MessageBeep(0); return 0;
case IDM_WHITE : |
// Note: Logic below |
|
case IDM_LTGRAY : |
// |
assumes that IDM_WHITE |
case IDM_GRAY : |
// |
through IDM_BLACK are |
case IDM_DKGRAY : |
// |
consecutive numbers in |
case IDM_BLACK : |
// the order shown here. |
CheckMenuItem(hMenu, iSelection, MF_UNCHECKED);
iSelection = LOWORD(wParam);
CheckMenuItem(hMenu, iSelection, MF_CHECKED);
SetClassLong(hwnd, GCL_HBRBACKGROUND,
(LONG) GetStockObject
(iColorID[LOWORD(wParam) - IDM_WHITE]));
InvalidateRect(hwnd, NULL, TRUE); return 0;
320
case IDM_START :
if(SetTimer(hwnd, 1, 1000, NULL))
{
EnableMenuItem(hMenu, IDM_START, MF_GRAYED);
EnableMenuItem(hMenu, IDM_STOP, MF_ENABLED);
}
return 0;
case IDM_STOP : KillTimer(hwnd, 1);
EnableMenuItem(hMenu, IDM_START, MF_ENABLED); EnableMenuItem(hMenu, IDM_STOP, MF_GRAYED); return 0;
case IDM_HELP :
MessageBox(hwnd, "Help not yet implemented!", szAppName, MB_ICONEXCLAMATION | MB_OK);
return 0;
case IDM_ABOUT :
MessageBox(hwnd, "Menu Demonstration Program.",
szAppName, MB_ICONINFORMATION | MB_OK);
return 0;
}
break;
case WM_TIMER : MessageBeep(0); return 0;
case WM_DESTROY : PostQuitMessage(0); return 0;
}
return DefWindowProc(hwnd, iMsg, wParam, lParam);
}
MENUDEMO.RC
/*-----------------------------
MENUDEMO.RC resource script
-----------------------------*/
#include "menudemo.h" |
|
MenuDemo MENU |
|
{ |
|
POPUP "&File" |
|
{ |
|
MENUITEM "&New", |
IDM_NEW |
MENUITEM "&Open...", |
IDM_OPEN |
MENUITEM "&Save", |
IDM_SAVE |
MENUITEM "Save &As...", |
IDM_SAVEAS |
MENUITEM SEPARATOR |
|
MENUITEM "E&xit", |
IDM_EXIT |
} |
|
POPUP "&Edit" |
|
{ |
|
MENUITEM "&Undo", |
IDM_UNDO |
MENUITEM SEPARATOR |
|
MENUITEM "Cu&t", |
IDM_CUT |
MENUITEM "&Copy", |
IDM_COPY |
MENUITEM "&Paste", |
IDM_PASTE |
MENUITEM "De&lete", |
IDM_DEL |
} |
|
POPUP "&Background" |
|
321
{
MENUITEM "&White",
MENUITEM "&Lt Gray",
MENUITEM "&Gray",
MENUITEM "&Dk Gray",
MENUITEM "&Black",
}
POPUP "&Timer"
{
MENUITEM "&Start"
MENUITEM "S&top"
}
POPUP "&Help"
{
MENUITEM "&Help...",
MENUITEM "&About MenuDemo...",
}
}
MENUDEMO.H
/*------------------------
MENUDEMO.H header file
------------------------*/
#define IDM_NEW |
1 |
#define IDM_OPEN |
2 |
#define IDM_SAVE |
3 |
#define IDM_SAVEAS |
4 |
#define IDM_EXIT |
5 |
#define IDM_UNDO |
10 |
#define IDM_CUT |
11 |
#define IDM_COPY |
12 |
#define IDM_PASTE |
13 |
#define IDM_DEL |
14 |
#define IDM_WHITE |
20 |
#define IDM_LTGRAY |
21 |
#define IDM_GRAY |
22 |
#define IDM_DKGRAY |
23 |
#define IDM_BLACK |
24 |
#define IDM_START |
30 |
#define IDM_STOP |
31 |
#define IDM_HELP |
40 |
#define IDM_ABOUT |
41 |
IDM_WHITE, CHECKED IDM_LTGRAY IDM_GRAY IDM_DKGRAY IDM_BLACK
IDM_START IDM_STOP, GRAYED
IDM_HELP
IDM_ABOUT
Рис. 10.1 Программа MENUDEMO
Все идентификаторы пунктов меню определяются в заголовочном файле MENUDEMO.Н. Этот файл должен быть включен (с помощью инструкции #include) в файл описания ресурсов и в файл с исходным текстом программы на С. Идентификаторы начинаются с букв IDM. Значения идентификаторов не обязательно должны быть последовательными. Однако, если в программе эти идентификаторы обрабатываются с помощью операторов switch и case, то запомните, что компилятор С гораздо лучше оптимизирует этот код, если значения идентификаторов будут последовательными.
Программа MENUDEMO просто издает звуковой сигнал (гудок) при получении сообщения WM_COMMAND для большинства пунктов всплывающих меню File и Edit. Во всплывающем меню Background перечисляются пять стандартных кистей, которые программа MENUDEMO может использовать для закрашивания фона. В файле описания ресурсов MENUDEMO.RC пункт меню White (с идентификатором меню IDM_WHITE) устанавливается в состояние CHECKED, что вызывает появление метки около этого элемента. В исходном тексте программы MENUDEMO.C начальное значение iSelection устанавливается равным IDM_WHITE.