Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

лекции / Shchupak_Yu._Win32_API_Razrabotka_prilozheniy_dlya_Windows

.pdf
Скачиваний:
0
Добавлен:
11.02.2026
Размер:
13.15 Mб
Скачать

Программа «Hello, World!» — первый вариант

31

 

 

{

case WM_PAINT:

hDC = BeginPaint(hWnd, &ps);

GetClientRect(hWnd, &rect);

DrawText(hDC, "Hello, World!", -1, &rect,

DT_SINGLELINE | DT_CENTER | DT_VCENTER );

EndPaint(hWnd, &ps); break;

case WM_CLOSE: DestroyWindow(hWnd); break;

case WM_DESTROY: PostQuitMessage(0); break;

default:

return DefWindowProc(hWnd, uMsg, wParam, lParam);

}

return 0;

}

//////////////////////////////////////////////////////////////////////

Создайте проект с именем Hello1, добавьте к нему указанный файл. После ком пиляции и запуска на выполнение на экране должно появиться окно программы, показанное на рис. 1.4.

Рис. 1.4. Окно программы Hello1

А вот теперь придется запастись терпением. Пояснения к программе Hello1 зай мут примерно в восемь раз больше страниц, чем сам код программы.

Файл исходного текста программы

В файле Hello1.cpp расположены только две функции: WinMain и WndProc. WinMain — это точка входа в программу. WndProc — это оконная процедура для главного окна

32 Глава 1. «Hello, World!», или Первые шаги к пониманию концепции Windows

программы. Оконная процедура инкапсулирует код, отвечающий за ввод инфор мации, обычно осуществляемый при помощи клавиатуры или мыши, а также за вывод информации на экран.

В Hello1.cpp отсутствуют инструкции для непосредственного вызова WndProc — оконная процедура вызывается только из Windows. Однако в WinMain имеется ссылка на WndProc (адрес оконной процедуры присваивается полю wc.lpfnWndProc), поэтому прототип функции WndProc объявлен в самом начале файла, еще до опре деления функции WinMain.

Обратите внимание на идентификаторы, написанные полностью прописны ми буквами. Эти идентификаторы задаются в заголовочных файлах Windows. Некоторые из них содержат двух или трехбуквенный префикс, завершаемый символом подчеркивания, например CS_HREDRAW, IDI_APPLICATION, IDC_ARROW,

WS_OVERLAPPEDWINDOW, CW_USEDEFAULT. Это просто числовые константы. Префикс обозначает основную категорию, к которой принадлежит константа. Некоторые из этих категорий приведены в табл. 1.3.

Таблица 1.3. Префиксы для числовых констант

Префикс

Категория

 

 

CS_

Опция стиля класса

CW_

Опция создания окна

DT_

Опция рисования текста

IDC_

Идентификатор предопределенного курсора

IDI_

Идентификатор предопределенной иконки (пиктограммы)

WM_

Сообщение окна

WS_

Стиль окна

 

 

Также следует обратить внимание на новые типы данных, специфичные для системы Windows. Некоторые их них были описаны в табл. 1.1.

Регистрация класса окна

Сразу после входа в функцию WinMain создается и регистрируется класс главного окна приложения. Для этого необходимо заполнить структуру типа WNDCLASSEX, а затем передать адрес этой структуры в виде аргумента функции RegisterClassEx.

Структура WNDCLASSEX имеет двенадцать полей:

