Уроки начинающим работать с С++ в Windows
Урок 1. Первая программа на С++ в среде Windows
— "Hello. World !"
Программирование в Операционной
Системе Windows основано на событиях и сообщениях.
Операционная система Windows общается с программой путем посылки ей сообщений.
Каждый раз при запуске
новой программы, Windows создает новый процесс
и выделяет для этого процесса свою очередь сообщений
Когда в системе происходит какое либо событие: нажатие клавиши клавиатуры,
кнопки мыши, движение мыши и др.
первой получает сообщение об этом операционная система Windows ! Получив сообщение,
ОС посылает сообщение
об этом событии программе или, другими словами, направляет
это событие в очередь сообщений для данной
программы, в окне которой это событие произошло.
Все приложения Windows должны иметь цикл обработки
этих сообщений ( в функции WinMain() )
Этот цикл читает сообщения из очереди сообщений программы и направляет
эти сообщения назад ОС Windows,
которая (ОС) затем вызывает оконную функцию программы, передавая ей это сообщение
в качестве параметра
Именно так функционируют все программы под Windows.
По традиции первой программой на С++ выступает программа, выводящая на экран
окно с текстом "Hello. World"
Любая программа под Windows состоит минимум из двух функций — WinMain()
и оконной функции.
Функция WinMain() должна выполнять следующие операции:
#include
<windows.h>
int PASCAL WinMain ( HANDLE hInstance, HANDLE hPrevInst, LPSTR lpszCmdParam,
int nCmdShow )
Функция WinMain().
Каждая программа для Windows имеет главную функцию — точку входа, с которой
начинается программа, и которая
называется WinMain(). Функция WinMain()
позволяет передавать аргументы командной строки приложениям Windows
через параметр lpszCmdParam
{
static char szAppName[] = "WinHel"; // szAppName — имя класса окна приложения
HWND hwnd; // hwnd — дескриптор окна приложения
MSG msg; // msg-сообщение (имеет тип MSG — см. описание ниже)
WNDCLASS wcn; // wcn-структура для передачи параметров, определяющая
вид главного окна приложения<
Регистрация класса
окнаif(!hPrevInst) // проверяем — если нет ни одного запущенного экземпляра приложения -
// т.е. наш класс окна еще не зарегистрирован — регистрируем класс окна
{
wcn.style = CS_HREDRAW | CS_VREDRAW; // определяем стиль окна приложения
wcn.lpfnWndProc = WndProc; // указатель на функцию WndProc
wcn.cbClsExtra = 0; // целые числа, зарезервированные для
wcn.cbWndExtra = 0; // дополнительной информации о стилях
wcn.hInstance = hInstance; // значение параметра hInstance
wcn.hIcon = LoadIcon(NULL, IDI_APPLICATION); // дескриптор значка приложения
wcn.hCursor = LoadCursor(NULL, IDC_ARROW); // дескриптор указателя мыши
wcn.hbrBackground = GetStockObject(WHITE_BRUSH); // цвет и узор фона главного окна
wcn.lpszMenuName = NULL; // т.к. меню у нас нет, значит NULL
wcn.lpszClassName = szAppName; // имя класса окна, определенное выше
RegisterClass ( &wcn ); // и наконец — регистрируем класс окна
}
wcn.style — в этом
поле определяется стиль окна. Установленные флаги CS_HREDRAW и CS_VREDRAW означают,hwnd = CreateWindow( szAppName, // имя класса окна "My First Window", // заголовок окна-если окно будет без заголовка, то NULL WS_OVERLAPPEDWINDOW, // стиль окна CW_USEDEFAULT, // начальная Х-координата окна (или введите значение) CW_USEDEFAULT, // начальная У-координата окна (или введите значение) CW_USEDEFAULT, // начальный горизонтальный размер(или введите значение) CW_USEDEFAULT, // начальный вертикальный размер (или введите значение) NULL, // дескриптор родительского окна NULL, // дескриптор меню окна — NULL — меню по умолчанию hInstance, // дескриптор экземпляра программы NULL); // параметры созданияЗначениями по умолчанию CW_USEDEFAULT являются для начального положения окна — левый верхний угол экрана,
ShowWindow( hwnd , nCmdShow ); // отобразить окно на экране UpdateWindow( hwnd ); // вывести на экран рабочую область окна.Цикл обработки сообщений
while( GetMessage( &msg, NULL, 0, 0 )) // ф-ция возвращает true пока не выберет WM_QUIT
{
TranslateMessage( &msg ); // ф-ция преобразования сочетания клавиш в другие события
DispatchMessage( &msg ); // распределяет сообщения по функциям окна, именно здесь
} // происходит "вызов" оконной функции
return msg.wParam; // когда цикл обработки сообщений заканчивается, поле
// wParam последнего сообщения возвращается вызывающему
// приложению — рабочему столу системы
} // конец функции WinMain()
&msg — указатель на структуру
сообщения, в которой хранятся данные о полученном сообщении, msg имеет тип MSG.typedef struct tagMSG {
HWND hwnd; // дескриптор окна, которому адресуется ссобщение
UINT message; // тип Windows-сообщения (например WM_RBUTTONDOWN — нажатие правой кнопки мыши)
WPARAM wparam; // параметр сообщения, зависит от типа сообщения, например координаты указателя мыши
LPARAM lparam; // параметр сообщения, зависит от типа сообщения
DWORD time; // время постановки сообщения в очередь
POINT pt; // координаты мыши в момент time, имеет тип struct ( int x, int y; }
} MSG;
Функция WndProc()long FAR PASCAL WndProc ( HWND hwnd, UINT msg, UINT wParam, LONG lParam )
{
HDC hdc; // дескриптор контекста устройства для доступа к рисованию на экран
PAINTSTRUCT ps; // структура для рисования
RECT rect; // структура для указания области рисования
switch( msg )
{
case WM_PAINT: // выводим надпись "Hello, World !", для этого:
hdc = BeginPaint( hwnd, &ps ); // получаем дескриптор(контекст) экрана
GetClientRect( hwnd , &rect ); // получаем координаты рабочей области окна
DrawText( hdc, "Hello, World !", -1, &rect,
DT_SINGLELINE | DT_CENTER | DT_VCENTER ); // выводим надпись
EndPaint( hwnd, &ps); // освобождаем дескриптор
return 0;
case WM_LBUTTONDOWN: // нажатие левой кнопки мыши — выводим "*"
hdc = GetDC( hwnd );
TextOut( hdc, LOWORD(lParam), HIWORD(lParam), "*", 1);
ReleaseDC( hwnd, hdc );
break;
case WM_DESTROY: // завершение приложения
PostQuitMessage(0); // помещает в очередь сообщение WM_QUIT, необходимое для
break; // прекращения цикла обработки в функции WinMain()
default: // если сообщение не обработано в switch, вернуть его Windows
return DefWindowProc ( hwnd, msg, wParam, lParam);
}
return NULL;
} // завершение оконной функции
case WM_PAINT:
Как правило, сообщение WM_PAINT генерируется неявным образом, например всякий
раз, когда окно