Программирование для Windows NT

Функция WinMain


Изучая исходный текст функции WinMain, вы по большому счету не найдете никаких отличий от исходных текстов этой функции, приведенных в приложениях Microsoft Windows 95 из 22 тома “Библиотеки системного программиста”. В этом нет ничего удивительного, так как и в Microsoft Windows 95, и в Microsoft Windows NT реализован 32-разрядный интерфейс WIN32, которым мы должны пользоваться. Более того, разрабатывая приложения для Microsoft Windows 95, вы должны проверять их работоспособность в среде Microsoft Windows NT, так как в противном случае вы не сможете стать соискателем логотипа “Designed for Microsoft Windows 95”.

Итак, вернемся к нашей функции WinMain.

Прежде всего эта функция сохраняет идентификатор приложения hInstance в глобальной переменной hInst для дальнейшего использования.

Затем выполняется поиск нашего приложения среди уже запущенных. При этом используется функция FindWindow. Если эта функция среди активных приложений найдет приложение с именем szAppName, она возвратит идентификатор его окна, если нет - значение NULL.

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

В среде Microsoft Windows NT, так же как и в среде Microsoft Windows 95, мы не можем проверить, было ли наше приложение запущенно ранее, анализируя значение параметра hPrevInstance функции WinMain, так как в отличие от Microsoft Windows версии 3.1, в указанных операционных системах через этот параметр всегда передается значение NULL. Об этом мы подробно говорили в 22 томе “Библиотеки системного программиста”.

Если приложение не найдено, выполняется регистрация класса окна. В отличие от операционной системы Microsoft Windows версии 3.1, в Microsoft Windows 95 и Microsoft Windows NT следует использовать регистрацию при помощи функции RegisterClassEx, подготовив для нее структуру WNDCLASSEX.

По сравнению со знакомой вам структурой WNDCLASS операционной системы Microsoft Windows версии 3.1 в структуре WNDCLASSEX имеются два дополнительных поля с именами cbSize и hIconSm. В первое из них необходимо записать размер структуры WNDCLASSEX, а во второе - идентификатор пиктограммы малого размера. Эта пиктограмма в Microsoft Windows NT версии 4.0 будет отображаться в левом верхнем углу главного окна приложения, играя роль пиктограммы системного меню.

Для загрузки пиктограмм из ресуросв приложения мы воспользовались функцией LoadImage, описанной нами в 22 томе “Библиотеки системного программиста”.

Заметим, что если вызов функции регистрации класса окна RegisterClassEx закончился неудачно (это может произойти, например, если вы запустите приложение в среде Microsoft Windows NT версии 3.5 или более ранней версии), мы выполняем регистрацию старым способом, который тоже работает, - при помощи функции RegisterClass.

После регистрации функция WinMain создает главное окно приложения, отображает и обновляет его, а затем запускает цикл обработки сообщений. Все эти процедуры мы описывали в 11 томе “Библиотеки системного программиста”, который называется “Операционная система Microsoft Windows 3.1 для программиста. Часть первая”.


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



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




Функция WinMain характерна для MDI-приложений. В ней вызывается функция инициализации приложения InitApp, которая регистрирует классы главного окна Frame Window и дочернего MDI-окна Document Window. Затем создается и отображается главное окно, а затем запускается цикл обработки сообщений. В этом цикле вызывается функция трансляции TranslateMDISysAccel, котурую используют MDI-приложения.




Функция WinMain выполняет обычные действия, создавая главное окно приложения и запуская цикл обработки сообщений.




Дополнительно к действиям, выполняемым этой функцией в приложении MultiMDI, новый вариант функции WinMain создает семафор с именем lpSemaphoreName:

hSemaphore = CreateSemaphore(NULL, 2, 2, lpSemaphoreName);

if(hSemaphore == NULL)

{

  MessageBox(NULL, "Ошибка при создании семафора",

    szWindowTitle, MB_OK | MB_ICONEXCLAMATION);

  return FALSE;

}

Начальное и максимальное значение счетчика семафора равно двум, поэтому одновременно будут работать не более двух задач, выполняющих рисование эллипсов в MDI-окнах, созданных пользователем. Если при создании семафора произошла ошибка, на экране появляется сообщение, после чего работа приложения завершается.

После завершения цикла обработки сообщений наше приложение освобождает идентификатор созданного ранее семафора, вызывая для этого функцию CloseHandle:

CloseHandle(hSemaphore);



Содержание раздела