- •Часть II. Проектирование пользовательских интерфейсов средствами win32 api п 1. Основы приложений для Windows. П 1.1 Типы данных Windows.
- •П. 1.2 Главная функция приложения WinMain().
- •П. 1.3 Оконная функция.
- •П. 1.4 Сообщения от окна
- •П. 1.5 Сообщения от мыши
- •1.5.1 Сообщения мыши, связанные с рабочей областью окна
- •1.5.3 Двойные щелчки мыши
- •1.5.4 Сообщения мыши, связанные с нерабочей областью окна
- •1.5.5 Захват мыши
- •П. 1.6 Сообщения от клавиатуры
- •1.6.1 Синхронизация событий клавиатуры
- •1.6.2 Игнорирование событий клавиатуры
- •1.6.3 Понятие фокуса ввода
- •1.6.4 Категории клавиатурных сообщений
- •1.6.5 Аппаратные сообщения
- •1.6.6 Символьные сообщения
- •П. 1.7 Таймеры Windows и служба времени.
- •П. 1.8 Классы окон
- •1.8.1. Описание используемых классом окон ресурсов
- •1.8.2. Регистрация класса окон
- •1.8.3. Создание окон
- •1.8.4. Стили окна
- •П. 1.9 Цикл обработки сообщений
- •П. 1.10 Структура текста приложения
- •П. 1.11 Вспомогательные функции создания окон
- •1.11.1 Функции отображения и перерисовки окон
- •1.11.2 Функции поиска и определения состояния окон
- •1.11.3 Функции перемещения окон
- •1.11.4 Сообщения приложения для пользователя
- •П. 1.12 Примеры создания окон
- •П 2. Органы управления
- •П 2.1. Кнопки
- •2.1.1. Создание кнопок
- •2.1.2. Кнопки и сообщения
- •2.1.3. Флажки и переключатели
- •П 2.2. Статический орган управления
- •П 2.3. Полоса прокрутки
- •2.3.1. Общие сведения
- •2.3.2. Создание полосы прокрутки
- •2.3.3. Простейшие полосы прокрутки
- •2.3.4. Сообщения от полосы прокрутки
- •2.3.5. Управление полосой прокрутки
- •П 2.4 Редактор текста
- •2.4.1. Создание редактора
- •2.4.2. Сообщения для редактора текста
- •2.4.3. Сообщения от редактора текста
- •П 2.5. Списки строк
- •2.5.1. Создание списка
- •2.5.2. Сообщения от списка
- •2.5.3. Сообщения для списка
- •П. 2.6. Комбинированный список
- •2.6.1. Создание комбинированного списка
- •2.6.2. Коды извещения
- •2.6.3. Сообщения для комбинированного списка
- •П 3. Вывод в окно
- •П. 3.1. Виды контекста отображения
- •П 3.2. Сообщение wm_paint
- •П 3.3. Установка атрибутов контекста отображения для текста
- •П 3.4. Вывод текста
- •3.4.1. Настройка параметров шрифта
- •3.4.2. Выбор шрифта в контекст отображения
- •3.4.3. Функции вывода текста
- •3.4.4. Определение метрик шрифта
- •П 3.5. Рисование геометрических фигур
- •3.5.1 Установка атрибутов контекста отображения для рисования.
- •3.5.1. Функции рисования точки
- •3.5.2. Функции рисования линий
- •3.5.3. Функции рисования замкнутых фигур
- •3.5.4 Функции создания и рисования регионов
- •П. 4 Ресурсы приложения и их использование. П. 4.1 Файл ресурсов.
- •П 4.2 Главное меню
- •П. 4.2.1 Элементы меню
- •П. 4.2.2 Создание меню
- •П. 4.2.3 Сообщения от меню
- •П. 4.3. Плавающее меню
- •П. 4.4. Акселераторы
- •П. 4.5. Панель инструментов
- •4.5.1. Создание панели инструментов
- •4.5.2. Управление состоянием кнопок панели
- •4.5.3. Вывод подсказок в панели инструментов
- •П. 4.6. Строка состояния
- •4.6.1. Создание строки состояния
- •4.6.2. Сообщения о меню в строке состояний
- •П 5. Диалоговые панели п. 5.1. Характеристики диалоговых панелей
- •5.1.1. Единицы диалоговой панели '
- •5.1.2. Стили диалоговой панели
- •5.1.3. Функция окна диалоговой панели
- •П. 5.2. Создание диалоговой панели
- •5.2.1 Создание окна модальной диалоговой панели
- •5.2.2 Создание окна немодальной диалоговой панели
- •П. 5.3 Разработка и компоновка диалоговых панелей.
- •П. 5.4 Сообщения и диалоговые панели
- •П. 5.5. Стандартные диалоговые панели
- •5.5.1. Панели для открытия или сохранения файлов
- •5.5.2. Панель для выбора цветов
- •5.5.3. Панель для выбора шрифта
П. 1.9 Цикл обработки сообщений
ОС Windows общается с программой путем посылки ей сообщений. Все приложения Windows должны иметь в функции WinMain() цикл обработки сообщений. Этот цикл читает сообщения из очереди сообщений приложения и направляет их назад в Windows, которая затем вызывает оконную функцию программы, передавая ей это сообщение в качестве параметра.
Такой способ функционирования связан с тем, что программа должна возвращать управление планировщику Windows, который занимается распределением времени центрального процессора с целью оптимизации его загрузки.
Всякий раз, когда приложение готово прочитать следующее сообщение, оно должно вызывать функцию API GetMessage. Она имеет следующий прототип:
BOOL GetMessage( LPMSG lpmsg, HWND hwnd,
WORD uMsgFilterMin, WORD uMsgFilterMax);
Параметр lpmsg указывает на структуру типа MSG, в которую будет записано выбираемое сообщение, hwnd - дескриптор окна, для которого нужно выбрать сообщение. Если hwnd=NULL, то выбираются сообщения для всех окон приложения. Параметры uMsgFilterMin и uMsgFilterMax указывают диапазон выбираемых сообщений, задавая соответственно минимальное и максимальное значение кодов сообщений. Если для этих параметров указать нулевые значения, из очереди будут выбираться все сообщения.
Функция GetMessage выбранное сообщение удаляет из очереди и записывает его в структуру, адрес которой задан ее первым параметром. При выборке сообщения с кодом WM_QUIT она возвращает 0, и завершается цикл обработки сообщений. При выборке других сообщений функция GetMessage возвращает ненулевое значение.
После этого функция WinMain возвращает управление и значение поля wParam последнего сообщения операционной системе.
Структура типа MSG описана следующим образом:
typedef struct
{ HWND hwnd; //Дескриптор окна-адресата
UINT message; //Код сообщения
WPARAM wParam; //Содержимое сообщения
LPARAM lParam; //Содержимое сообщения
DWORD time; //Время отправления
POINT pt; //Координаты места отправления
} MSG; //Имя типа
Цикл обработки сообщений имеет следующий вид:
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMesage(&msg);
}
Функция GetMessage заполняет поля структуры msg данными следующего сообщения из очереди. Вызов DispatchMesage вызывает соответствующую оконную процедуру. Между двумя этими функциями находится функция TranslateMessage.
Функция TranslateMessage преобразует аппаратные сообщения клавиатуры в символьные сообщения. Если этим сообщением является WM_KEYDOWN (WM_SYSKEYDOWN) и, если нажатие клавиши в сочетании с положением клавиши сдвига генерирует символ, тогда TranslateMessage помещает символьное сообщение в очередь сообщений.
Это символьное сообщение будет следующим, после сообщения о нажатии клавиши, которое функция GetMessage извлечет из очереди.
П. 1.10 Структура текста приложения
Структура текста приложения определяется двумя требованиями:
1. Текст содержит описание функции с именем WinMain.
2. Если регистрируются новые классы, то текст содержит описание структуры типа WNDCLASS и функций окон этих классов.
Следующее приложение регистрирует класс перекрывающихся окон, создает окно этого класса и передает управление циклу обработки сообщений.
// Иллюстрация структуры простейшего приложения.
#include <windows.h>
//Описание прототипов функций
LRESULT CALLBACK MainWindow(HWND, UINT, WPARAM, LPARAM);
//Описание глобальных переменных
char Name[]="MainWindow";
HINSTANCE hinst;
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE Prev,
LPSTR Line,
int Show)
{
MSG msg;
HWND hwnd;
hinst=hInstance;
//Описываем класс окна
WNDCLASS wc;
wc.style=wc.cbClsExtra=wc.cbWndExtra=0;
wc.lpfnWndProc=WndProc;
wc.hInstance=hinst;
wc.hIcon=LoadIcon(NULL,IDI_APPLICATION);
wc.hCursor=LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground=(HBRUSH)(color+1);
wc.lpszMenuName=NULL;
wc.lpszClassName=Name;
wc.style=CS_HREDRAW | CS_VREDRAW;
//Регистрируем класс окна
if (RegisterClass(&wc)==0) return FALSE;
//Создаем окно класса Name
hwnd=CreateWindow(Name,"Каркас приложения для Windows",
WS_OVERLAPPEDWINDOW|WS_VISIBLE,
0,0,750,550,0, 0, hInstance, NULL);
if (!hwnd) return FALSE;
//Вызываем цикл обработки сообщений
while (GetMessage(&msg, 0, 0, 0)) DispatchMessage(&msg);
return msg.wParam;
}
//Описываем оконную функцию
LRESULT CALLBACK MainWindow(HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_DESTROY:
{PostQuitMessage(0); return (0);}
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
Как видно из листинга, приложение является обычной программой языка Си. Текст содержит привычные директивы, объявления и описания. Отличие содержится в заголовке главной функции, в специфической функции окна и в способе ее вызова.
Рассмотрим алгоритм работы этого приложения.
1. Классы окон регистрируют в начале работы приложения.
2. Окно приложения создают до передачи управления циклу обработки сообщений.
3. Управление передают циклу обработки сообщений. В теле этого цикла выбираются и распределяются сообщения.
4. Функция окна обрабатывает сообщение WM_DESTROY, а остальные сообщения возвращает системе. Функция окна приложения должна обрабатывать это сообщение.
5. Приложение завершает работу.
Таким же является алгоритм работы большинства приложений. Отличие между ними в основном заключается в функциях окон.