typedef struct tagWNDCLASSEX {

UINT cbSize;

// размер данной структуры в байтах

UINT style;

// стиль класса окна

WNDPROC lpfnWndProc;

// указатель на функцию окна (оконную процедуру)

int cbClsExtra;

// число дополнительных байтов, которые должны

 

//быть распределены в конце структуры класса

int cbWndExtra;

// число дополнительных байтов, которые должны

 

//быть распределены вслед за экземпляром окна

HINSTANCE hInstance;

// дескриптор экземпляра приложения, в котором

 

//находится оконная процедура для этого класса

HICON hIcon;

// дескриптор пиктограммы

HCURSOR hCursor;

// дескриптор курсора

HBRUSH hbrBackground;

// дескриптор кисти, используемой для закраски

 

//ôîíà îêíà

Программа «Hello, World!» — первый вариант

33

 

 

LPCTSTR lpszMenuName; // указатель на строку, содержащую имя меню, //применяемого по умолчанию для этого класса

LPCTSTR lpszClassName; // указатель на строку, содержащую имя класса окна HICON hIconSm; // дескриптор малой пиктограммы

} WNDCLASSEX;

ПРИМЕЧАНИЕ

Следует упомянуть о некоторых аспектах использованных в этом определении типов данных, а также о венгерской нотации имен полей.

Префиксы LP и lp означают «длинный указатель» (long pointer), являющийся пережитком 16-разряд- ной Windows, в которой различались короткие 16-разрядные указатели и длинные 32-разрядные указатели. В Win 32 API все указатели имеют длину 32 разряда.

Префикс lpfn означает «длинный указатель на функцию» (long pointer to a function). Префикс cb означает «счетчик байтов» (counter of bytes). А префикс hbr — это «дескриптор кисти» (handle to a brush).

Рассмотрим назначение полей структуры WNDCLASSEX.

Значение первого поля, cbSize, должно быть равно длине структуры.

Второе поле, style, может содержать в своем значении один или несколько сти лей, перечисленных в табл. 1.41.

Таблица 1.4. Стили класса окна

Стиль

Описание

 

 

CS_GLOBALCLASS

Создать класс, доступный всем приложениям. Обычно этот стиль при-

 

меняется для создания определяемых пользователем элементов

 

управления в DLL

CS_HREDRAW

Перерисовывать все окно, если изменен размер по горизонтали

CS_NOCLOSE

Запретить команду Close в системном меню

CS_OWNDC

Выделить уникальный контекст устройства для каждого окна, созданного

 

при помощи этого класса

CS_VREDRAW

Перерисовывать все окно, если изменен размер по вертикали

 

 

Взаголовочных файлах Windows идентификаторы, начинающиеся с префик са CS_, задаются в виде 32 разрядной константы, в которой только один разряд установлен в единичное значение. Например, константа CS_VREDRAW задана как 0x0001, а CS_HREDRAW — как 0x0002. Подобные константы иногда называют пораз рядными флагами (bit flags). Они могут объединяться с помощью операции ИЛИ языка C++.

Врассматриваемой программе используется комбинация стилей CS_HREDRAW | CS_VREDRAW. Это означает, что все окна этого класса должны це ликом перерисовываться при изменении как горизонтального, так и вертикаль ного размеров окна. Если попробовать изменить размеры окна A Hello1 Application, то можно увидеть, что строка текста переместится в новый центр окна. Механизм уведомления оконной процедуры об изменении размеров окна будет рассмотрен позже.

Третье поле, lpfnWndProc, содержит адрес оконной процедуры (в нашей про грамме это — WndProc).

1 В таблице указаны наиболее употребительные стили. Полный список стилей см. в MSDN.

34 Глава 1. «Hello, World!», или Первые шаги к пониманию концепции Windows

Назначение полей 4—6 представляется очевидным1.

Седьмое поле, hIcon, содержит дескриптор пиктограммы, которая предназначе на для этого класса окна. Пиктограмма (синонимы: иконка, значок) — это малень кая битовая картинка, которая появляется на панели задач Windows и в левой ча сти заголовка окна. Значение hIcon обычно получают вызовом функции LoadIcon, которая имеет следующий прототип:

HICON LoadIcon(HINSTANCE hInstance, LPCTSTR lpIconName);

