Блог Раймонда Чена почти целиком посвящен обсуждению аспектов Windows API, которые являются «странностями» для нас сегодня. И, к счастью, у него есть сообщение в блоге , которое отвечает на этот точный вопрос:
В 16-битной Windows была функция GetInstanceData. это
функция взяла HINSTANCE, указатель, длину и скопированную память
из этого экземпляра в ваш текущий экземпляр. (Это своего рода
16-битный эквивалент ReadProcessMemory с ограничением, что
второй и третий параметры должны быть одинаковыми.)
...
Это и стало причиной параметра hPrevInstance для WinMain. Если
hPrevInstance был не равен NULL, тогда это был дескриптор экземпляра копии
программы, которая уже запущена. Вы можете использовать GetInstanceData для
скопируйте данные с него, быстрее встаньте на ноги. Например,
Вы можете скопировать дескриптор главного окна из предыдущего
экземпляр, чтобы вы могли общаться с ним.
Независимо от того, был ли hPrevInstance равен NULL или нет, вы сообщили
Первый экземпляр программы. Под 16-битной виндой только первый
экземпляр программы зарегистрировал свои классы; второй и последующий
экземпляры продолжали использовать классы, которые были зарегистрированы
первый случай. (Действительно, если бы они попытались, регистрация провалилась бы
так как класс уже существовал.) Поэтому все 16-битные винды
программы пропустили регистрацию класса, если hPrevInstance был
не-NULL.
Люди, разработавшие Win32, оказались в затруднительном положении, когда
пришло время портировать WinMain: что перейти на hPrevInstance?
В конце концов, весь модуль / экземпляр не существовал в Win32, и
отдельные адресные пространства означали, что программы, которые пропустили
повторная инициализация во втором случае больше не будет работать. Итак, Win32
всегда пропускает NULL, заставляя все программы полагать, что они
первый.
Конечно, теперь, когда hPrevInstance
не имеет отношения к Windows API сегодня, за исключением соображений совместимости, MSDN рекомендует использовать мьютекс для обнаружения предыдущих экземпляров приложения.
Мьютекс означает «взаимное исключение». Вы можете обратиться к документации MSDN для CreateMutex()
. Существует множество примеров использования мьютексов для обнаружения предыдущих экземпляров приложений, , таких как . Основная идея - создать мьютекс с уникальным именем, которое вы придумали, а затем попытаться создать этот мьютекс. Если CreateMutex()
завершился неудачно с ERROR_ALREADY_EXISTS
, вы знаете, что экземпляр вашего приложения уже запущен.