Работаем с MS Visual Studio. (2 стр)
Автор: Сергей Шайкин
Создание заготовки Win32 Application.
Часто в примерах будет использоваться один и тот же костяк приложения. Рассмотрим пример создания Win32 Application. Возможно, по причине захвата большей аудитории, очень подробно. Это приложение не будет использовать MFC.
Аналогично предыдущему пункту. Выбираем меню File / New. В появившемся диалоговом окне New выбирается закладка Projects. В списке типов проекта выделяем Win32 Application. В окне ProjectName - пишем имя нового проекта, Location - устанавливаем его местоположение на диске. Нажимаем кнопку OK. В следующем появившемся окне «Win32 Application Step1 of 1» устанавливаем An Empty Project (пустой проект). Нажимаем кнопку Finish — создаём пустой проект.
Теперь нам нужно создать файл, в который поместим часть кода приложения. Меню File / New. В появившемся окне New, должна быть выбрана закладка Files. В списке типов файлов выбираем C++ Source File, далее, в окне FileName пишем название нашего файла, например, «main». И нажимаем либо кнопку OK, либо Enter на клавиатуре.
Теперь у вас есть пустой файл main.cpp.
Этот файл будет отвечать за работу приложения в среде Windows. По этой причине он будет содержать
#include <windows.h>
и функцию WinMain().
Функция WinMain() — это точка входа вашей программы. То есть с выполнения этой функции начинается выполнение вашей программы. Функция WinMain() вызывается автоматически системой. Завершение выполнения функции WinMain(), означает завершение работы приложения. Пример самой простой программы под Windows:
#include <windows.h> int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { return 0; }
Как видно, функция WinMain имеет четыре параметра:
HINSTANCE hInstance - текущий уникальный дескриптор приложения.
HINSTANCE hPrevInstance - дескриптор предыдущей копии приложения. В Win32 всегда равен 0.
LPSTR lpCmdLine - указатель на командную строку.
int nCmdShow - флаг, указывающий, как должно быть открыто главное окно приложения.
Для большинства примеров мы будем использовать главное окно приложения. То есть выводить графику именно в нём.
Как известно, в Windows работа приложений происходит при помощи сообщений. Сообщения появляются при каких-то действиях пользователя или внутренней работы системы. Приложение должно обеспечить корректную работу с сообщениями и их обработку. Для этого есть стандартные методы построения программного кода.
Поскольку наше приложение будет работать с окном, вы должны предоставить обработчик сообщений для этого окна, создать окно и вывести его на экране.
Обработчик сообщений окна представляет собой обычную функцию определённого вида. Эту функцию необходимо реализовать и, во время создания окна, связать её с окном.
После, система будет вызывать эту функцию, когда будет приходить сообщение, предназначенное вашему окну. Само сообщение передаётся одним из параметров.
Сообщение представляет собой число типа UINT (unsigned int). Числами в чистом виде не пользуются, а используют макроподстановки, которые описаны в стандартных заголовочных файлах, подключаемых из windows.h. Названия сообщений в макроподстановках начинается на "WM_", например, WM_PAINT, WM_CLOSE и тд.
С сообщением также может приходить дополнительная информация в других параметрах функции-обработчика. Один обработчик может обрабатывать сообщения для нескольких окон.
Итак, обработчик должен быть следующего вида.
LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
Ясно, что название функции может быть любым.
HWND hWnd — идентификатор окна - уникальное число, имеющееся у каждого окна.
UINT msg — сообщение.
WPARAM wParam, LPARAM lParam - дополнительные параметры.
Поскольку типов сообщений большое количество, для их обработки используют оператор switch.
Вообще, нужно обрабатывать все сообщения, приходящие в обработчик окна. Но так как сообщений приходит огромное количество, вся оставшаяся работа по обработке сообщений отдаётся системе, а именно, вызывается стандартный обработчик DefWindowProc().
Создание окна происходит в два этапа, сначала регистрируется Класс Окна, а после создаётся само окно.
Класс окна представляет собой объект типа WNDCLASS. WNDCLASS — это структура, рассмотрим несколько важных полей, которые нужно заполнить.
LpfnWndProc — этому полю нужно присвоить указатель на функцию обработчик вашего создаваемого окна.
hInstance — уникальный идентификатор приложения, автоматически передается системой в качестве параметра функции WinMain().
hCursor — идентификатор курсора. Вы можете создать свой курсор в редакторе ресурсов или же воспользоваться стандартным курсором. Курсор загружается функцией LoadCursor().
hbrBackground — устанавливаете заполнение фона окна.
lpszClassName — строковое имя класса онкна.
Заполнив поля класса окна, зарегистрируйте этот объект методом RegisterClass().
Окно создаётся функцией CreateWindow() или CreateWindowEx().
Пример:
HWND hWnd = CreateWindow(lpszClassName, pWindowName, dwStyle, nLeft, nTop, nWidth, nHeight, 0, 0, hInstance, NULL);
здесь:
lpszClassName — строка, содержащаю имя класса.
pWindowName — заголовок окна.
dwStyle — стиль окна.
nLeft, nTop — координаты левого верхнего угла окна.
nWidth, nHeight — размеры окна.
hInstance — уникальный идентификатор приложения.
Функция CreateWindow() возвращает либо идентификатор созданного окна, либо 0 (NULL), если окно по каким-либо причинам не удалось создать.
Далее окно нужно сделать видимым на экране.
ShowWindow(hWnd, nCmdShow); UpdateWindow( hWnd);
В завершении, после того как сделаны все приготовления по работе приложения, необходимо запустить цикл обработки и управления сообщениями. Сообщения можно получить функцией GetMessage(). Затем его необходимо отправить системе, для дальнейшей обработки:
TranslateMessage() и DispatchMessage().
Функция GetMessage() при вызове находится в состоянии ожидания нового сообщения. Но в трёхмерных играх почти всегда нужно постоянно обновлять изображение. Обновление производится в свободное время, когда не приходит никаких сообщений. Чтобы узнать есть ли в очереди новое сообщение или нет, используют функцию PeekMessage(). Если эта функция возвращает не нулевое значение (TRUE), то в очереди есть новое сообщение, тогда получаем его и обрабатываем. В противном случае, можно делать наше обновление изображения.
После закрытия окна приложения, оно разрушается, при этом приходит сообщение WM_DESTROY. В главном окне приложения нужно отследить это сообщение и вызвать функцию PostQuitMessage(0), говорящее, что приложение завершает свою работу. При этом в очередь сообщений помещается сообщение WM_QUIT, а функция GetMessage() получив его, возвращает нулевое значение (FALSE). Одной из этих реакций можно воспользоваться, чтобы остановить цикл обработки сообщений и завершить выполнение функции WinMain().
19 ноября 2001 (Обновление: 5 мар 2006)