Эта функция загружает ресурс пиктограммы, заданный параметром lpIconName, из экземпляра приложения, указанного параметром hInstance2. Функцию можно использовать также для загрузки одной из системных (предопределенных) пик тограмм, если передать первому аргументу значение NULL. В этом случае второй аргумент должен содержать константу, идентификатор которой начинается с пре фикса IDI_ («идентификатор значка» — ID for icon). Возможные значения второ го аргумента для предопределенных пиктограмм приведены в табл. 1.5.

Таблица 1.5. Предопределенные идентификаторы пиктограмм

Значение

Описание

 

 

IDI_APPLICATION

Пиктограмма приложения по умолчанию

IDI_ASTERISK

Òî æå, ÷òî è IDI_INFORMATION

IDI_ERROR

Пиктограмма в виде белого креста на фоне красного круга. Она исполь-

 

зуется в серьезных предупреждающих сообщениях

IDI_EXCLAMATION

Òî æå, ÷òî è IDI_WARNING

IDI_HAND

Òî æå, ÷òî è IDI_ERROR

IDI_INFORMATION

Пиктограмма «i», которая используется в информационных сообщениях

IDI_QUESTION

Пиктограмма «?»

IDI_WARNING

Пиктограмма «!», которая используется в предупреждающих сообщениях

IDI_WINLOGO

Логотип Windows

 

 

Поле hCursor содержит дескриптор курсора мыши, используемого приложени ем в клиентской области окна. Значение hCursor обычно получают с помощью вы зова функции LoadCursor, имеющей следующий прототип:

HCURSOR LoadCursor(HINSTANCE hInstance, LPCTSTR lpCursorName);

Эта функция загружает ресурс курсора, заданный вторым параметром (lpCursorName), из экземпляра приложения, заданного первым параметром (hInstance)3.

Функцию можно также использовать для загрузки одного из системных (пре допределенных) курсоров, если передать первому аргументу значение NULL. Зна чение второго аргумента при этом выбирается из табл. 1.6.

Таблица 1.6. Предопределенные идентификаторы курсора

Значение

Описание

 

 

IDC_APPSTARTING

Стандартная стрелка и малые песочные часы

IDC_ARROW

Стандартная стрелка

 

 

1 Поля cbClsExtra и cbWndExtra используются крайне редко.

2 Вопросы создания и использования пользовательских пиктограмм рассматриваются в главе 5.

3 Вопросы создания и использования пользовательских курсоров рассматриваются в главе 5.

Программа «Hello, World!» — первый вариант

35

 

 

 

 

 

 

Значение

Описание

 

 

 

 

IDC_CROSS

Перекрестье

 

IDC_HELP

Стрелка и вопросительный знак

 

IDC_IBEAM

Текстовый двутавр

 

IDC_NO

Перечеркнутый кружок

 

IDC_SIZEALL

Четырехконечная стрелка

 

IDC_SIZENESW

Двухконечная стрелка, указывающая на северо-восток и юго-запад

 

IDC_SIZENS

Двухконечная стрелка, указывающая на север и юг

 

IDC_SIZENWSE

Двухконечная стрелка, указывающая на северо-запад и юго-восток

 

IDC_SIZEWE

Двухконечная стрелка, указывающая на запад и восток

 

IDC_UPARROW

Вертикальная стрелка

 

IDC_WAIT

Песочные часы

 

 

 

 

Девятое поле, hbrBackground, содержит дескриптор кисти, используемой при ложением для закраски фона в клиентской области окна. Кисть (brush) — это гра фический объект, который представляет собой шаблон пикселов различных цве тов, используемый для закрашивания области. В Windows имеется несколько стандартных или предопределенных кистей. Вызов функции GetStockObject с ар гументом WHITE_BRUSH возвращает дескриптор белой кисти. Так как возвращае мое значение имеет тип HGDIOBJ, то необходимо его преобразование к типу HBRUSH.

Десятое поле, lpszMenuName, указывает на строку, содержащую имя меню, при меняемого по умолчанию для данного класса. Рассматриваемая программа не имеет меню, поэтому поле установлено в NULL.

Поле lpszClassName указывает на строку, содержащую имя класса. Это имя долж но использоваться в параметре lpClassName функции CreateWindow.

Двенадцатое поле, hIconSm, содержит дескриптор малой пиктограммы, кото рая предназначена для использования в строке заголовка окон, созданных при помощи этого класса. Размеры пиктограммы должны быть 16 × 16 пикселов. Если поле равно NULL, то система ищет ресурс пиктограммы, указанный полем hIcon, чтобы сформировать малую пиктограмму из него.

Итак, с заполнением структуры класса окна мы разобрались. Осталось заре гистрировать подготовленный класс, вызвав функцию RegisterClassEx. Это расши ренная версия1 функции RegisterClass из предыдущих версий Windows. В то же время можно пользоваться и функцией RegisterClass, передавая ей адрес структу ры WNDCLASS (а не WNDCLASSEX).

Создание окна

Если регистрация класса окна прошла успешно, то следующий этап — создание окна. Для этого вызывается функция CreateWindow, прототип которой приведен ниже:

HWND CreateWindow(

 

LPCTSTR lpClassName,

// имя зарегистрированного класса

LPCTSTR lpWindowName, // èìÿ îêíà

DWORD dwStyle,

// стиль окна

int x,

// горизонтальная позиция

1 На это указывает окончание имени Ex, то есть extended — расширенный.

36 Глава 1. «Hello, World!», или Первые шаги к пониманию концепции Windows

int y,

// вертикальная позиция

int nWidth,

// ширина окна

int nHeight,

// высота окна

HWND hWndParent,

// дескриптор родительского окна

HMENU hMenu,

// дескриптор меню окна или идентификатор элемента

 

//управления

HINSTANCE hInstance,

// дескриптор экземпляра приложения

LPVOID lParam

// указатель на данные, передаваемые в сообщении

 

//WM_CREATE

);

Рассматривая назначение параметров, не будем забывать, что функция Create Window позволяет создавать не только основное окно приложения, но и любые другие окна, включая окна предопределенных классов, с помощью которых реа лизуются стандартные элементы управления Windows.

Первый параметр, lpClassName, — это указатель на строку, содержащую допус тимое имя класса окна. Таким именем может быть либо имя класса, зарегистриро ванного ранее при помощи функции RegisterClassEx или RegisterClass, либо имя од ного из предопределенных классов, перечисленных в табл. 1.7.

Таблица 1.7. Предопределенные классы окон

Класс

Описание

Префикс

 

 

в обозначении

 

 

стилей

 

 

 

BUTTON

Прямоугольное окно кнопки, группы, флажка, переклю-

BS_

 

чателя или пиктограммы

 

COMBOBOX

Элемент управления, объединяющий элементы LISTBOX

CBS_

 

и EDIT. В поле редактирования отображается выбранная

 

 

строка из LISTBOX

 

EDIT

Прямоугольное окно (поле редактирования), предназна-

ES_

 

ченное для ввода текста с клавиатуры

 

LISTBOX

Прямоугольное окно со списком строк, из которого поль-

LBS_

 

зователь может выбрать любую строку

 

MDICLIENT

Клиентское окно многодокументного интерфейса. Это

 

 

окно получает сообщения, которые управляют дочерни-

 

 

ми окнами в MDI-приложении

 

RICHEDIT

Элемент управления Rich Edit версии 1.0. В дополнение

ES_

 

к возможностям элемента EDIT позволяет редактировать

 

 

текст с разными шрифтами и стилями

 

RICHEDIT_CLASS

Элемент управления Rich Edit версии 2.0 или 3.01.

ES_

 

Усовершенствованная версия элемента RICHEDIT с до-

 

 

полнительными возможностями

 

SCROLLBAR

Элемент управления линейкой прокрутки

SBS_

STATIC

Элемент управления статическим текстом. Применяется

SS_

 

для размещения в окне текста или рамок

 

 

 

 

Второй параметр, lpWindowName, — это указатель на строку, содержащую имя окна. Место отображения имени зависит от вида окна. Например, для главного окна приложения оно выводится как заголовок окна (см. рис. 1.3), а для окна пре допределенного класса BUTTON размещается по центру кнопки.

1 В зависимости от версии Windows, установленной на компьютере.

Программа «Hello, World!» — первый вариант

37

 

 

Третий параметр, dwStyle, позволяет указывать стиль окна, состоящий из зна чений, указанных в табл. 1.8. Эти константы могут объединяться в значении пара метра с помощью побитовой операции ÈËÈ. Для окон предопределенных классов дополнительно могут быть добавлены стили, характерные для данного элемента управления. Идентификаторы таких стилей начинаются с префикса, указанного в табл. 1.71.

Таблица 1.8. Стили окна

Обозначение стиля

Описание

 

 

WS_BORDER

Создать окно с рамкой в виде тонкой линии

WS_CAPTION

Создать окно, которое имеет область заголовка (включает стиль

 

WS_BORDER)

WS_CHILD

Создать дочернее окно. Окно этого стиля не может иметь полосу

 

меню и не может иметь стиль WS_POPUP

WS_CLIPCHILDREN

Исключить перерисовку дочерних окон, принадлежащих данному

 

родительскому окну

WS_CLIPSIBLINGS

Исключить перерисовку соседних дочерних окон при перерисовке

 

данного дочернего окна

WS_DLGFRAME

Создать окно, имеющее рамку со стилем, типичным для диалого-

 

вых окон. Окно этого стиля не может иметь область заголовка

WS_GROUP

Считать данное окно первым в группе элементов управления

 

(обычно группируются переключатели)

WS_HSCROLL

Создать окно с горизонтальной линейкой прокрутки

WS_MAXIMIZE

Создать окно, которое первоначально является развернутым

WS_MAXIMIZEBOX

Создать окно с кнопкой развертывания

WS_MINIMIZE

Создать окно, которое первоначально является свернутым

WS_MINIMIZEBOX

Создать окно с кнопкой свертывания

WS_OVERLAPPED

Создать перекрывающееся окно. Окно этого стиля имеет область

 

заголовка и рамку

WS_OVERLAPPEDWINDOW

Сочетание стилей WS_OVERLAPPED, WS_CAPTION, WS_SYSMENU,

 

WS_THICKFRAME, WS_MINIMIZEBOX è WS_MAXIMIZEBOX

WS_POPUP

Создать всплывающее окно. Этот стиль не может использоваться

 

совместно со стилем WS_CHILD

WS_POPUPWINDOW

Сочетание стилей WS_BORDER, WS_POPUP и WS_SYSMENU. Чтобы

 

сделать системное меню видимым, необходимо добавить стиль

 

WS_CAPTION

WS_SYSMENU

Создать окно с системным меню в области заголовка

WS_TABSTOP

Стиль указывает, что на окне может остановиться фокус ввода,

 

перемещаемый при помощи клавиши TAB

WS_THICKFRAME

Создать окно с рамкой, которая позволяет изменять его размеры

WS_VISIBLE

Создать окно, которое сразу же является видимым

WS_VSCROLL

Создать окно с вертикальной линейкой прокрутки

 

 

В рассматриваемой программе используется стандартный стиль для главного окна приложения — WS_OVERLAPPEDWINDOW. Это обычное перекрывающееся окно с заголовком, системным меню, расположенным в левой части строки заголовка,

1Стили для элементов управления здесь не приводятся. При необходимости эту информацию можно найти в MSDN.

38 Глава 1. «Hello, World!», или Первые шаги к пониманию концепции Windows

кнопками для сворачивания, разворачивания и закрытия окна справа на строке заголовка и «толстой» рамкой, позволяющей изменять размеры окна.

Четвертый параметр, x, задает горизонтальную позицию левого верхнего угла окна. Для главного окна позиции x и y определяются в экранных координатах, а для дочерних окон и элементов управления координаты отсчитываются относи тельно левого верхнего угла родительского окна.

