
- •Лабораторная работа №1-3 (6 часов). Программирование в api.
- •Цель работы
- •Общие сведения
- •Типы данных Wundows
- •Основы программирования для Windows. Окна и очереди.
- •Окна Windows как объекты
- •Функция окна
- •Создание простейшего приложения FirsApp.
- •Создание каркаса приложения
- •Функция _tWinMain
- •Функция MyRegisterClass
- •Функция InitInstance
- •Функция окна WndProc()
- •Немного об отладке приложений Windows
- •Задания
- •Задание 1 – 25 баллов
- •Задание 2 – 50 баллов
- •Задание 3 – 50 баллов
- •Задание 4 – 100 баллов
-
Функция _tWinMain
В отличие от программы DOS, главная программа API для Windows должна иметь имя _tWinMain и тип APIENTRY. Кроме этого типа, мы будем использовать типы WINAPI и CALLBACK. Эти типы определены так:
#define CALLBACK __stdcall
#define WINAPI __stdcall
#define APIENTRY WINAPI
Согласно документации ключевое слово __stdcall определяет функцию, аргументы которой помещаются в стек справа налево.
Теперь о значениях параметров функции _tWinMain.
hInstance содержит идентификатор приложения.
hPrevInstance – идентификатор предыдущей копии приложения, если в системе работает несколько копий одного приложения. Если запущена только одна копия, то hPrevInstance имеет значение NULL. В среде Win32 значение этого идентификатора всегда NULL.
lpCmdLine указывает на строку параметров.
nCmdShow определяет способ отображения окна (минимизированное SW_MINIMIZE, нормальное SW_SHOW и т. д.).
В области стека функции _tWinMain созданы две переменные с именами hAccelTable и msg:
MSG msg; // структура для работы с сообщениями
HACCEL hAccelTable; // дескриптор таблицы акселераторов
Структура MSG предназначена для временного хранения сообщений и используется в цикле обработки сообщений. MSG определена в так:
typedef struct tagMSG
{
HWND hwnd; // дескриптор окна
UINT message; // номер сообщения;
WPARAM wParam; // дополнительная информация о сообщении
LPARAM lParam; // дополнительная информация о сообщении
DWORD time; // время, в момент постановки
// сообщения в очередь
POINT pt; // положение курсора мыши, в момент постановки
// сообщения в очередь
} MSG;
HACCEL hAccelTabl – это дескриптор таблицы акселераторов.
Дескриптор (handle) – это число, задающее номер какого-либо ресурса (блок памяти, файл, курсор, шрифт и т. п.). Дескриптор используется обычно при работе через некоторый интерфейс (API), причем смысл значения дескриптора скрыт за этим интерфейсом. Например, дескриптор блока памяти может означать номер ячейки в таблице адресов блоков памяти; поскольку пользователь API работает с дескриптором, а не с указателем, адрес размещения блока памяти может менятся, и это не скажется на работе с ним через дескриптор.
Работа функции _tWinMain начинается с вызова трех функций LoadString(). Назначение этих функций мы выясним позже. Далее следует вызов двух функций: MyRegisterClass() и InitInstance(), задающие параметры и свойства окна приложенияокна приложения. Завершает программу _tWinMain главный цикл обработки сообщений. Теперь, более подробно рассмотрим функции MyRegisterClass и InitInstance.
-
Функция MyRegisterClass
В функции MyRegisterClass определена одна локальная переменная - wcex.
WNDCLASSEX wcex; // структура для регистрации класса окна
Эта структура определена так:
typedef struct _WNDCLASSEX {
UINT cbSize; // размер структуры в байтах
UINT style; // стиль окна
WNDPROC lpfnWndProc; // указатель на оконную функцию
int cbClsExtra; // дополнительная память в байтах для
// описания класса
int cbWndExtra; // дополнительная память в байтах для
// для описания класса
HINSTANCE hInstance; // дескриптор приложения
HICON hIcon; // дескриптор пиктограммы
HCURSOR hCursor; // дескриптор курсора
HBRUSH hbrBackground; // цвет фона окна
LPCTSTR lpszMenuName; // идентификатор меню
LPCTSTR lpszClassName; // идентификатор класса окна
HICON hIconSm; // дескриптор маленькой пиктограммы
} WNDCLASSEX, *PWNDCLASSEX;
Теперь о формировании структуры wcex, выполняемой функцией MyRegisterClass.
Стиль окна style задаются в виде отдельных битов, для которых определены символические константы с префиксом CS_. Подробно стили рассмотрены в приложении 3.
В нашем приложении стиль окна задан так:
wcex.style = CS_HREDRAW | CS_VREDRAW;
В этом случае, при изменении горизонтального или вертикального размера окна, приложение будет его перерисовывать.
Передаем в структуру указатель на функцию окна, обрабатывающую сообщения и предназначенную для всех окон, созданных на основе данного класса.
wcex.lpfnWndProc = WndProc;
Этот указатель определен как глобальная переменная.
Инициализируем структуру дескриптором приложения:
wcex.hInstance = hInstance;
Рис.
2.2. Встроенные в Windows
пиктограммы.
a)
IDI_APPLICATION;
b)
IDI_ASTERISK;
c)
IDI_EXCLAMATION; d)
IDI_HAND;
e)
IDI_QUESTION;
f)
IDI_WINLOGO
(только
для
Windows 95)
Функция LoadCursor загружает курсор в виде стандартной стрелки.
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
Всего же имеется 12 стандартных курсоров. Их изображения и идентификаторы приведены на рис. 2.3.
Рис.
2.3. Встроенные
курсоры.
a)
IDC_APPSTARTING; b)
IDC_ARROW;
c)
IDC_CROSS; d)
IDC_IBEAM;
e)
IDC_NO; f)
IDC_SIZEALL;
g)
IDC_SIZENESW; h)
IDC_SIZENS;
i)
IDC_SIZENWSE; k)
IDC_SIZEWE;
l)
IDC_UPARROW; m)
IDC_WAIT.
В дальнейшем мы научимся самостоятельно создавать уникальные пиктограммы и курсоры.
Приложение FirstApp будет использовать системный цвет окна. Поэтому:
wcex.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
Этот цвет можно изменить с помощью Control Panel.
Наше первое приложение использует меню. Поэтомузагружаем его из ресурсного файла так:
wcex.lpszMenuName = MAKEINTRESOURCE(IDC_FIRSTAPP);
где IDC_FIRSTAPP – идентификатор ресурса. MAKEINTRESOURCE – макрос, преобразующий целочисленное значение идентификатора ресурса, в имя ресурса. Прототип:
LPTSTR MAKEINTRESOURCE(
[in] WORD wInteger
);
Если меню использовать не предполагается, то можно написать:
wcex.lpszMenuName = NULL;
Определяет целочисленное значение, которое будет преобразовано.
Возвращаемое значение
Возвращаемое значение - указанное значение в младшем слове и нуль в старшем слове.
Инициализируем структуру именем приложения:
wcex.lpszClassName = szWindowClass;
В заключении, регистрируем класс окна, вызвав функцию RegisterClass с параметром wcex.
Функция RegisterClass относится к программному интерфейсу Windows и выполняет регистрацию класса окна. В качестве единственного параметра функции необходимо указать адрес предварительно проинициализированной структуры типа WNDCLASS: