Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабораторный практикум «Основы разработки приложений Windows» книга 1.DOC
Скачиваний:
107
Добавлен:
10.05.2014
Размер:
721.41 Кб
Скачать

Главная функция WinMain()

Запуская приложение, мы фактически передаем управление программам Windows, которые загружают в память нашу программу и вызывают из нее главную функцию, которая обязательно должна иметь имя WinMainи описательWINAPI. Вызывая функциюWinMain(), Windows передает ей четыре параметра.

Первый параметр, имеющий тип HINSTANCEи поступающий в локальную переменную, названную нами в примере 1-1 hInst, представляет собой дескриптор приложения. Он назначается приложению при его запуске системой Windows и служит для его идентификации. Многие функции Windows используют этот дескриптор в качестве входного параметра, поэтому его часто приходится сохранять в соответствующей глобальной переменной. В данной программе сохранениеhInstне требуется.

Второй параметр того же типа в старых, 16-разрядных приложениях, являлся дескриптором предыдущего запущенного экземпляра этого же приложения (если приложение одновременно выполнялось в нескольких экземплярах); в 32-разрядных приложениях он всегда имеет значение NULL и не используется.

Следующий параметр представляет собой указатель на строку, содержащую параметры командной строки запуска приложения, если при его запуске были указаны какие-либо параметры. Поскольку мы не предполагаем запускать наше приложение с параметрами, и этот аргумент функции WinMain()нам не нужен, в заголовке функции указан только его типLPSTR, а сам аргумент опущен.

Наконец, через последний параметр Windows передает нам свои рекомендации по режиму запуска приложения (стандартного размера, свернутое в значок или развернутое на весь экран). В дальнейшем мы сами зададим режим запуска, рекомендации Windows нас не интересуют, и последний аргумент в заголовке функции также опущен.

В типичном приложении Windows главная функция WinMain() должна выполнить по меньшей мере три важных действия:

  • Зарегистрироватьв системе Windows класс главного окна. Если помимо главного окна планируется выводить на экран внутренние, порожденные окна, то их классы также необходимо зарегистрировать.Windows выводит на экран и обслуживает только зарегистрированные окна.

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

  • Организовать цикл обработки сообщений, поступающих в приложение. Вся дальнейшая жизнь приложения будет фактически состоять в бесконечном выполнении этого цикла и в обработке поступающих в приложение сообщений. Запущенное приложение Windows обычно функционирует до тех пор, пока пользователь не подаст команду его завершения с помощью системного меню или вводом команды <Alt>+<F4>. Эти действия приводят к завершению главной функции и удалению приложения из списка действующих задач.

Функция WinMain после своего завершения возвращает в Windows целочисленный результат (в нашем примере 0), который системой не анализируется и нас интересовать не будет.

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

Как уже отмечалось, для вывода на экран любого окна, в частности главного окна приложения, необходимо прежде всего зарегистрировать класс окна, в котором задаются некоторые характеристики, присущие всем окнам данного класса. Это действие выполняется в первой, инициализирующей части функции WinMain().

Действия по регистрации класса окна заключаются в заполнении структурной переменной типа WNDCLASS, служащей для описания характеристик класса регистрируемого окна, и вызове затем функции WindowsRegisterClass(), которая и выполняет регистрацию данного класса.

Структура WNDCLASS, определенная в файлеWINUSER.H, содержит ряд членов, задающих наиболее общие характеристики окна, такие, как имя оконной функции, цвет фона, формы курсора и пиктограммы и др.

При заполнении структурной переменной типа WNDCLASS необходимо обеспечить нулевое значение всех элементов, которым мыне присваиваемконкретные значения. Нулевое значение элемента структуры обозначает для Windows, что характеристики этого элемента должны устанавливаться по умолчанию. Это правило, кстати, характерно и для других структур, описывающих те или иные объекты Windows, например для структурыOPENFILENAME, служащей для вывода на экран стандартного диалога Windows “Открытие файла”, или структурыLOGFONT, позволяющей создать шрифт требуемого начертания. Поэтому, объявив структурную переменнуюwc, мы прежде всего обнуляем ее вызовом функции WindowsZeroMemory()

ZeroMemory(&wc,sizeof(wc));