Если позиция x не важна, то можно установить значение CW_USEDEFAULT. В этом случае Windows использует значения x и y по умолчанию. Это означает, что сис тема располагает следующие друг за другом перекрывающиеся окна, равномерно отступая по горизонтали и вертикали от левого верхнего угла экрана.

Пятый параметр, y, задает вертикальную позицию левого верхнего угла окна. Если параметр x имеет значение CW_USEDEFAULT, то значение параметра y игнорируется.

Шестой параметр, nWidth, задает ширину окна в пикселах. Если ему присвоено значение CW_USEDEFAULT, то система будет использовать значения nWidth и nHight по умолчанию.

Седьмой параметр, nHight, задает высоту окна в пикселах. Если параметр nWidth установлен в CW_USEDEFAULT, то значение nHight игнорируется.

Восьмой параметр, hWndParent, в рассматриваемой программе имеет значение NULL, поскольку у главного окна программы отсутствует родительское окно. За метим, что, если между двумя окнами существует связь типа родительское—до чернее, дочернее окно всегда появляется только на поверхности родительского.

Девятый параметр, hMenu, содержит дескриптор меню окна или идентификатор элемента управления. Интерпретация значения параметра зависит от вида окна.

Если приложение использует меню, определенное в классе окна (поле lpszMenuNameв структуре WNDCLASSEX), то параметру hMenuнеобходимо передать значение NULL.

Если создаваемое окно относится к элементу управления, то параметру hMenu передается целочисленное значение, которое далее используется как идентифи катор созданного элемента. Этот идентификатор, например, будет содержаться в сообщениях WM_COMMAND, поступающих от элемента управления.

Десятому параметру, hInstance, должен быть присвоен дескриптор экземпляра приложения, переданный программе в качестве аргумента функции WinMain.

Последний параметр, lParam, в рассматриваемом примере тоже имеет значение NULL. При необходимости он может быть использован в качестве указателя на не кие дополнительные данные, передаваемые окну в момент его создания с помо щью сообщения WM_CREATE.

Итак, функция CreateWindow вызвана. Отработав, она возвращает дескриптор созданного окна. Если по какой то причине создать окно не удалось, то функция возвращает значение NULL. Поэтому рекомендуется проверять возвращаемое функ цией значение и в случае неудачи выдавать соответствующее сообщение, исполь зуя уже знакомую функцию MessageBox.

Использование функции CreateWindowEx

Для создания окна вместо функции CreateWindow может быть вызвана функция CreateWindowEx, прототип которой приведен ниже:

HWND CreateWindowEx(DWORD dwExStyle, LPCTSTR lpClassName,

LPCTSTR lpWindowName, DWORD dwStyle, int x, int y, int nWidth,

Программа «Hello, World!» — первый вариант

39

 

 

int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lParam);

Все параметры этой функции, кроме первого, имеют тот же смысл, что и у функ ции CreateWindow. Первый параметр, dwExStyle, задает расширенный стиль окна, применяемый совместно со стилем, определенным в параметре dwStyle. Напри мер, в качестве расширенного стиля можно задать один или несколько флагов, приведенных в табл. 1.9. Полный список расширенных стилей можно найти в MSDN.

Таблица 1.9. Расширенные стили окна

Стиль

Описание

 

 

WS_EX_ACCEPTFILES

Создать окно, которое принимает перетаскиваемые файлы

WS_EX_CLIENTEDGE

Рамка окна имеет утопленный край

WS_EX_CONTROLPARENT

Разрешить пользователю перемещаться по дочерним окнам

 

с помощью клавиши Tab

WS_EX_MDICHILD

Создать дочернее окно многодокументного интерфейса

WS_EX_STATICEDGE

Создать окно с трехмерной рамкой. Этот стиль предназначен

 

для элементов, которые не принимают ввод от пользователя

