Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows


Программа-пример Applnst


Эта программа, "17 AppInst.exe" (см листинг на рис 17-1), демонстрирует, как выяс нить, сколько экземпляров приложения уже выполняется в системе Файлы исходно го кода и ресурсов этои программы находятся в каталоге 17-AppInst на компакт-дис

ке, прилагаемом к книге. Погле запуска AppInst на экране появляется диалоговое окно, в котором сообщается, что сейчас выполняется только один cc экземпляр.

rihter17-4.jpg

Если Вы запустите второй экземпляр, оба диалоговых окна сообщат, что теперь выполняется два экземпляра.

rihter17-5.jpg

Вы можете запускать и закрывать сколько угодно экземпляров этой программы — окно любого из них всегда будет отражать точное количество выполняемых экземп ляров.

Где-то в начале файла AppInst.cpp Вы заметите следующие строки:

// указываем компилятору поместить эту инициализированную переменную
// в раздел Shared, чтобы она стала диступной всем окземплярам программы

#pragma data_seg("Shared")
volatile LONG g_lApplicationInstances = 0;
#pragma data_seg()

// указываем компоновщику, что раздел Shared должен быть
// читаемым, записываемым и разделяемым
#pragma comment(linker, "/Section.Shared,RWS")

В этих строках кода создается раздел Shared c атрибутами защиты, которые раз решают его чтение, запись и разделение. Внутри него находится одна переменная, g_lApplicationInstances, доступная всем экземплярам программы. Заметьте, что для этой переменной указан спецификатор vokitile, чтобы оптимизатор не слишком с ней ум ничал.

При выполнении функции _tWinMain каждого экземпляра значение переменной g_lApplicattonInstances увеличивается на 1, а перед выходом ич _tWinMain — уменьша ется на 1. Я изменяю ее знячение с помощью функции InterlockedExchangeAdd, так как эта переменная является общим ресурсом для нескольких потоков.

Когда на экране появляется диалоговое окпо каждого экземпляра программы, вызывается функция Dlg__OnJnitDialog. Она рассылает всем окнам верхнего уровня зарегиорированное оконное сообщение (идентификатор которого содержится в переменной g_aMsgAppInstCоuntUpdate).

PostMessage(HWND_BROADCAST, g_aMsgAppInstCountUpdate, 0, 0);

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

AppInst




Начало  Назад  Вперед