которая записывает, начиная с адреса &wc, нули в количествеsizeof(wc)штук. Далее ряду элементов структуры присваиваются определенные значения.

Наиболее важными для дальнейшего функционирования программы являются три поля: hInstance, где хранится дескриптор данного приложения,lpszClassName, куда заносится произвольное имя, присвоенное нами окнам данного класса (у нас это окно единственное) иlpfnWndProc– имя оконной функции. Именно с помощью структурыWNDCLASSWindows, обслуживая нашу программу, определяет адрес оконной функции, которую она должна вызывать при поступлении в окно сообщений. ПолеlpszClassNameмы заполняем из переменнойszClassName, определенной нами в начале программы, а значение дескриптора приложения переносим из параметраhInstфункцииWinMain().

Менее важными в принципиальном плане, но существенными для разумного поведения приложения являются поля hIcon, hCur­sorиhbrBackground, куда следует записать дескрипто­ры пиктограммы, курсора и цветной кисти, которой закрашивается фон окна.

Курсор относится к ресурсам Windows; ресурсы обычно загружаются из специально созданного файла ресурсов с помощью соответствующих функций Windows, в частности LoadCursor(). В качестве первого аргумента этих функций указывается дескриптор приложения, в котором хранится требуемый ресурс, а в качестве второго – имя ресурса. Однако можно обойтись и встроенными ресурсами Windows. Для этого в качестве первого аргумента этих функций указываетсяNULL(обычноNULLна месте дескриптора приложения обозначает саму систему Windows); второй аргумент надо выбрать из списка встроенных ресурсов Windows.

Другим ресурсом Windows, указываемым в классе окна, является пиктограмма. Как и курсор, пиктограмма может быть нарисована программистом специально для данного приложения и храниться в файле ресурсов приложения или в отдельном файле с расширением .ICO; для учебных задач проще использовать одну из стандартных пиктограмм Windows. Символические константы, обозначающие те или иные ресурсы Windows (курсоры и пиктограммы) можно найти в интерактивном справочнике, в статьяхLoad­Cur­sorи LoadIcon.

Цвет фона окна определяется дескриптором кисти, записанным в структуру WNDCLASS. Проще всего воспользоваться одной из встроенных кистей, хранящихся на складе Windows, получив ее оттуда с помощью макросаGetStockBrush()или функцииGet­StockObject().

Можно ли закрасить главное окно приложения каким-нибудь другим цветом, например зеленым или желтым? Можно, однако, таких кистей нет на складе, и их придется создавать заново. Для создания кисти служит функция CreateSolidBrush(), в качестве единственного параметра которой указывается требуемый цвет в виде комбинации трех чисел, характеризующих интенсивность красной, зеленой и синей составляющих цвета. Для упаковки этих трех чисел в одно 4-байтовое слово и преобразования полученного значения в типCOLORREF, требуемый функциейCreate­SolidBrush(), служит макросRGB(). Таким образом, чтобы сделать главное окно приложения, например, бирюзовым, надо заполнить элементhbrBackground структурной переменной типаWNDCLASS следующим образом:

wc.hbrBackground=CreateSolidBrush(RGB(0,255,255));

Отметим еще назначение стилякласса окна (элементstyle структурыWNDCLASS), хотя в нашем примере эта переменная не используется. Стиль представляет собой комбинацию констант, определяющих некоторые характеристики всех окон, принадлежащих регистрируемому классу. Так, указание константыCSDBL­CLKS позволяет программе реагировать на двойные щелчки мышью в области окна; константыCSVREDRAW иCSHREDRAW заставляют Windows перерисовывать окно заново при каждом изменении его размеров по горизонтали и вертикали, константаCSNOCLOSE запрещает закрытие окна пользователем и т. д. Если стилю назначается несколько констант одновременно, их необходимо сложить с помощью оператора побитового ИЛИ:

wc.style= CS_VREDRAW |CS_HREDRAW;

Функция RegisterClass()требует в качестве аргументаадресструктурной переменной типаWNDCLASS, поэтому предложение вызова этой функции выглядит следующим образом:

RegisterClass(&wc);

Зарегистрировав класс окна, можно приступить к созданию и показу окна.