- •Содержание
- •Глава 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
364
Более сложное окно диалога
В программе ABOUT1 проиллюстрированы основы работы с простым окном диалога; теперь попытаемся сделать нечто более сложное. Программа ABOUT2, представленная на рис. 11.3, показывает, как работать с дочерними окнами элементов управления (в данном случае с группой переключателей) внутри процедуры окна диалога, и как рисовать в рабочей области окна диалога.
ABOUT2.MAK
#----------------------
# ABOUT2.MAK make file
#----------------------
about2.exe : about2.obj about2.res
$(LINKER) $(GUIFLAGS) -OUT:about2.exe about2.obj about2.res $(GUILIBS)
about2.obj : about2.c about2.h $(CC) $(CFLAGS) about2.c
about2.res : about2.rc about2.h about2.ico $(RC) $(RCVARS) about2.rc
ABOUT2.C
/*------------------------------------------ |
|
|
|
ABOUT2.C |
-- About Box Demo Program No. 2 |
||
|
|
(c) Charles Petzold, 1996 |
|
------------------------------------------ |
|
|
*/ |
#include <windows.h> |
|
||
#include "about2.h" |
|
||
LRESULT CALLBACK WndProc |
(HWND, UINT, WPARAM, LPARAM); |
||
BOOL |
CALLBACK AboutDlgProc(HWND, UINT, WPARAM, LPARAM); |
int iCurrentColor = IDD_BLACK, iCurrentFigure = IDD_RECT;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{ |
|
static char |
szAppName[] = "About2"; |
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);
365
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
void PaintWindow(HWND hwnd, int iColor, int iFigure) |
|
|
||
{ |
|
|
|
|
static COLORREF crColor[8] = { RGB(0, |
0, 0), RGB( |
0, |
0, 255), |
|
|
RGB(0, |
255, 0), RGB( |
0, 255, 255), |
|
|
RGB(255, |
0, 0), RGB(255, |
0, 255), |
|
|
RGB(255, 255, 0), RGB(255, 255, 255) }; |
|||
HBRUSH |
hBrush; |
|
|
|
HDC |
hdc; |
|
|
|
RECT |
rect; |
|
|
|
hdc = GetDC(hwnd); GetClientRect(hwnd, &rect);
hBrush = CreateSolidBrush(crColor[iColor - IDD_BLACK]); hBrush =(HBRUSH) SelectObject(hdc, hBrush);
if(iFigure == IDD_RECT)
Rectangle(hdc, rect.left, rect.top, rect.right, rect.bottom);
else
Ellipse (hdc, rect.left, rect.top, rect.right, rect.bottom);
DeleteObject(SelectObject(hdc, hBrush));
ReleaseDC(hwnd, hdc);
}
void PaintTheBlock(HWND hCtrl, int iColor, int iFigure)
{
InvalidateRect(hCtrl, NULL, TRUE);
UpdateWindow(hCtrl);
PaintWindow(hCtrl, iColor, iFigure);
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
static HINSTANCE hInstance; PAINTSTRUCT ps;
switch(iMsg)
{
case WM_CREATE :
hInstance =((LPCREATESTRUCT) lParam)->hInstance; return 0;
case WM_COMMAND : switch(LOWORD(wParam))
{
case IDM_ABOUT :
if(DialogBox(hInstance, "AboutBox", hwnd, AboutDlgProc))
InvalidateRect(hwnd, NULL, TRUE); return 0;
}
break;
366
case WM_PAINT : BeginPaint(hwnd, &ps); EndPaint(hwnd, &ps);
PaintWindow(hwnd, iCurrentColor, iCurrentFigure); return 0;
case WM_DESTROY : PostQuitMessage(0); return 0;
}
return DefWindowProc(hwnd, iMsg, wParam, lParam);
}
BOOL CALLBACK AboutDlgProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
static HWND hCtrlBlock; static int iColor, iFigure;
switch(iMsg)
{
case WM_INITDIALOG :
iColor = iCurrentColor; iFigure = iCurrentFigure;
CheckRadioButton(hDlg, IDD_BLACK, IDD_WHITE, iColor);
CheckRadioButton(hDlg, IDD_RECT, IDD_ELL, iFigure);
hCtrlBlock = GetDlgItem(hDlg, IDD_PAINT);
SetFocus(GetDlgItem(hDlg, iColor)); return FALSE;
case WM_COMMAND : switch(LOWORD(wParam))
{
case IDOK :
iCurrentColor = iColor; iCurrentFigure = iFigure; EndDialog(hDlg, TRUE); return TRUE;
case IDCANCEL : EndDialog(hDlg, FALSE); return TRUE;
case IDD_BLACK : case IDD_RED : case IDD_GREEN : case IDD_YELLOW : case IDD_BLUE : case IDD_MAGENTA : case IDD_CYAN : case IDD_WHITE :
iColor = LOWORD(wParam);
CheckRadioButton(hDlg, IDD_BLACK, IDD_WHITE, LOWORD
(wParam));
PaintTheBlock(hCtrlBlock, iColor, iFigure); return TRUE;
case IDD_RECT : case IDD_ELL :
iFigure = LOWORD(wParam);
367
CheckRadioButton(hDlg, IDD_RECT, IDD_ELL, LOWORD
(wParam));
PaintTheBlock(hCtrlBlock, iColor, iFigure); return TRUE;
}
break;
case WM_PAINT :
PaintTheBlock(hCtrlBlock, iColor, iFigure); break;
}
return FALSE;
}
ABOUT2.RC
/*---------------------------
ABOUT2.RC resource script
---------------------------*/
#include <windows.h> #include "about2.h"
about2 ICON about2.ico
About2 MENU
{
POPUP "&Help"
{
MENUITEM "&About About2...", IDM_ABOUT
}
}
#define TABGRP(WS_TABSTOP | WS_GROUP)
AboutBox DIALOG 20, 20, 140, 188 |
|
|
|
|
||
STYLE WS_POPUP | WS_DLGFRAME |
|
|
|
|
||
{ |
|
|
|
|
|
|
CTEXT |
"About2" |
-1, |
0, |
12, 140, |
8 |
|
ICON |
"About2" |
-1, |
8, |
8, |
0, |
0 |
CTEXT |
"About Box Demo Program" -1, 4, |
36, 130, |
8 |
|||
CTEXT |
"" |
IDD_PAINT, |
68, |
54, |
60, |
60 |
GROUPBOX |
"&Color" |
-1, |
4, |
50, |
54, 112 |
|
RADIOBUTTON |
"&Black" |
IDD_BLACK, |
8, |
60, |
40, |
12, TABGRP |
RADIOBUTTON |
"B&lue" |
IDD_BLUE, |
8, |
72, |
40, |
12 |
RADIOBUTTON |
"&Green" |
IDD_GREEN, |
8, |
84, |
40, |
12 |
RADIOBUTTON |
"Cya&n" |
IDD_CYAN, |
8, |
96, |
40, |
12 |
RADIOBUTTON |
"&Red" |
IDD_RED, |
8, 108, |
40, |
12 |
|
RADIOBUTTON |
"&Magenta" |
IDD_MAGENTA, |
8, 120, |
40, |
12 |
|
RADIOBUTTON |
"&Yellow" |
IDD_YELLOW, |
8, 132, |
40, |
12 |
|
RADIOBUTTON |
"&White" |
IDD_WHITE, |
8, 144, |
40, |
12 |
|
GROUPBOX |
"&Figure" |
-1, |
68, 120, |
60, |
40, WS_GROUP |
|
RADIOBUTTON |
"Rec&tangle" |
IDD_RECT, |
72, 134, |
50, |
12, TABGRP |
|
RADIOBUTTON "&Ellipse" |
IDD_ELL, |
72, 146, |
50, |
12 |
||
DEFPUSHBUTTON "OK" |
IDOK, |
20, 168, |
40, |
14, WS_GROUP |
||
PUSHBUTTON |
"Cancel" |
IDCANCEL, |
80, 168, |
40, |
14, WS_GROUP |
|
} |
|
|
|
|
|
|
ABOUT2.H
/*----------------------
ABOUT2.H header file
---------------------- |
*/ |
#define IDM_ABOUT |
1 |