Windows приложения функция winmain
Функция WinMain вызывается системой как начальная точка входа, для базирующейся на Windows, прикладной программы.
HINSTANCE hInstance, // дескриптор текущего экземпляра окна
HINSTANCE hPrevInstance, // дескриптор предыдущего экземпляра окна
LPSTR lpCmdLine, // указатель на командную строку
int nCmdShow // показывает состояние окна
[in] Дескриптор текущего экземпляра прикладной программы.
[in] Дескриптор предыдущего экземпляра приложения. Этот параметр всегда имеет значение ПУСТО (NULL). Если Вам нужно обнаружить, существует ли другой экземпляр уже существующей программы, создайте именованный mutex-объект , используя функцию CreateMutex . Функция CreateMutex завершится успешно, даже если мьютекс (флажок блокировки) уже существует, но функция возвратит ERROR_ALREADY_EXISTS . Это указывает (обозначает), что другой экземпляр вашего приложения существует, потому что он первым создал мьютекс.
[in] Указатель на строку с символом нуля в конце, устанавливающую командную строку для приложения, исключая имя программы. Чтобы извлечь полную командную строку, используйте функцию GetCommandLine .
[in] Определяет, как окно должно быть показано. Этот параметр может быть одним из следующих значений:
Значение
Предназначение
Скрывает окно и активизирует другое окно.
SW_MAXIMIZE
Максимизирует заданное окно.
SW_MINIMIZE
Минимизирует заданное окно и активизирует следующее окно верхнего уровня в Z-последовательности .
SW_RESTORE
Активизирует и показывает на экране окно. Если окно минимизировано или развернуто, система восстанавливает его в первоначальном размере и позиции. Приложение должно установить этот флажок при восстановлении свернутого окна.
Активизирует и отображает окно на экране в его текущем размере и позиции.
SW_SHOWMAXIMIZED
Активизирует окно и отображает его как развернутое окно.
SW_SHOWMINIMIZED
Активизирует окно и отображает его как пиктограмму.
SW_SHOWMINNOACTIVE
Отображает окно как пиктограмму. Это значение походит на флажок SW_SHOWMINIMIZED , исключая окно, которое не активизировано.
SW_SHOWNA
Отображает окно в его текущих размерах и позиции. Это значение походит на флажок SW_SHOW , исключая окно, которое не активизировано.
SW_SHOWNOACTIVATE
Отображает окно в его самых последних размерах и позиции. Это значение походит на флажок SW_SHOWNORMAL , исключая окно, которое не активизировано.
SW_SHOWNORMAL
Активизирует и отображает на экране окно. Если окно минимизировано или развернуто, система восстанавливает его в первоначальных размерах и позиции. Приложение должно установить этот флажок при отображении на экране окна впервые.
Если функция достигла цели, то завершается тогда, когда примет сообщение WM_QUIT , при этом она должна возвратить значение выхода, содержащееся в параметре wParam этого сообщения. Если функция завершается перед вводом цикла сообщений, она должна возвратить 0.
WinMain инициализирует прикладную программу, отображает на экране её основное окно и, затем, входит в извлекающий и распределяющий цикл сообщений, который является управляющей структурой верхнего уровня для остальных элементов выполнения прикладной программы. Цикл сообщений завершается тогда, когда он получает сообщение WM_QUIT. В этот момент, WinMain завершает работу прикладной программы, возвращая значение, переданное в параметр wParam сообщения WM_QUIT. Если WM_QUIT было получено в результате вызова PostQuitMessage , значение wParam — значение параметра nExitCode функции PostQuitMessage . Для получения дополнительной информации, см. Создание цикла обработки сообщений .
Приложения ANSI могут использовать параметр lpCmdLine функции WinMain , чтобы обратиться к командной строке, исключая имя программы. Причина этого в том, что WinMain не может возвращать строки Уникода из-за того, что lpCmdLine использует тип данных LPSTR , не тип данных LPTSTR . Функция GetCommandLine может быть использована для обращения к строкам
Unicode в командной строке, потому что она использует тип данных LPTSTR .
Структура оконного приложения
Оконные приложения строятся по принципам событийно-управляемого программирования (event-driven programming) — стиля программирования, при котором поведение компонента системы определяется набором возможных внешних событий и ответных реакций компонента на них. Такими компонентами в Windows являются окна.
С каждым окном в Windows связана определенная функция обработки событий – оконная функция . События для окон называются сообщениями . Сообщение относится к тому или иному типу, идентифицируемому определенным кодом (32-битным целым числом), и сопровождается парой 32-битных параметров ( WPARAM и LPARAM ), интерпретация которых зависит от типа сообщения.
Задача любого оконного приложения — создать главное окно и сообщить Windows функцию обработки событий для этого окна. Все самое интересное для приложения будет происходить именно в функции обработки событий главного окна.
В Windows программа пассивна. После запуска она ждет, когда ей уделит внимание операционная система. Операционная система делает это посылкой сообщений. Сообщения могут быть разного типа, они функционируют в системе достаточно хаотично, и приложение не знает, какого типа сообщение придет следующим. Логика построения Windows-приложения должна обеспечивать корректную и предсказуемую работу при поступлении сообщений любого типа.
Классическое оконное приложение, как правило, состоит по крайней мере из двух функций:
Стартовая функция WinMain
В консольной программе на С точкой входа является функция main() . С этого места программа начинает выполняться.
Точкой входа программы для Windows является функция WinMain() .
Эта функция использует последовательность вызовов API и при завершении возвращает операционной системе целое число.
Аргументы функции:
- hInstance – дескриптор процесса (instance handle) – число, идентифицирующее программу, когда она работает под Windows. Если одновременно работают несколько копий одной программы, каждая копия имеет свое значение hInstance .
- hPrevInstance — предыдущий дескриптор процесса (previous instance) — в настоящее время устарел, всегда равен NULL.
- szCmdLine — указатель на оканчивающуюся нулем строку, в которой содержатся параметры, переданные в программу из командной строки. Можно запустить программу с параметром командной строки, вставив этот параметр после имени программы в командной строке.
- iCmdShow — целое константное значение, показывающее, каким должно быть выведено на экран окно в начальный момент. Задается при запуске программы другой программой. В большинстве случаев число равно 1 ( SW_SHOWNRMAL ).
Имя | Значение | Описание |
SW_HIDE | 0 | Скрывает окно и делает активным другое окно |
SW_SHOWNORMAL | 1 | Отображает и делает активным окно в его первоначальном размере и положении. |
SW_SHOWMINIMIZED | 2 | Активизирует окно и отображает его в свернутом виде |
SW_SHOWMAXIMIZED | 3 | Активизирует окно и отображает его в полноэкранном виде |
SW_SHOWNOACTIVATE | 4 | Отображает окно аналогично SW_SHOWNORMAL , но не активизирует его |
SW_SHOW | 5 | Отображает и делает активным окно с текущим размером и положением. |
SW_MINIMIZE | 6 | Сворачивает текущее окно и делает активным следующее окно в порядке очереди. |
SW_SHOWMINNOACTIVE | 7 | Сворачивает окно аналогично SW_SHOWMINIMIZED , но не активизирует его. |
SW_SHOWNA | 8 | Отображает окно в текущей позиции аналогично SW_SHOW , но не активизирует его. |
SW_RESTORE | 9 | Отображает и активизирует окно. Если окно было свернуто или развернуто во весь экран, оно отображается в своем первоначальном положении и размере. |
SW_SHOWDEFAULT | 10 | Отображает окно способом, заданным по умолчанию. |
SW_FORCEMINIMIZE | 11 | Применяется для минимизации окон, связанных с различными потоками. |
В структуре стартовой функции Windows можно выделить следующие операции, образующие «скелет» программы:
Регистрация класса окна
Регистрация класса окна осуществляется функцией
Члены структуры
style — устанавливает стиль(и) класса. Этот член структуры может быть любой комбинацией стилей класса.
Имя | Значение | Описание |
CS_VREDRAW | 0x01 | Вертикальная перерисовка: осуществлять перерисовку окна при перемещении или изменении высоты окна. |
CS_HREDRAW | 0x02 | Горизонтальная перерисовка: осуществлять перерисовку окна при перемещении или изменении ширины окна. |
CS_KEYCVTWINDOW | 0x04 | В окне будет выполняться преобразование виртуальных клавиш. |
CS_DBLCLKS | 0x08 | Окну будут посылаться сообщения о двойном щелчке кнопки мыши. |
CS_OWNDC | 0x20 | Каждому экземпляру окна присваивается собственный контекст изображения. |
CS_CLASSDC | 0x40 | Классу окна присваивается собственный контекст изображения,который можно разделить между копиями. |
CS_PARENTDC | 0x80 | Классу окна передается контекст изображения родительского окна. |
CS_NOKEYCVT | 0x100 | Отключается преобразование виртуальных клавиш. |
CS_NOCLOSE | 0x200 | Незакрываемое окно: в системном меню блокируется выбор пункта закрытия окна. |
CS_SAVEBITS | 0x800 | Часть изображения на экране, закрытая окном, сохраняется. |
CS_BYTEALIGNCLIENT | 0x1000 | Выравнивание клиентской области окна: использование границы по байту по оси x. |
CS_BYTEALIGNWINDOW | 0x2000 | Выравнивание окна: bспользование границы по байту по оси x. |
CS_PUBLICCLASS CS_GLOBALCLASS | 0x4000 | Определяется глобальный класс окон. |
lpfnWndProc — указатель на оконную процедуру.
cbClsExtra — устанавливает число дополнительных байт, которые размещаются вслед за структурой класса окна. Система инициализирует эти байты нулями, в большинстве случаев равен 0.
cbWndExtra — устанавливает число дополнительных байтов, которые размещаются вслед за экземпляром окна. Система инициализирует байты нулями.
hInstance — дескриптор экземпляра, который содержит оконную процедуру для класса.
hIcon — дескриптор значка класса, дескриптор ресурса значка. Если этот член структуры — NULL, система предоставляет заданный по умолчанию значок.
hCursor — дескриптор курсора класса, дескриптор ресурса курсора. Если этот член структуры — NULL, приложение устанавливает форму курсора всякий раз, когда мышь перемещается в окно прикладной программы.
hbrBackground — дескриптор кисти фона класса, дескриптор физической кисти, которая используется, чтобы красить цветом фона, или код цвета, преобразованный к типу HBRUSH .
lpszMenuName — указатель на символьную строку с символом конца строки ( ‘\0’ ), которая устанавливает имя ресурса меню класса. Можно использовать целое число, чтобы идентифицировать меню с помощью макроса MAKEINTRESOURCE( int ) . Если этот член структуры — NULL , окна, принадлежащие этому классу, не имеют заданного по умолчанию меню.
lpszClassName — указатель на символьную строку с именем класса, оканчивающуюся ‘\0’ .
Создание окна
Создание окна осуществляется функцией
Прототип функции находится в файле библиотеки user32.dll.
Возвращаемое значение – дескриптор создаваемого окна. В случае невозможности создать окно возвращается NULL.
Аргументы функции :
lpClassName – указывает на строку с ‘\0’ в конце, которая определяет имя класса окна. Имя класса может быть зарегистрированным функцией RegisterClass или любым из предопределенных имен класса элементов управления.
lpWindowName — указывает на строку с ‘\0’ в конце, которая определяет имя окна.
dwStyle — определяет стиль создаваемого окна.
Имя | Значение | Описание |
WS_BORDER | 0x00800000 | Окно имеет тонкую границу в виде линии. |
WS_CAPTION | 0x00C00000 | Окно имеет строку заголовка. |
WS_CHILD | 0x40000000 | Окно является дочерним. |
WS_DISABLED | 0x08000000 | Окно является изначально неактивным. |
WS_GROUP | 0x00020000 | Окно группирует другие управляющие элементы. |
WS_HSCROLL | 0x00100000 | Окно содержит горизонтальную полосу прокрутки. |
WS_MAXIMIZE | 0x01000000 | Исходный размер окна – во весь экран. |
WS_MINIMIZE | 0x20000000 | Исходно окно свернуто. |
WS_OVERLAPPED | 0x00000000 | Окно может быть перекрыто другими окнами. |
WS_POPUP | 0x80000000 | Всплывающее окно. |
WS_SYSMENU | 0x00080000 | Окно имеет системное меню в строке заголовка. |
WS_VISIBLE | 0x10000000 | Окно изначально видимое. |
WS_VSCROLL | 0x00200000 | Окно имеет вертикальную полосу прокрутки. |
x — определяет координату левой стороны окна относительно левой стороны экрана. Измеряется в единицах измерения устройства, чаще всего в точках (pt). Для дочернего окна определяет координату левой стороны относительно начальной координаты родительского окна. Если установлен как CW_USEDEFAULT , Windows выбирает заданную по умолчанию позицию окна.
у – определяет координату верхней стороны окна относительно верхней стороны экрана. Измеряется в единицах измерения устройства, чаще всего в точках (pt). Для дочернего окна определяет координату верхней стороны относительно начальной координаты родительского окна.
nWidth – определяет ширину окна в единицах измерения устройства. Если параметр соответствует CW_USEDEFAULT , Windows выбирает заданную по умолчанию ширину и высоту для окна.
nHeight – определяет высоту окна в единицах измерения устройства.
hWndParent – дескриптор родительского окна.
hMenu – идентифицирует меню, которое будет использоваться окном. Этот параметр может быть NULL , если меню класса будет использовано.
hInstance — идентифицирует экземпляр модуля, который будет связан с окном.
lpParam — указывает на значение, переданное окну при создании.
Отображение и перерисовка окна
Отображение окна осуществляется функцией
Прототип функции находится в файле библиотеки user32.dll.
Возвращаемое значение: 1 – успешное отображение окна, 0 – ошибка.
Аргументы функции :
hWnd – дескриптор отображаемого окна.
nCmdShow – константа, определяющая, как будет отображаться окно согласно таблице.
Перерисовка окна осуществляется функцией
Прототип функции находится в файле библиотеки user32.dll.
Возвращаемое значение: 1 – успешная перерисовка окна, 0 – ошибка.
Аргумент функции hWnd – дескриптор окна.
Цикл обработки сообщений
После вызова функции UpdateWindow , окно окончательно выведено на экран. Теперь программа должна подготовить себя для получения информации от пользователя через клавиатуру и мышь. Windows поддерживает «очередь сообщений» (message queue) для каждой программы, работающей в данный момент в системе Windows. Когда происходит ввод информации, Windows преобразует ее в «сообщение», которое помещается в очередь сообщений программы. Программа извлекает сообщения из очереди сообщений, выполняя блок команд, известный как «цикл обработки сообщений» (message loop):
Для получения сообщения из очереди используется функция:
Прототип функции находится в файле библиотеки user32.dll.
В случае получения из очереди сообщения, отличного от WM_QUIT , возвращает ненулевое значение.
Аргументы функции :
lpMsg — указатель на структуру сообщения.
Структура POINT имеет вид
hWnd — дескриптор окна, очередь для которого просматривается.
wMsgFilterMin — нижняя граница фильтра идентификаторов сообщений.
wMsgFilterMax — верхняя граница фильтра идентификаторов сообщений.
передает аргумент — структуру msg обратно в Windows для преобразования какого-либо сообщения с клавиатуры. Возвращает ненулевое значение в случае успешной расшифровки сообщения, 0 – ошибка.
передает аргумент — структуру msg обратно в Windows. Windows отправляет сообщение для его обработки соответствующей оконной процедуре — таким образом, Windows вызывает соответствующую оконную функцию, указанную при регистрации класса окна.
После того, как оконная функция обработает сообщение, оно возвращается в Windows, которая все еще обслуживает вызов функции DispatchMessage . Когда Windows возвращает управление в стартовую функцию WinMain() к следующему за вызовом DispatchMessage коду, цикл обработки сообщений в очередной раз возобновляет работу, вызывая GetMessage .
Возвращает значение, определяемое оконной функцией, которое чаще всего игнорируется.
Прототипы функций находятся в файле библиотеки user32.dll.
Пример стартовой функции, создающей и выводящей окно размером 500х300 точек:
Примечание : Для корректной сборки приложения используется многобайтовая кодировка.
Оконная функция — обработка сообщений окна
Оконная функция предназначена для обработки сообщений окна. Функция обработки сообщений окна организована по принципу ветвления, состоящего из последовательной проверки типа сообщения. При совпадении типа сообщения, переданного в структуре Message с соответствующей веткой, осуществляется его обработка. Минимальный вид оконной функции представлен ниже.
4 аргумента оконной функции идентичны первым четырем полям структуры сообщения MSG .
В примере обрабатывается только один тип сообщения WM_DESTROY , которое передается оконной функции при закрытии окна.
Вызов функции DefWindowProc() обрабатывает по умолчанию все сообщения, которые не обрабатывает оконная процедура.
Функция PostQuitMessage() сообщает Windows, что данный поток запрашивает завершение. Аргументом является целочисленное значение, которое функция вернет операционной системе.
Результат выполнения программы, выводящей окно:
Комментариев к записи: 13
/*WinAPI приложение. Минимальный
набор функций для отображения окна.
Эта программа станет базовой заготовкой для всех последующих программ*/
#include
//Создаём прототип функции окна
LRESULT CALLBACK WndProc( HWND , UINT , WPARAM , LPARAM );
//объявляем имя программы
char szProgName[]=&qout;Имя программы&qout;;
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)
<
HWND hWnd; //идентификатор окна
MSG lpMsg;
WNDCLASS w; //создаём экземпляр структуры WNDCLASS и начинаем её заполнять
w.lpszClassName=szProgName; //имя программы
w.hInstance=hInstance; //идентификатор текущего приложения
w.lpfnWndProc=WndProc; //указатель на функцию окна
w.hCursor=LoadCursor( NULL , IDC_ARROW); //загружаем курсор в виде стрелки
w.hIcon=0; //иконки у нас не будет пока
w.lpszMenuName=0; //и меню пока не будет
w.hbrBackground=( HBRUSH )GetStockObject(WHITE_BRUSH); //цвет фона окна — белый
w.style= CS_HREDRAW | CS_VREDRAW ; //стиль окна — перерисовываемое по х и по у
w.cbClsExtra=0;
w.cbWndExtra=0;
//Если не удалось зарегистрировать класс окна — выходим
if (! RegisterClass (&w))
return 0;
//Создадим окно в памяти, заполнив аргументы CreateWindow
hWnd= CreateWindow (szProgName, //Имя программы
«Моя первая программа!» , //Заголовок окна
WS_OVERLAPPEDWINDOW , //Стиль окна — перекрывающееся
100, //положение окна на экране по х
100, //по у
500, //размеры по х
400, //по у
( HWND ) NULL , //идентификатор родительского окна
( HMENU ) NULL , //идентификатор меню
( HINSTANCE )hInstance, //идентификатор экземпляра программы
( HINSTANCE ) NULL ); //отсутствие дополнительных параметров
//Выводим окно из памяти на экран
ShowWindow(hWnd, nCmdShow);
//Обновим содержимое окна
UpdateWindow(hWnd);
//Цикл обработки сообщений
while ( GetMessage (&lpMsg, NULL , 0, 0)) < //Получаем сообщение из очереди
TranslateMessage(&lpMsg); //Преобразуем сообщения клавиш в символы
DispatchMessage (&lpMsg); //Передаём сообщение соответствующей функции окна
>
return (lpMsg.wParam);
>
//Функция окна
LRESULT CALLBACK WndProc( HWND hWnd, UINT messg,
WPARAM wParam, LPARAM lParam)
<
HDC hdc; //создаём контекст устройства
PAINTSTRUCT ps; //создаём экземпляр структуры графического вывода
//Цикл обработки сообщений
switch (messg)
<
//сообщение рисования
case WM_PAINT :
//начинаем рисовать
hdc=BeginPaint(hWnd, &ps);
//здесь вы обычно вставляете свой текст:
TextOut(hdc, 150,150, «Здравствуй, WIN 32 API. » , 26);
//закругляемся
//обновляем окно
ValidateRect(hWnd, NULL );
//заканчиваем рисовать
EndPaint(hWnd, &ps);
break ;
//сообщение выхода — разрушение окна
case WM_DESTROY :
PostQuitMessage(0); //Посылаем сообщение выхода с кодом 0 — нормальное завершение
break ;
default:
return ( DefWindowProc (hWnd, messg, wParam, lParam));
//освобождаем очередь приложения от нераспознаных
>
return 0;
>