WS_EX_TOOLWINDOW

Создать окно с инструментами, предназначенное для реа-

 

лизации плавающих панелей инструментов

WS_EX_TRANSPARENT

Создать прозрачное окно. Любые окна того же уровня,

 

накрываемые этим окном, получат сообщение WM_PAINT

 

в первую очередь, тем самым создавая эффект прозрач-

 

ности

WS_EX_WINDOWEDGE

Создать окно, имеющее рамку с активизированным краем

 

 

Функция CreateWindowEx так же, как и функция CreateWindow, может быть при менена для создания любых окон, в том числе и окон элементов управления Windows. Некоторые из расширенных стилей окна предназначены как раз для дочерних окон элементов управления1.

Отображение окна на экране

Для отображения на экране созданного окна вызывается функция ShowWindow, имеющая следующий прототип:

BOOL ShowWindow(HWND hWnd, int nCmdShow);

Первым параметром функции является дескриптор окна, а второй параметр определяет, в каком виде будет показано окно.

При начальном отображении главного окна рекомендуется присваивать вто рому параметру то значение, которое передается приложению через параметр nCmdShow функции WinMain.

При последующих отображениях можно использовать любое из значений, при веденных в табл. 1.102.

1Базовые элементы управления рассматриваются в главе 7, элементы управления общего пользова ния — в главе 8.

2 В таблице приведены наиболее употребляемые значения. Полный список значений см. в MSDN.

40 Глава 1. «Hello, World!», или Первые шаги к пониманию концепции Windows

Таблица 1.10. Значения параметра nCmdShow функции ShowWindow

 

Значение

Описание

 

 

 

 

SW_HIDE

Скрыть окно

 

SW_MAXIMIZE

Развернуть окно

 

SW_MINIMIZE

Свернуть окно

 

SW_SHOW

Активизировать окно и показать в его текущих размерах

 

 

и позиции

 

SW_SHOWMINNOACTIVE

Окно не выводится, а на панели задач появляются его имя

 

 

и пиктограмма

 

 

 

ПРИМЕЧАНИЕ

Во всех книгах, посвященных программированию с Win32 API, а также в справочных материалах MSDN рекомендуется после вызова функции ShowWindow вызвать функцию UpdateWindow, которая посылает оконной процедуре сообщение WM_PAINT, заставляющее окно перерисовать свою клиентскую область. Однако эксперименты показали, что в этом нет никакой необходимости. Отладочная трассировка сообщений выявила, что результатом работы функции ShowWindow является генерация сообщений WM_SIZE и WM_MOVE, а обрабатывая сообщение WM_SIZE, система всегда генерирует сообщение WM_PAINT. Поэтому вызов функции UpdateWindow в примере закомментирован.

Обработка сообщений

После вывода окна на экран программа должна подготовить себя для получения информации от пользователя. Эта информация обычно вводится с помощью кла виатуры или мыши. Windows поддерживает «очередь сообщений» (message queue) для каждой программы, работающей в системе. Любое действие пользователя система Windows преобразует в «сообщение», которое помещается в указанную очередь.

Программа извлекает сообщения из очереди, выполняя блок команд, извест ный как «цикл обработки сообщений» (message loop):

while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg);

}

return msg.wParam;

В этом фрагменте кода переменная msg — это структура типа MSG, которая оп ределена в заголовочных файлах Windows следующим образом:

typedef struct tagMSG {

HWND

hwnd;

// дескриптор окна, которому адресовано сообщение

UINT

message;

// номер (идентификатор) сообщения

WPARAM

wParam;

// параметр сообщения wParam

LPARAM

lParam;

// параметр сообщения lParam

DWORD

time;

// время отправки сообщения

POINT

pt;

// позиция курсора (в экранных координатах) в момент

 

 

//отправки сообщения

} MSG;

 

 

Интерпретация параметров wParam и lParam зависит от номера сообщения. Тип данных POINT используется для представления точки парой ее координат: