Глобальные переменные не использовать! 1 страница
Министерство образования и науки Республики Казахстан
Таразский государственный университет им М.Х. Дулати
Г.С.Алтыбаев, А.Н.Иманбекова
СИСТЕМНОЕ ПРОГРАММИРОВАНИЕ В ОС WINDOWS
Учебно-методическое пособие
Издательство«Тараз университеті»
Тараз, 2016
Алтыбаев Г.С., Иманбекова А.Н.
Системное программирование в ОС Windows: Учебно-методическое пособие. – Тараз: Тараз университетi, 2016. – 143 стр.
Рецензенты:
Аязбаев Т.Л. – к.ф.-м.н., доцент кафедры «Математика и вычислительная техника» Таразского инновационно-гуманитарного университета;
Мамаев Ш.М. – д.ф.-м.н., заведующий кафедрой «Математика и вычислительная техника» Таразского инновационно-гуманитарного университета;
Сембина Г.К. – к.т.н., доцент, заведующая кафедрой «Информационные системы» Таразского государственного университета им. М.Х. Дулати.
В пособии рассмотрены вопросы использования интерфейса программирования приложений (API) Win32 для разработки системных программ, предназначенных для управления и взаимодействия процессов и потоков, управления файловой системой, организации обмена между процессами и потоками асинхронным вводом-выводом. В пособии приводятся примеры программирования процесса включения функции в динамическую библиотеку и вызова этой функции из динамической библиотеки.
© Алтыбаев Г.С., Иманбекова А.Н.
© ТарГУ им. М.Х. Дулати, 2016
Содержание
ВВЕДЕНИЕ | |
Лабораторная работа №1. Создание окон с помощью Win32 API функций | |
Лабораторная работа №2. Процессы и их создание в Win32 API | |
Лабораторная работа №3. Создание потоков в Win32 API | |
Лабораторная работа №4. Синхронизация потоков при помощи семафоров и критических секций | |
Лабораторная работа №5. Синхронизация процессов при помощи событий и мьютексов | |
Лабораторная работа №6. Обмен данными по анонимному каналу с сервером | |
Лабораторная работа №7. Обмен данными по именованному каналу с сервером | |
Лабораторная работа №8. Работа с файлами с помощью Win32 API функций | |
Лабораторная работа №9. Работа с атрибутами файлов с помощью Win32 API функций | |
Лабораторная работа №10. Работа с каталогами с помощью Win32 API функций | |
Лабораторная работа №11. Использование динамических библиотек для создания приложений | |
Список рекомендованной литературы |
ВВЕДЕНИЕ
Учебно-методическое пособие представляет собой лабораторный практикум программирования в среде Microsoft Visual Studio 2010 с использованием библиотеки Win32 API(далее Win32) – набора базовых функций интерфейсов программирования приложений (API – Application Programming Interface), работающих под управлением операционных систем (ОС) семейства Windows.
Лабораторный практикум состоит из 11 лабораторных работ, охватывающих основные разделы программирования в среде Win32. В нем представлены примеры системного программирования приложений, предназначенных для управления файловой системой, управления и взаимодействия процессов и потоков, асинхронным вводом-выводом и т.д. В каждой лабораторной работе приводится теоретический раздел, в котором дается подробное описание используемых функций Win32, параметров функций и их возможные значения, результат выполнения данной функции и правила ее использования в программе. Поскольку программной средой выполнения лабораторной работы является MS Visual Studio 2010, то в лабораторных работах, которые посвящены созданию отдельных видов приложений, описывается процесс создания проекта, приведены исходные коды основных файлов проекта и технология компиляции файла программы. Использование функций Win32 для выполнения лабораторной работы приводится в программе, написанной на Visual Studio 2010.
Лабораторная работа состоит из следующих этапов:
1) домашняя подготовка;
2) выполнение работы на компьютере в соответствии с заданием;
3) сдача выполненной работы преподавателю на персональном компьютере;
4) распечатка результатов работы на принтере;
5) оформление отчета;
5) защита лабораторной работы.
В процессе домашней подготовки студент изучает лекционный материал, материалы по темам данного пособия и дополнительной литературы, знакомится с заданием на выполнение лабораторной работы и готовит отчет по выполнению лабораторной работы.
Выполнение лабораторной работы сводится к созданию исполняемого модуля и запуску программы с соответствующими исходными данными во время занятий в компьютерном классе кафедры «Информационные системы» в присутствии преподавателя. В процессе выполнения лабораторной работы студент последовательно выполняет задание, а по завершению работы – демонстрирует преподавателю результаты.
После приема преподавателем лабораторной работы на ПК студент сохраняет результаты лабораторной работы внешнем носителе, готовит отчет по работе и распечатывает результаты на подготовленных листах формата А4.
Отчет по каждой лабораторной работе должен содержать:
− название работы;
− цель лабораторной работы;
− задание на выполнение лабораторной работы;
− алгоритмы программ;
После выполнения лабораторной работы производится защита, на которой студенты должны пояснить технологию создания проекта задания, выбор основных параметров проекта, использование функций Win32, процесс создания Windows-приложения и ответить на контрольные вопросы, приведенные в задании.
Использование данного пособия поможет студентам освоить процесс использования функций Win32, программирование интерфейса и Windows приложений под управлением ОС семейства Windows NT.
Лабораторная работа №1
Создание окон с помощью Win32 API функций
Цель работы:
1. Изучение принципов организации и функционирования стандартных приложений Windows.
2. Изучение структуры приложений, использующих функции Win32API.
3. Создание каркаса оконного приложения Win32 и исследование его структуры.
Краткое теоретическое введение
Стиль программирования Windows-приложений принципиально отличается от того, который сложился в операционных системах раннего поколения. В MS-DOS программа монопольно владеет всеми ресурсами системы и является инициатором взаимодействия с операционной системой. Совсем иначе дело обстоит в операционной системе Windows, которая строилась как многозадачная, и именно операционная система является инициатором обращения к программе. Все ресурсы Windows являются разделяемыми, и программа, в дальнейшем будем называть ее приложением, не может владеть ими монопольно. В связи с такой идеологией построения операционной системы приложение должно ждать посылки сообщения операционной системы и лишь после его получения выполнить определенные действия, затем вновь перейти в режим ожидания очередного сообщения. На рисунке 1 схематично изображена диаграмма типичного Windows-приложения.
Windows генерирует множество различных сообщений, которые направляются приложению, например, щелчок кнопки мыши или нажатие клавиши на клавиатуре. Если приложение не обрабатывает какие-то сообщения, реакция на них осуществляется операционной системой стандартным способом, так что задачей программиста является обработка лишь тех сообщений, которые необходимы приложению.
Рисунок 1. Структура приложения Windows
Разработчиками операционной системы Windows была создана библиотека функций, при помощи которых и происходит взаимодействие приложения с операционной системой, так называемые функции Программного интерфейса приложений (Application Program Interface, API).
Подмножество этих функций, предназначенных для графического вывода на дисплей, графопостроитель и принтер, представляет собой Интерфейс графических устройств (Graphics Device Interface, GDI).
Библиотека API-функций разрабатывалась в расчете на то, что ее можно использовать для любого языка программирования, а поскольку разные языки имеют различные типы данных, то были созданы собственные Windows-типы, которые приводятся к типам данных языков программирования. Отметим только, что в Windows нет логического типа bool, но есть Windows-тип bool, который эквивалентен целому типу int. Будем рассматривать типы данных Windows по мере необходимости.
Еще одной особенностью API-функций является использование обратного, по отношению к принятому в языке С, порядка передачи параметров, как это реализовано в языке Pascal. В С для идентификации таких функций использовалось служебное слово pascal, в Windows введены его синонимы CALLBACK, APIENTRY или WINAPI. По умолчанию С-функции передают параметры, начиная с конца списка так, что первый параметр всегда находится на вершине стека. Именно это позволяет использовать в языке С функции с переменным числом параметров, что в API-функциях невозможно.
Каркас Windows-приложения
В отличие от программы, выполняемой в операционной системе MS-DOS, даже для создания простейшего приложения под Windows придется проделать намного больше работы. Чтобы иметь возможность работать с оконным интерфейсом, заготовка или каркас Windows-приложения должна выполнить некоторые стандартные действия:
1. Определить класс окна.
2. Зарегистрировать окно.
3. Создать окно данного класса.
4. Отобразить окно.
5. Запустить цикл обработки сообщений.
Термин интерфейс здесь следует понимать как способ взаимодействия пользователя и приложения. Класс окна – структура, определяющая его свойства.
С помощью листинга 1 рассмотрим "каркас" Windows-приложения.
Листинг 1. Минимальный код каркаса Windows-приложения
#include <windows.h>
#include <tchar.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
TCHAR WinName[] = _T("MainFrame");
int APIENTRY _tWinMain(HINSTANCE This, // Дескриптор текущего приложения
HINSTANCE Prev, // В современных системах всегда 0
LPTSTR cmd, // Командная строка
int mode) // Режим отображения окна
{
HWND hWnd; // Дескриптор главного окна программы
MSG msg; // Структура для хранения сообщения
WNDCLASS wc; // Класс окна
// Определение класса окна
wc.hInstance = This;
wc.lpszClassName = WinName; // Имя класса окна
wc.lpfnWndProc = WndProc; // Функция окна
wc.style = CS_HREDRAW | CS_VREDRAW; // Стиль окна
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); // Стандартная иконка
wc.hCursor = LoadCursor(NULL,IDC_ARROW); // Стандартный курсор
wc.lpszMenuName = NULL; // Нет меню
wc.cbClsExtra = 0; // Нет дополнительных данных класса
wc.cbWndExtra = 0; // Нет дополнительных данных окна
// Заполнение окна белым цветом
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
if(!RegisterClass(&wc)) return 0; // Регистрация класса окна
// Создание окна
hWnd = CreateWindow(WinName, // Имя класса окна
_T("Каркас Windows-приложения"), // Заголовок окна
WS_OVERLAPPEDWINDOW, // Стиль окна
CW_USEDEFAULT, // x
CW_USEDEFAULT, // y Размеры окна
CW_USEDEFAULT, // Width
CW_USEDEFAULT, // Height
HWND_DESKTOP, // Дескриптор родительского окна
NULL, // Нет меню
This, // Дескриптор приложения
NULL); // Дополнительной информации нет
ShowWindow(hWnd, mode); //Показать окно
// Цикл обработки сообщений
while(GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);// Функция трансляции кодов нажатой клавиши
DispatchMessage(&msg); // Посылает сообщение функции WndProc()
}
return 0;
}
// Оконная функция вызывается операционной системой
// и получает сообщения из очереди для данного приложения
LRESULT CALLBACK WndProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam)
{ // Обработчик сообщений
switch(message)
{
case WM_DESTROY : PostQuitMessage(0);
break; // Завершение программы
// Обработка сообщения по умолчанию
default : return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
Исследование каркаса Windows-приложения
Рассмотрим подробно текст программы. Первая строка содержит файл включений, который обязательно присутствует во всех Windows-программах.
#include <windows.h>
Если в ранних версиях Visual Studio этот файл содержал основные определения, то сейчас он служит для вызова других файлов включений, основные из которых: windef.h, winbase.h, wingdi.h, winuser.h; а также несколько дополнительных файлов, в которых помещены определения API-функций, констант и макросов.
Дополнительно подключим:
#include <tchar.h>
В этом файле содержатся определения некоторых полезных макросов, например, макрос _Т() служит для создания строки Unicode на этапе компиляции и определен примерно так:
#define _T(x) T(x)
#ifdef _UNICODE
#define __T(x) L ## x
#else
#define __T(x) x
#endif
Рисунок 2. Страница общих свойств проекта
Макрос преобразуется в оператор "L", который является инструкцией компилятору для образования строки UNICODE, если определена константа UNICODE; и в "пустой оператор", если константа не определена. Константа UNICODE устанавливается в зависимости от установок свойства проекта Character Set (рисунок 2). Диалоговое окно свойств Property Pages доступно сейчас на подложке Property Manager панели управления Solution Explorer.
Таким образом, этот макрос позволяет компилировать проект как в кодировке Unicode, так и в Windows-кодировке. Мы подробно рассмотрели данный макрос потому, что многие определения Windows описаны подобным образом.
Далее следует прототип оконной функции:
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
Оконная функция также является функцией обратного вызова, что связано с некоторыми особенностями организации вызовов операционной системы. Эта функция регистрируется в системе, а ее вызов осуществляет операционная система, когда требуется обработать сообщение. Тип возвращаемого значения функции LRESULT эквивалентен long для Win32-проекта.
На глобальном уровне описывается имя класса окна приложения в виде текстовой строки:
TCHAR WinName [] = _T("MainFrame");
Тип TCHAR также преобразуется в wchar_t, если определена константа _UNICODE, и в char, если константа не определена.
Тип wchar_t эквивалентен типу short и служит для хранения строк в кодировке Unicode, где для одного символа выделяется 16 бит.
Имя класса окна используется операционной системой для его идентификации. Имя может быть произвольным, в частности содержать кириллический текст.
Рассмотрим заголовок головной функции:
int APIENTRY _tWinMain(HINSTANCE This, // Дескриптор текущего приложения
HINSTANCE Prev, // В современных системах всегда 0
LPTSTR cmd, // Командная строка
int mode) // Режим отображения окна
Для Windows-приложений с Unicode она носит имя wWinMain(), а в 8-битной кодировке -WinMain(), выбор варианта определяется префиксом _t, что также является стандартным приемом в библиотеке API-функций. Функция имеет четыре параметра, устанавливаемых при загрузке приложения:
− This – дескриптор, присваиваемый операционной системой при загрузке приложения;
− Prev – параметр предназначен для хранения дескриптора предыдущего экземпляра приложения, уже загруженного системой. Сейчас он потерял свою актуальность и сохранен лишь для совместимости со старыми приложениями (начиная с Windows 95, параметр устанавливается в нулевое значение);
− cmd – указатель командной строки, но без имени запускаемой программы. Тип LPTSTR эквивалентен TCHAR*;
− mode – режим отображения окна.
Дескриптор (описатель) – тип данных Windows, который используется для описания объектов операционной системы. Дескриптор напоминает индекс хеш-таблицы и позволяет отслеживать состояние объекта в памяти при его перемещении по инициативе операционной системы. Предусмотрено много типов дескрипторов: HINSTANCE, HWND и др., но все они являются 32-разрядными целыми числами.
Внутри головной функции описаны три переменные:
− hWnd — предназначена для хранения дескриптора главного окна программы;
− msg — это структура, в которой хранится информация о сообщении, передаваемом операционной системой окну приложения:
struct MSG
{
HWND hWnd; // Дескриптор окна
UINT message; // Номер сообщения
WPARAM wParam; // 32-разрядные целые содержат
LPARAM lParam; // дополнительные параметры сообщения
DWORD time; // Время посылки сообщения в миллисекундах
POINT pt; // Координаты курсора (x,y)
};
struct POINT
{
LONG x,y;
};
Тип wparam – "короткий параметр" был предназначен для передачи 16-разрядного значения в 16-разрядной операционной системе, в Win32 это такое же 32-разрядное значение, что и lparam.
– wc – структура, содержащая информацию по настройке окна. Требуется заполнить следующие поля:
wc.hlnstance = This; Дескриптор текущего приложения.
wc.lpszClassName = WinName;
Имя класса окна.
• wc.lpfnWndProc = WndProc;
Имя оконной функции для обработки сообщений.
• wc.style = CS_HREDRAW | CS_VREDRAW;
Такой стиль определяет автоматическую перерисовку окна при изменении его ширины или высоты.
• wc.hIcon = LoadIcon(NULL,IDI_APPLICATION);
Дескриптор пиктограммы (иконки) приложения. Функция LoadIcon() обеспечивает ее загрузку. Если первый параметр NULL, используется системная пиктограмма, которая выбирается по второму параметру из следующего набора:
– idi_application — стандартная иконка;
– idi_asterisk — звездочка;
– idi_exclamation — восклицательный знак;
– idi_hand — ладонь;
– IDI_QUESTION — вопросительный знак;
– idi_winlogo — логотип Windows;
• wc.hCursor = LoadCursor(NULL,IDC_ARROW);
Аналогичная функция LoadCursor () обеспечивает загрузку графического образа курсора, где нулевой первый параметр также означает использование системного курсора, вид которого можно выбрать из списка:
– idc_arrow — стандартный курсор;
– idc_appstarting — стандартный курсор и маленькие песочные часы;
– idc_cross — перекрестие;
– idc_ibeam — текстовый курсор;
– idc_no — перечеркнутый круг;
– idc_sizeall — четырехлепестковая стрелка;
– idc_sizenesw — двухлепестковая стрелка, северо-восток и юго-запад;
– idc_sizenwse — двухлепестковая стрелка, северо-запад и юго-восток;
– idc_sizens — двухлепестковая стрелка, север и юг;
– idc_sizewe — двухлепестковая стрелка, запад и восток;
– idc_uparrow — стрелка вверх;
– idc_wait — песочные часы;
• wc.lpszMenuName = NULL;
Ссылка на строку главного меню, при его отсутствии null.
• wc.cbClsExtra = 0;
Дополнительные параметры класса окна.
• wc.cbWndExtra = 0; Дополнительные параметры окна.
• wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
Дескриптор кисти, которая используется для заполнения окна. Стандартная конструкция, создает системную кисть белого цвета WHITE_BRUSH. Требуется явное преобразование типа — HBRUSH.
После того как определены основные характеристики окна, можно это окно создать при помощи API-функции CreateWindow(), где также нужно задать параметры:
1. WinName — имя, которое присвоено классу окна.
2. _T("Каркас Windows-приложения") — заголовок окна в виде строки Unicode либо С-строки.
3. ws_overlappedwindow — макрос, определяющий стиль отображения стандартно-
го окна, имеющего системное меню, заголовок, рамку для изменения размеров,
а также кнопки минимизации, развертывания и закрытия. Это наиболее общий
стиль окна, он определен так:
#define WS_OVERLAPPEDWINDOW (WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|
WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX)
Можно создать другой стиль, используя комбинацию стилевых макросов при помощи операции логического сложения, вот некоторые из них:
WS_OVERLAPPED — стандартное окно с рамкой;
WS_CAPTION — окно с заголовком;
WS_THICKFRAME — окно с рамкой;
WS_MAXIMIZEBOX — кнопка распахивания окна;
WS_MINIMIZEBOX — кнопка минимизации;
WS_SYSMENU — системное меню;
WS_HSCROLL — горизонтальная панель прокрутки;
WS_VSCROLL — вертикальная панель прокрутки;
WS_VISIBLE — окно отображается;
WS_CHILD — дочернее окно;
WS_POPUP — всплывающее окно;
4. Следующие два параметра определяют координаты левого верхнего угла окна (x,y) , еще два параметра: Width — ширину и Height — высоту окна в пикселах. Задание параметра CW_USEDEFAULT означает, что система сама выберет для отображения окна наиболее (с ее точки зрения) удобное место и размер.
5. Следующий параметр — указатель на структуру меню, или NULL, при его отсутствии.
6. Далее требуется указать дескриптор приложения, владельца окна — This.
7. И, наконец, указатель на дополнительную информацию, в нашем случае – NULL.
Окно создано, и с ним можно работать, но пока оно не отображается. Для того чтобы окно увидеть, необходимо его отобразить с помощью функции ShowWindow(hWnd, mode), которая принимает два параметра: hWnd – дескриптор окна и mode – режим отображения. В нашем случае используется значение, полученное при открытии приложения через параметр головной функции.
Далее, заключительная часть головной функции – цикл обработки сообщений. Он задается оператором while, аргументом которого является функция GetMessage(&msg, NULL, 0, 0). Такой цикл является обязательным для всех Windows-приложений, его цель — получение и обработка сообщений, передаваемых операционной системой. Операционная система ставит сообщения в очередь, откуда они извлекаются функцией GetMessage() по мере готовности приложения:
□ первым параметром функции является &msg — указатель на структуру MSG, где и хранятся сообщения;
□ второй параметр hWnd — определяет окно, для которого предназначено сообщение, если же необходимо перехватить сообщения всех окон данного приложения, он должен быть null;
□ остальные два параметра определяют [min, max] диапазон получаемых сообщений. Чаще всего необходимо обработать все сообщения, тогда эти параметры должны быть равны 0.
Сообщения определяются их номерами, символические имена для них определены в файле включений winuser.h. Префикс всех системных сообщений WM_.
Внутри цикла расположены две функции:
TranslateMessage(&msg);
DispatchMessage(&msg);
Первая из них транслирует код нажатой клавиши в клавиатурные сообщения WM_CHAR. При этом в переменную wParam структуры msg помещается код нажатой клавиши в Windows-кодировке CP-1251, в младшее слово lParam — количество повторений этого сообщения в результате удержания клавиши в нажатом состоянии, а в старшее слово — битовая карта со значениями, приведенными в таблица 1.
Использование этой функции не обязательно и нужно только для обработки сообщений от клавиатуры.
Вторая функция, DispatchMessage(&msg), обеспечивает возврат преобразованного сообщения обратно операционной системе и инициирует вызов оконной функции данного приложения для его обработки.
Данным циклом и заканчивается головная функция.
Далее следует описать оконную функцию WndProc(), и построение каркаса Windows-приложения будет закончено.
Таблица 1. Битовая карта клавиатуры, HIWORD(lParam)
Бит | Значение |
1, если клавиша отпущена, 0 — если нажата | |
1, если клавиша была нажата перед посылкой сообщения | |
1, если нажата клавиша <Alt> | |
12–9 | Резерв |
1, если нажата функциональная клавиша | |
7–0 | Scan-код клавиши |
Основной компонент этой функции – переключатель switch, обеспечивающий выбор соответствующего обработчика сообщений по его номеру message. В нашем случае предусмотрена обработка лишь одного сообщения WM_DESTROY. Это сообщение посылается, когда пользователь завершает программу. Получив его, оконная функция вызывает функцию PostQuitMessage(0), которая завершает приложение и передает операционной системе код возврата – 0. Точнее генерируется сообщение WM_QUIT, получив которое функция GetMessage () возвращает нулевое значение. В результате цикл обработки сообщений прекращается и происходит завершение работы приложения.
Все остальные сообщения обрабатываются по умолчанию функцией DefWindowProc(), имеющей такой же список параметров и аналогичное возвращаемое значение, поэтому ее вызов помещается после оператора return.
Листинг 2. Простое окно сообщений
#include <windows.h> // заголовочный файл, содержащий функции API
// Основная функция - аналог int main() в консольном приложении:
int WINAPI WinMain(HINSTANCE hInstance, // дескриптор экземпляра приложения
HINSTANCE hPrevInstance, // в Win32 не используется
LPSTR lpCmdLine, // нужен для запуска окна в режиме командной строки
int nCmdShow) // режим отображения окна
{
// Функция вывода окна с кнопкой "ОК" на экран (о параметрах позже)
MessageBox(NULL, L"Привет, мир!!!", L"Оконная процедура", MB_OK);
return NULL; // возвращаем значение функции
}
Листинг 3. Сложное окно сообщений
#include <windows.h> // содержит API
// Основная функция:
int WINAPI WinMain (HINSTANCE hInst, // дескриптор экземпляра приложения
HINSTANCE hPreviousInst, // в Win32 не используется, но объявление нужно
LPSTR lpCommandLine, // нужен для запуска окошка в режиме командной строки
int nCommandShow) // режим отображения окна
{
int result = MessageBox(NULL, L"Вам нравится WINAPI?!", L"Задача",
MB_ICONQUESTION | MB_YESNO);
switch (result)
{
case IDYES: MessageBox (NULL, L"Продолжайте в том же духе!!!",
L"Ответ", MB_OK| MB_ICONASTERISK); break;
case IDNO: MessageBox (NULL, L"Очень жаль!!!", L"Ответ",
MB_OK| MB_ICONSTOP); break;
}
return NULL;
}
Третьим параметром могут быть записаны следующие идентификаторы:
параметры кнопок:
MB_ABORTRETRYIGNORE — три кнопки: ABORT, RETRY, IGNORE
MB_CANCELTRYCONTINUE — три кнопки: CANCEL, TRY, CONTINUE
MB_HELP MB_OK MB_OKCANCEL — 2 кнопки: OK, CANCEL
MB_RETRYCANCEL — 2 кнопки: RETRY, CANCEL
MB_YESNO — 2 кнопки: YES, NO
MB_YESNOCANCEL — три кнопки: YES, NO, CANCEL
параметры пиктограммы:
MB_ICONSTOP — выводит (крестик)
MB_ICONQUESTION — выводит (знак вопроса)
MB_ICONEXCLAMATION — выводит восклицательный знак в треугольнике
MB_ICONASTERISK — выводит (восклицательный знак)
А возвращать значения при нажатии вышеуказанных кнопок функция MessageBox будет такие:
IDABORT — при нажатии на ABORT
IDCANCEL – …….на кнопку CANSEL
IDCONTINUE – ……..на кнопку CONTINUE
IDIGNORE – …….на кнопку IGNORE
IDNO – …….на кнопку NO
IDOK – …….на кнопку OK
IDRETRY – …….на кнопку RETRY