Уроки начинающим работать с С++ в 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; // структура для рисованияcase WM_PAINT: Как правило, сообщение WM_PAINT генерируется неявным образом, например всякий раз, когда окно
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; } // завершение оконной функции