функция WinMain вызывается системой как начальная точка входа, для базирующейся на Win32, прикладной программы.
Синтаксис:
int WINAPI WinMain
(
HINSTANCE hInstance, // дескриптор текущего экземпляра окна
HINSTANCE hPrevInstance, // дескриптор предыдущего экземпляра окна
LPSTR lpCmdLine, // указатель на командную строку
int nCmdShow // показывает состояние окна
)
Параметры
hInstance Идентифицирует текущий образец прикладной программы. hPrevInstance Идентифицирует предыдущий образец прикладной программы. Для базирующейся на Win32 прикладной программы, этот параметр всегда имеет значение ПУСТО (NULL). Если Вам нужно обнаружить, существует ли другой образец уже существующей программы, создайте именованный mutex-объект, используя функцию CreateMutex. Если функция GetLastError возвращает сообщение ERROR_ALREADY_EXISTS, другой образец вашей прикладной программы существует (это создано mutex-объектом). lpCmdLine Указывает на строку с нулевым символом в конце, определяющую командную строку для прикладной программы. nCmdShow Определяет, как окно должно быть показано. Этот параметр может быть одним из следующих значений:
SW_HIDE - Скрывает окно и активизирует другое окно.
SW_MINIMIZE - Минимизирует определенное окно и активизирует окно верхнего уровня в списке системы.
SW_RESTORE - Активизирует и отображает окно. Если окно минимизировано или развернуто, Windows восстанавливает его в первоначальном размере и позиции (то же самое, что и SW_SHOWNORMAL).
SW_SHOW - Активизирует и отображает окно на экране в его текущем размере и позиции.
SW_SHOWMAXIMIZED - Активизирует окно и отображает его как развернутое окно.
SW_SHOWMINIMIZED - Активизирует окно и отображает его как пиктограмму.
SW_SHOWMINNOACTIVE - Отображает окно как пиктограмму. Активное окно остается активным.
SW_SHOWNA - Отображает окно в его текущем состоянии. Активное окно остается активным.
SW_SHOWNOACTIVATE - Отображает окно в его самых последних размерах и позиции. Активное окно остается активным.
SW_SHOWNORMAL - Активизирует и отображает окно. Если окно минимизировано или развернуто, Windows восстанавливает его в первоначальный размер и позицию (то же самое, что и SW_RESTORE).
Возвращаемые значения Если функция достигла цели, она завершается тогда, когда примет сообщение WM_QUIT, она должно возвратить значение выхода, содержащееся в параметре этого сообщения wParam. Если функция завершается перед вводом цикла сообщения, она должна возвратить 0.
Замечания WinMain инициализирует прикладную программу, отображает на экране её основное окно и, затем, входит в цикл сообщений " поиск и отправка по назначению (диспетчеризация)", который является управляющей структурой верхнего уровня для остальных элементов выполнения прикладной программы. Цикл сообщений завершается, когда получено сообщение WM_QUIT. В этой точке, WinMain завершает работу прикладной программы, возвращая значение, переданное в параметр wParam сообщения WM_QUIT. Если WM_QUIT было получено в результате вызова PostQuitMessage, значение wParam - значение параметра nExitCode функции PostQuitMessage. Для получения дополнительной информации, см. Создание Цикла Сообщений (Creating a Message Loop).
Типичные действия WinMain — инициализация структур данных, создние окна и запуск цикла обработки сообщений, представляющего собой непрерывную проверку наличия новых доступных сообщений. При обнаружении нового сообщения цикл принимает его и передает для дальнейшей обработки.
Дескриптор копии приложения
hPrevInstance Дескриптор предыдущего экземпляра приложения. Для Win32-приложений значение этого параметра всегда равно NULL. Если вам необходимо определить, запущена ли другая копия приложения, создайте именованый мьютекс, используя функцию CreateMutex. Если функция GetLastError возвратит значение ERROR_ALREADY_EXISTS, значит, другая копия вашего приложения запущена (она создала мьютекс).
3)Для регистрации класса окна, необходимо заполнить поля структуры типа WNDCLASS .У нас, для этого, объявлена переменная wcl.
Прежде всего нужно создать и заполнить структурную переменную WNDCLASS, а затем на её основе зарегистрировать оконный класс.
Вот как выглядит эта структура:
typedef struct {
UINT style; // стиль окна
WNDPROC lpfnWndProc; // указатель на оконную процедуру
int cbClsExtra; // дополнительные байты после класса. Всегда ставьте 0
int cbWndExtra; // дополнительные байты после экземпляра окна. Всегда ставьте 0
HINSTANCE hInstance; // экземпляр приложения. Передаётся в виде параметра в WinMain
HICON hIcon; // иконка приложения
HCURSOR hCursor; // курсор приложения
HBRUSH hbrBackground; // цвет фона
LPCTSTR lpszMenuName; // имя меню
LPCTSTR lpszClassName; // имя класса
} WNDCLASS, *PWNDCLASS;
Структура WNDCLASS в составе WinAPI определяет базовые свойства создаваемого окна: иконки, вид курсора мыши, есть ли меню у окна, какому приложению будет принадлежать окно...
После того как вы заполните эту структуру, на её основе можно зарегистрировать оконный класс. Речь идёт не о таких классах как в C++. Скорее можно считать, что оконный класс это такой шаблон, вы его зарегистрировали в системе, и теперь на основе этого шаблона можно создать несколько окон. И все эти окна будут обладать свойствами, которые вы определили в структурной переменной WNDCLASS.
В качестве параметра функции RegisterClass передается указатель на структуру wcl.
4)Оконная процедура
Оконная процедура определяет перечень сообщений, на которые реагирует окно, и алгоритмы обработки сообщений. Вызов этой функции осуществляет операционная система. После завершения работы функции управление передается обратно операционной системе.
Функции, вызываемые операционной системой, называются функциями обратного вызова, и для обозначения таких функций используется модификатор CALLBACK. Оконная процедура – это функция обратного вызова.
Оконная процедура имеет следующую структуру:
LRESULT CALLBACK WndProc (HWND hwnd,//дескриптор
//окна
UINT iMsg, //идентификатор сообщения
WPARAM wParam, //параметр сообщения
LPARAM lParam ) //параметр сообщения
{
//объявления переменных
…
switch(iMsg)
{
case WM_COMMAND:
… //обработка сообщения
break;
case WM_PAINT:
… //обработка сообщения
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd,iMsg,wParam,lParam);
}
return 0;
}
Оконная процедура получает идентификатор сообщения и выполняет ветвь инструкции switch, соответствующую этому сообщению. Если в инструкции switch такая ветвь отсутствует, обработка сообщения выполняется по умолчанию функцией DefWindowProc(). Значения параметров wParam и lParam зависят от того, какое именно сообщение получено; при обработке одних сообщений эти параметры используются, при обработке других сообщений – нет. Обработка сообщения WM_DESTROY, возникающего при завершении работы программы, заключается в исполнении функции PostQuitMessage(), которая помещает в очередь сообщений приложения сообщение WM_QUIT, останавливающее цикл обработки сообщений приложения.
5)
6) После создания окна, создающая функция возвращает дескриптор окна (window handle), который уникально идентифицирует окно. Прикладная программа использует этот дескриптор в других функциях, чтобы направить их действия на это окно. Дескриптор окна имеет тип данных HWND; прикладная программа должна использовать этот тип при объявлении переменной, которая содержит в себе дескриптор окна.
Win32 API включает в себя несколько специальных констант, которые могут заменять дескриптор окна в некоторых функциях. Например, прикладная программа может использовать HWND_TOPMOST в функции SendMessageTimeout, HWND_BROADCAST в функции SendMessage, или HWND_DESKTOP в функции MapWindowPoints.
Хотя константа ПУСТО (NULL) - не дескриптор окна, Вы можете использовать её в некоторых функциях, чтобы определить, нет ли воздействия на какое-либо окно. Например, установив значение ПУСТО (NULL) в параметре hwndParent функции CreateWindowEx, создается окно, у которого нет какого либо родителя или владельца. Некоторые функции могут возвращать значение ПУСТО (NULL) вместо дескриптора, указывая, что данное действие не применяется ни к какому окну.
Прикладная программа может использовать функцию FindWindow, чтобы обнаружить, существует ли в системе окно с определенным именем класса или именем окна. Если такое окно существует, FindWindow возвращает дескриптор окна. Чтобы ограничивать поиск в дочерних окнах отдельной прикладной программы, используйте функцию FindWindowEx. Функция IsWindow определяет, правильно ли идентифицирует дескриптор окна существующее окно.
7)Функция ShowWindow устанавливает состояние показа определяемого окна.
Синтаксис
BOOL ShowWindow
(
HWND hWnd, // дескриптор окна
int nCmdShow // состояние показа окна
);
Параметры hWnd
Идентифицирует окно.
nCmdShow
Определяет, как окно должно быть показано. Этот параметр первоначально игнорируется, когда прикладная программа вызывает ShowWindow, если программа, которая запустила прикладную программу, обеспечивает структуру STARTUPINFO. Иначе, при первом вызове функции ShowWindow, это значение должно быть значением, полученным функцией WinMain в ее параметре nCmdShow. В последующих обращениях, этот параметр может быть одним из следующих значений:
SW_HIDE - Скрывает окно и активизирует другое окно.
SW_MAXIMIZE - Развертывает определяемое окно.
SW_MINIMIZE - Свертывает определяемое окно и активизирует следующее окно верхнего уровня в Z-последовательности.
SW_RESTORE - Активизирует и отображает окно. Если окно свернуто или развернуто, Windows восстанавливает в его первоначальных размерах и позиции. Прикладная программа должна установить этот флажок при восстановлении свернутого окна.
SW_SHOW - Активизирует окно и отображает его текущие размеры и позицию.
SW_SHOWDEFAULT - Устанавливает состояние показа, основанное на флажке SW_, определенном в структуре STARTUPINFO, переданной в функцию CreateProcess программой, которая запустила прикладную программу.
SW_SHOWMAXIMIZED - Активизирует окно и отображает его как развернутое окно.
SW_SHOWMINIMIZED - Активизирует окно и отображает его как свернутое окно.
SW_SHOWMINNOACTIVE - Отображает окно как свернутое окно. Активное окно остается активным.
SW_SHOWNA - Отображает окно в его текущем состоянии. Активное окно остается активным.
SW_SHOWNOACTIVATE - Отображает окно в его самом современном размере и позиции. Активное окно остается активным.
SW_SHOWNORMAL - Активизирует и отображает окно. Если окно свернуто или развернуто, Windows восстанавливает его в первоначальном размере и позиции. Прикладная программа должна установить этот флажок при отображении окна впервые.
Возвращаемые значения
Если функция завершилась успешно, возвращается значение отличное от нуля. Если функция потерпела неудачу, возвращаемое значение - ноль.
Замечания
Первый раз, когда программа вызывает ShowWindow, она использует параметр nCmdShow функции WinMain как свой параметр nCmdShow. Последующие обращения к ShowWindow должны использовать одно из значений в данном списке, вместо того, заданного функцией WinMain параметра nCmdShow. Как отмечено в обсуждении параметра nCmdShow, значение nCmdShow игнорируется при первом обращении к ShowWindow, если программа, которая запустила прикладную программу, определяет информацию автозапуска в структуре STARTUPINFO. В этом случае, ShowWindow использует информацию, заданную в структуре STARTUPINFO, чтобы показать окно. На последующих обращениях, прикладная программа должна вызвать ShowWindow с установкой nCmdShow в SW_SHOWDEFAULT, чтобы использовать информацию автозапуска, обеспеченную программой, которая запустила прикладную программу. Например, программа Program Manager устанавливает, что прикладные программы начинаются со свернутого основного окна. Это поведение разработано для следующих ситуаций:
Прикладные программы создают свое основное окно, вызывая CreateWindow с установкой флажка WS_VISIBLE.
Прикладные программы создают свое основное окно, вызывая CreateWindow со сброшенным флажком WS_VISIBLE, а при более позднем обращении к ShowWindow с установкой флаж-ка SW_SHOW, чтобы делать его видимым.
8) учебник стр 72
9) учебник стр 72
10) учебник стр 72
11)
12)стр111. Синхронными сообщениями называются сообщения, которые Windows помещает в очередь сообщений приложения. Такие сообщения извлекаются и диспетчери-зуются в цикле обработки сообщений.
Асинхронные сообщения передаются непосредственно окну, когда Windows вызывает оконную процедуру.
Приведем примеры синхронных сообщений. Прежде всего, к ним относятся сообщения о событиях пользовательского ввода, таких как нажатие клавиш (WM_KEYDOWN и WM_KEYUP), перемещение мыши (WM_M0USEM0VE) или щелчок левой кнопкой мыши (WM_LBUTT0ND0WN). Кроме этого синхронными являются сообщения от таймера (WM_TIMER), сообщение о необходимости перерисовки клиентской области (WM_PAINT) и сообщение о выходе из программы (WM_QUIT). Приложение может само направить в очередь синхронное сообщение, вызвав функцию PostMessage.
Остальные сообщения, как правило, являются асинхронными. Во многих случаях асинхронные сообщения являются результатом обработки синхронных сообщений. Вообще, когда асинхронное сообщение обрабатывается функцией DefWindowProc, Windows часто генерирует другие сообщения, направляемые оконной процедуре. Приложение также может послать асинхронное сообщение, вызвав функцию SendMessage.
Таким образом, оконная процедура должна быть повторно входимой (reentrant program). Это означает, что Windows часто вызывает функцию WndProc с новым сообщением, появившимся в результате вызова DefWindowProc из WndProc при обработке предыдущего сообщения. В большинстве случаев повторная входимость оконной процедуры не создает каких-то особых проблем, но знать об этом полезно.
Рассмотрим, например, какие события произойдут после щелчка кнопкой мыши на кнопке закрытия окна приложения Hellol. Все начнется с того, что Windows отправит асинхронное сообщение WM_SYSCOMMAND оконной процедуре WndProc. Оконная процедура передаст это сообщение на обработку функции DefWindowProc. Функция DefWindowProc реагирует на него, отправляя сообщение WM_CL0SE оконной процедуре. В рассматриваемом примере предусмотрена обработка этого сообщения — вызывается функция DestroyWindow. Однако если не предусмотреть эту обработку, то функция DefWindowProc сделала бы то же самое, то есть вызвала бы функцию DestroyWindow. Функция DestroyWindow заставляет Windows отправить оконной процедуре сообщение WM_DESTROY. И наконец, WndProc, обрабатывая это сообщение, вызывает функцию PostQuitMessage, которая посылает синхронное сообщение WM_QUIT в очередь сообщений приложения. Сообщение WM_QUIT прерывает цикл обработки сообщений в WinMain, и приложение завершает свою работу.
Сообщения не похожи на аппаратные прерывания. Пока оконная процедура обрабатывает одно сообщение, программа не может быть прервана другим сообщением. Только в том случае, когда функция, выполняемая в теле оконной процедуры, генерирует новое асинхронное сообщение, оно вызывает повторно оконную процедуру, и только после его обработки выполнение прерванной функции продолжается.
13)
14)=26?Обработка сообщения WM_PAINT крайне важна для программирования под Windows. Это сообщение уведомляет программу, что часть или вся клиентская область окна недействительна (invalid) и ее следует перерисовать.
В каких ситуациях клиентская область окна становится недействительной? Очевидно, что при создании окна недействительна вся его клиентская область, поскольку в ней еще ничего не нарисовано. Это раз.
Если вы меняете размеры окна, клиентская область также объявляется системой недействительной, что обусловлено комбинацией стилей CS_HREDRAW | CS_VREDRAW в поле style структуры класса окна. Это два.
Когда вы минимизируете окно программы Hellol, сворачивая его на панель задач, а затем снова разворачиваете до начального размера, то Windows объявляет клиентскую область окна недействительной. Это три.
Если вы перемещаете окна так, что они перекрываются, а затем закрытая часть окна вновь открывается, то Windows помечает требующую восстановления клиентскую область как недействительную. Это четыре.
Можно было бы продолжить, но оставим подробности для второй главы.
Во всех перечисленных случаях, кроме первого, операционная система автоматически помечает клиентскую область окна как недействительную, что влечет за собой посылку сообщения WM_PAINT. В первом случае, когда окно только что было создано, аналогичный эффект достигается вызовом функции ShowWindow. В процессе ее выполнения генерируются сообщения WM_SIZE и WM_M0VE, а обрабатывая WM_SIZE, система автоматически генерирует сообщение WM_PAINT.
15) Обработку сообщения WM_PAINT рекомендуется всегда начинать с вызова функции Begin Paint:
hDC - BeginPainUhWnd, &ps);
Первый параметр функции содержит дескриптор окна, полученный через аргумент оконной процедуры, а второй — адрес структуры ps типа PAINTSTRUCT. Поля этой структуры, заполняемые в результате выполнения функции BeginPaint, в дальнейшем используются операционной системой1. Для нас сейчас более важно возвращаемое функцией значение — это дескриптор так называемого контекста устройства.
Контекст устройства (device context) описывает физическое устройство вывода информации, например дисплей или принтер. Этот важнейший объект графической подсистемы Windows рассматривается подробно во второй главе. Сейчас достаточно понимания того, что контекст устройства — это некоторая внутренняя структура данных, сохраняющая часто используемые графические атрибуты, такие как цвет фона, перо, кисть, шрифт и им подобные параметры. Эти атрибуты используются при вызове всех рисующих функций, получающих дескриптор hDC в качестве параметра.
Прежде чем перейти к следующей строке программного текста, отметим два побочных эффекта выполнения функции BeginPaint.
Во-первых, обрабатывая вызов BeginPaint, система Windows обновляет фон клиентской области, если обновляемый регион помечен для стирания1. По умолчанию для этого используется кисть, заданная в поле hbrBackground структуры WNDCLASSEX.
Во-вторых, вызов функции BeginPaint делает всю клиентскую область действительной (valid), то есть не требующей перерисовки. Это предотвращает повторную генерацию системой сообщения WM_PAINT до тех пор, пока вновь не произойдет одно из событий, требующих перерисовки окна.
После вызова BeginPaint в рассматриваемой программе следует вызов функции GetClientRect, предназначенной для получения размеров клиентской области окна:
GetClientRect(hWnd. Srect);
Результат работы функции помещается в переменную rect типа RECT. Структура RECT, описывающая прямоугольник (rectangle), определена в заголовочных файлах Windows следующим образом:
typedef struct tagRECT {
LONG left;
LONG top;
LONG right;
LONG bottom; } RECT;
Поля этой структуры задают координаты левого верхнего угла (left, top) и правого нижнего угла (right, bottom) прямоугольника.
После выполнения функции GetClientRect поля left и top всегда получают нулевое значение, а поля right и bottom содержат ширину и высоту клиентской области в пикселах. Информация о размерах клиентской области, сохраненная в переменной rect, используется далее в «рисующей» функции DrawText.
В нашей программе все «рисование» сводится к выводу текста «Hello, World!» при помощи функции DrawText, имеющей следующий прототип:
BOOL DrawText(
HDC hdc. // дескриптор контекста устройства
LPCTSTR IpString. // указатель на символьную строку
int nCount, // длина текста
LPRECT lpRect, // указатель на ограничивающий прямоугольник
UINT uFormat // флаги форматирования текста );
Функция2 выводит текст из строки IpString в прямоугольную область, заданную структурой типа RECT, используя метод форматирования, заданный параметром uFormat Количество символов в выводимой строке задается параметром nCount. Если установить значение nCount в -1, то система сама определит длину строки IpString по завершающему нулевому символу. Но в этом случае программист должен позаботиться о том, чтобы строка действительно завершалась нулевым байтом.
На месте последнего параметра функции задан набор флагов DT_SINGLELINE | DT_CENTER | DT_VCENTER, значения которых определяются в заголовочных файлах Windows. Флаги показывают, что текст будет выводиться в одну строку, по центру относительно горизонтали и вертикали внутри прямоугольной области, заданной четвертым параметром. Благодаря этому текст «Hello, World!» выводится в центре клиентской области.
Когда клиентская область становится недействительной (например, при изменении размеров окна), WndProc получает новое сообщение WM_PAINT. Обрабатывая его, программа вновь вызывает функцию GetClientRect и поэтому рисует текст опять в центре окна.
После окончания работы с графическими функциями в блоке обработки сообщения WM_PAINT необходимо освободить полученный контекст устройства с помощью функции EndPaint.
Следует отметить, что при выводе текста используются текущие установки для шрифта, цвета фона и цвета текста. О том, как управлять этими атрибутами, будет рассказано во второй главе. Для тех, кто хочет экспериментировать с цветами текста и фона немедленно, ниже приводится краткая справка.