Функция main
Функция main , получающая управление при запуске приложения, создает главное окно и организует цикл обработки сообщений.
В переменной hmq хранится идентификатор очереди сообщений, созданной функцией WinCreateMsgQueue . При выборке сообщение записвается для временного хранения в структуру qmsg.
Переменная flFrameFlags хранит набор флагов, которые используются при создании окна Frame Window :
ULONG flFrameFlags = FCF_SYSMENU | FCF_TITLEBAR | FCF_MINMAX | FCF_SIZEBORDER | FCF_SHELLPOSITION | FCF_TASKLIST | FCF_ICON;
Мы создаем окно, которое имеет меню, заголовок, кнопки минимизации и максимизации, рамку для изменения размеров окна и пиктограмму. Начальные размеры и расположение окна выбираются оболочкой Workplace Shell.
В строке szWndClass записано имя класса, которое используется для окна Client Window .
Первое, что делает функция main после запуска приложения - это инициализация при помощи функции WinInitialize . Данная функция должна вернуть идентификатор блока Anchor-block при нормальном завершении и значение NULLHANDLE в случае возникновения ошибки.
Как обработать ошибку?
Можно, конечно, просто завершить работу приложения, однако в этом случае мы так и не узнаем, что же произошло. Гораздо лучше было бы вывести на экран сообщение об ошибке, однако в приложении Presentation Manager мы не можем воспользоваться для этого такими функциями, как puts или printf .
Нас выручит тот факт, что в программном интерфейсе Presentation Manager имеется простейшее средство отображения сообщений в диалоговых панелях - функция WinMessageBox . Вот как мы использовали эту функцию для вывода сообщения при возникновении ошибки инициализации:
if(hab == NULLHANDLE) { WinMessageBox (HWND_DESKTOP, HWND_DESKTOP, "Ошибка инициализации", "Ошибка", 0, MB_ICONHAND | MB_OK); return(-1); }
Прототип функции WinMessageBox приведен ниже:
ULONG WinMessageBox ( HWND hwndParent, // идентификатор родительского окна HWND hwndOwner, // идентификатор окна владельца PSZ pszText, // текст сообщения PSZ pszCaption, // заголовок диалоговой панели ULONG idWindow, // идентификатор окна // диалоговой панели ULONG flStyle); // стиль диалоговой // панели с сообщением
В функции main определены флаги, которые используются для создания окон верхнего уровня (переменная flFrameFlags) и для окна дочернего уровня (переменная flFrameChildFlags).
Обратите внимание, что для дочернего окна мы не используем флаги FCF_ICON , FCF_SHELLPOSITION и FCF_TASKLIST . Для установки пиктограммы, отображемой в верхнем левом углу дочернего окна, мы посылаем этому окну сообщение WM_SETICON . Размеры и расположение дочернего окна будут установлены явням образом при помощи функции WinSetWindowPos .
Каждое из трех окон нашего приложения имеет свою функцию окна и потому создается на базе своего класса окна. Имена этих классов хранятся в переменных szWndClass1, szWndClass2 и szWndClassChild.
Свою работу функция main начинает, как обычно, с вызова функции инициализации WinInitialize . Далее при помощи функции WinCreateMsgQueue создается очередь сообщений.
После этого для регистрации классов окна три раза вызывается функция WinRegisterClass . При этом определяется, что для окон, создаваемых на базе класса szWndClass1, будет использоваться функция окна WndProc1, для окон, создаваемых на базе класса szWndClass2 - функция окна WndProc2, а для окон, создаваемых на базе класса szWndClassChild - функция окна WndProcChild.
Как и раньше, после вызова каждой функции проверяется код возврата. Если при выполнении функции произошла ошибка, приложение выводит на экран соответствующее сообщение и завершает свою работу.
Если регистрация классов завершилась успешно, функция main создает два окна верхнего уровня, аналогично тому, как создавалось главное окно предыдущего приложения. Каждое из этих окон основано на базе своего класса окна и имеет собственную функцию окна, однако для обоих окон мы указали один и тот же идентификатор ресурсов. В результате эти окна будут иметь одинаковую пиктограмму системного меню.
На следующем этапе наше приложение создает окно, которое является дочерним по отношению к второму окну верхнего уровня, имеющему идентификатор hWndFrame2. Для этого используется знакомая вам функция WinCreateStdWindow :
Функция main в этом приложении не имеет никаких особенностей. Так как первоначально меню верхнего уровня загружается из ресурсов приложения, при создании главного окна мы указали флаг FCF_MENU .
Функция main не имеет никаких особенностей. Она создает главное окно приложения и очередь сообщений, а затем запускает цикл обработки сообщений.
В функции main нет ничего особенного за исключением того, что при создании главного окна приложения используется сокращенный набор флагов:
ULONG flFrameFlags = FCF_SIZEBORDER | FCF_SHELLPOSITION | FCF_TASKLIST | FCF_ICON;
В результате окно Frame Window не создает окна заголовка, системное меню и кнопки минимизации/максимизации. Без дополнительной обработки сообщений мыши пользователь не сможет перемещать такое окно. Размер окна можно изменять, так как указан флаг FCF_SIZEBORDER.
Функция main имеет одну особенность - после создания главного окна приложения и перед запуском цикла обработки сообщений главному окну посылается сообщение WM_SETICON :
WinSendMsg (hWndFrame, WM_SETICON , (MPARAM)WinQuerySysPointer (HWND_DESKTOP, SPTR_ICONINFORMATION, FALSE), NULL);
Через первый параметр вместе с этим сообщением передается идентификатор встроенной пиктограммы SPTR_ICONINFORMATION , полученный от функции WinQuerySysPointer . Второй параметр сообщения WM_SETICON равен нулю.
После получения этого сообщения пиктограмма приложения, которая отображается в окне системного меню и которая была загружена из ресурсов приложения, заменяется на новую.
В функции main приложения CLOCK для создания главного окна приложения используется самый маленький набор флагов:
ULONG flFrameFlags = FCF_TASKLIST | FCF_ICON;
Главное окно приложения не имеет рамки, поэтому пользователь не может изменять его размеры. У окна нет заголовка, системного меню и меню минимизации/максимизации, поэтому для перемещения окна используется та же методика, что и в описанном ранее приложении MOUSEMOVE. Эта методика основана на обработке сообщения WM_MOUSEMOVE .
Сразу после создания главного окна наше приложение устанавливает его размер. Для этого функция main получает пространство отображения, выбирает в него шрифт с фиксированной шириной символов и определяет метрики этого шрифта. Ширина главного окна приложения выбирается в 10 раз больше, чем ширина символов, а высота - равной высоте символов с учетом размера выступающей части:
WinSetWindowPos (hWndFrame, HWND_TOP , 0, 0, 10 * cxChar, cyChar + cyDesc, SWP _SIZE | SWP_MOVE | SWP_ZORDER );
Кроме изменения размеров онка, функция WinSetWindowPos изменяет расположение окна по оси Z, выдвигая его на передний план.
Далее функция main обычным образом запускает цикл обработки сообщений.
Функция main не имеет особенностей. Она создает главное окно приложений, очередь сообщений и запускает цикл обработки сообщений.
Функция main не имеет никаких особенностей. Она создает главное окно приложения, очередь сообщений и затем запускает цикл обработки сообщений.