link7526 link7527 link7528 link7529 link7530 link7531 link7532 link7533 link7534 link7535 link7536 link7537 link7538 link7539 link7540 link7541 link7542 link7543 link7544 link7545 link7546 link7547 link7548 link7549 link7550 link7551 link7552 link7553 link7554 link7555 link7556 link7557 link7558 link7559 link7560 link7561 link7562 link7563 link7564 link7565 link7566 link7567 link7568 link7569 link7570 link7571 link7572 link7573 link7574 link7575 link7576 link7577 link7578 link7579 link7580 link7581 link7582 link7583 link7584 link7585 link7586 link7587 link7588 link7589 link7590 link7591 link7592 link7593 link7594 link7595 link7596 link7597 link7598 link7599 link7600 link7601 link7602 link7603 link7604 link7605 link7606 link7607 link7608 link7609 link7610 link7611 link7612 link7613 link7614 link7615 link7616 link7617 link7618 link7619 link7620 link7621 link7622 link7623 link7624 link7625 link7626 link7627 link7628 link7629 link7630 link7631 link7632 link7633 link7634 link7635 link7636 link7637 link7638 link7639 link7640 link7641 link7642 link7643 link7644 link7645 link7646 link7647 link7648 link7649 link7650 link7651 link7652 link7653 link7654 link7655 link7656 link7657 link7658 link7659 link7660 link7661 link7662 link7663 link7664 link7665 link7666 link7667

Уроки начинающим работать с С++ в Windows

Урок 1. Первая программа на С++ в среде Windows  — "Hello. World !"

Программирование в Операционной Системе Windows основано на событиях и сообщениях.
Операционная система Windows общается с программой путем посылки ей сообщений. Каждый раз при запуске
новой программы, Windows создает новый процесс и выделяет для этого процесса свою очередь сообщений
Когда в системе происходит какое либо событие: нажатие клавиши клавиатуры, кнопки мыши, движение мыши и др.
первой получает сообщение об этом операционная система Windows ! Получив сообщение, ОС посылает сообщение
об этом событии программе или, другими словами, направляет это событие в очередь сообщений для данной
программы, в окне которой это событие произошло.
Все приложения Windows должны иметь цикл обработки этих сообщений ( в функции WinMain() )
Этот цикл читает сообщения из очереди сообщений программы и направляет эти сообщения назад ОС Windows,
которая (ОС) затем вызывает оконную функцию программы, передавая ей это сообщение в качестве параметра
Именно так функционируют все программы под Windows.

По традиции первой программой на С++ выступает программа, выводящая на экран окно с текстом "Hello. World"



Любая программа под Windows состоит минимум из двух функций — WinMain() и оконной функции.
Функция WinMain() должна выполнять следующие операции:

  1. Определять класс окна
  2. Регистрировать класс окна
  3. Создавать окно данного класса
  4. Отображать окно
  5. Запускать цикл обработки сообщений
Оконная функция предназначена для обработки сообщений, относящихся к данному окну

Данный пример в ОС Windows состоит примерно из нескольких десятков строк кода на С++
Итак, начинаем...

#include <windows.h>

int PASCAL WinMain ( HANDLE hInstance, HANDLE hPrevInst, LPSTR lpszCmdParam, int nCmdShow )


Функция WinMain().

Каждая программа для Windows имеет главную функцию — точку входа, с которой начинается программа, и которая
называется WinMain(). Функция WinMain() позволяет передавать аргументы командной строки приложениям Windows
через параметр lpszCmdParam

Функция WinMain() имеет четыре аргумента

hInstance — уникальный идентификатор текущего экземпляра приложения
hPrevInstance — идентификатор последненго из запущенных экземпляров приложения, если запущено несколько экземпляров
приложения, если же запущен один экземпляр приложения, то hPrevInstance равен NULL
lpszCmdParam — указатель на строку, которая заканчивается нулевым байтом и содержит все параметры командной строки,
передаваемые данному экземпляру программы.
nCmdShow — целое число, показывающее как отображать запущенную программу — в виде открытого окна или в виде кнопки
на панели задач

Определяем локальные переменные
{
static char szAppName[] = "WinHel"; // szAppName — имя класса окна приложения
HWND hwnd; // hwnd — дескриптор окна приложения
MSG msg; // msg-сообщение (имеет тип MSG — см. описание ниже)
WNDCLASS wcn; // wcn-структура для передачи параметров, определяющая
вид главного окна приложения<
Регистрация класса окна

Здесь возможны два варианта, в зависимости от значания аргумента hPrevInstance.
Первый — в настоящий момент активен хотя бы один экземпляр программы, и тогда регистрировать класс окна не нужно.
Второй — нет ни одного запущенного экземпляра программы, что чаще всего и бывает, т.е. hPrevInstance == NULL, и значит
мы должны зарегистрировать класс окна , в котором хотим вывести надпись "Hello, World".
Заполняем структуру 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 означают,
что всякий раз при изменении ширины или высоты окна будет производиться полная перерисовка рабочей области
окна
wcn.lpfnWndProc — указатель на экспортируемую функцию, обрабатывающую все сообщения. которые Windows посылает
приложению.
wcn.cbClsExtra и wcn.cbWndExtra — целые числа, зарезервированные для указания дополнительной информации о стилях
класса или окна.
wcn.hInstance — значение параметра hInstance, определенного Windows при инициализации первого экземпляра программы,
неизменное для всех последующих экземпляров приложения
wcn.Icon — дескриптор значка приложения (у нас например IDI_APPLICATION - белый квадрат в черной рамке)
wcn.hCursor — дескриптор указателя мыши (у нас например IDC_ARROW — вид стрелки, направленной вверх и влево)
wcn.hbrBackground — дескриптор кисти, определяет цвет и узор фона главного окна (белый фон окна — WHITE_BRUSH)
wcn.lpszMenuName — указатель на строку, содержащую имя меню (у нас нет меню, поэтому NULL)
wcn.lpszClassName — указатель на строку с именем класса окна (как у нас будет назван наш класс окна)
И наконец, вызов API-функции Windows RegisterClass(), предназначенной для регистрации класса окна в Windows

Создание окна приложения

Создается окно приложения функцией CreateWindow()
Функция CreateWindow() возвращает дескриптор созданного окна hwnd, который в дальнейшем может использоваться в
качестве аргумента при вызове других функций, работающих с нашим окном.
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(),
которой в качестве параметра передается дескриптор окна, возвращенный функцией CreateWindow() и аргумент
nCmdShow переданный функции WinMain() (см. выше)
ShowWindow( hwnd , nCmdShow ); // отобразить окно на экране
UpdateWindow( hwnd ); // вывести на экран рабочую область окна.
Цикл обработки сообщений

Как уже было сказано ранее, для каждого приложения Windows создает отдельную очередь сообщений.
Каждый раз, когда происходит событие, Windows преобразует это событие в сообщение и помещает это
сообщение в очередь сообщений приложению. Сообщение находится в очереди до тех пор, пока не будет обработано.
Для обработки этих сообщений и нужен цикл обработки сообщений.
Сообщение выбирается из очереди сообщений, принадлежащих данному приложению с помощью функции GetMessage()
 while( GetMessage( &msg, NULL, 0, 0 )) // ф-ция возвращает true пока не выберет WM_QUIT
{
TranslateMessage( &msg ); // ф-ция преобразования сочетания клавиш в другие события
DispatchMessage( &msg ); // распределяет сообщения по функциям окна, именно здесь
} // происходит "вызов" оконной функции
return msg.wParam; // когда цикл обработки сообщений заканчивается, поле
// wParam последнего сообщения возвращается вызывающему
// приложению — рабочему столу системы
} // конец функции WinMain()
&msg — указатель на структуру сообщения, в которой хранятся данные о полученном сообщении, 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()

С этой функции и начинается работа нашего приложения. Функция WndProc (ей можно присвоить другое имя)
получает сообщения из операционной системы и определяет реакцию приложения на эти сообщения
Итак, окно создано и выведено, теперь начинается работа приложения.
Мы хотим Давайте сделаем это в нашей оконной функции 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 генерируется неявным образом, например всякий раз, когда окно
приложения создается, перемещается, меняет размер, или например наше окно было закрыто частично или
полностью окном другого приложения (например, программой "Проводник") и требуется перерисовать
рабочую область окна.

case WM_DESTROY: сообщение возникает при попытке закрыть окно приложения, может появляться
и в других случаях
DefWindowProc() — обработчик необработанных или нераспознанных сообщений
В нашей программе мы обрабатываем сообщения WM_PAINT, WM_DESTROY и WM_LBUTTONDOWN
а все другие сообщения передаем обратно в Windows для обработки по умолчанию

case WM_LBUTTONDOWN: сообщение возникает при нажатии левой кнопки мыши
(работа с мышью будет описана в последующих уроках, здесь лишь как пример)
LOWORD(lParam) — координата X мыши
HIWORD(lParam) — координата Y мыши


Краткие итоги:

Итак, ма завершили создание первой программы на С++ в среде Windows "Hello. World !"
Текст и проект для C++Builder 6 получившейся программы можно скачать здесь. ( 7Кб )
Запустите программу, посмотрите как она работает, поэкспериментируйте

В следующих уроках мы поговорим о типах данных в Windows, работе с полосами прокрутки, выводе текста.