Почему prevInstance существует в WinMain и wWinMain, если он всегда NULL - PullRequest
7 голосов
/ 18 сентября 2011

Поскольку я начинающий, это может быть очень простой вопрос. Я запускаю DirectX 11, и при создании моего первого приложения использовался wWinMain, и во время поиска различий между WinMain и wWinMain я наткнулся на этот параметр prevInstance.

prevInstance всегда равен нулю в соответствии с MSDN, и, поскольку он всегда равен нулю, почему он существует (поскольку логично думать, что создатели не предоставят бесполезный параметр). И (цитата из книги)

если вам нужен способ определить, является ли предыдущий экземпляр приложение уже запущено, документация рекомендует создать мьютекс с уникальным именем, использующий CreateMutex. Хотя мьютекс будет После создания функция CreateMutex вернет ERROR_ALREADY_EXISTS.

Что такое мьютекс и как его использовать (хорошей ссылки будет достаточно). И похоже, что нужен метод, чтобы найти, существует ли другой экземпляр приложения, у prevInstance должен быть указатель или ссылка на него, что, по-видимому, не так, поскольку оно равно нулю. Почему это так, и какова роль распространенности?

Ответы [ 2 ]

15 голосов
/ 18 сентября 2011

Блог Раймонда Чена почти целиком посвящен обсуждению аспектов 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, вы знаете, что экземпляр вашего приложения уже запущен.

1 голос
/ 18 сентября 2011

Превосходный параметр экземпляра для 16-битной совместимости с Windows. Я думаю, что это было указано в справочнике MSDN для WinMain, по крайней мере, раньше.

...