воскресенье, 26 апреля 2009 г.

Какой смысл у параметра hPrevInstance в WinMain?

Это перевод What was the purpose of the hPrevInstance parameter to WinMain? Автор: Реймонд Чен.

Когда запускается ваша GUI-программа, её выполнение начинается с функции WinMain. Второй параметр, hPrevInstance, всегда равен нулю в Win32. Наверное, у него когда-то тоже был смысл?

Ну конечно же был.

В 16-ти битных Windows была функция GetInstanceData. Эта функция принимала аргументы типа HINSTANCE, указатель и размер буфера и копировала память из указанного экземпляра в ваш экземпляр (в какой-то мере, это 16-ти битный эквивалент функции ReadProcessMemory, только с ограничением, что второй и третий параметр должны быть одинаковыми).

Поскольку в 16-ти битных Windows все приложения выполнялись в единственном адресном пространстве, то функция GetInstanceData была просто обёрткой к hmemcpy, и многие программы использовали это и просто вызывали hmemcpy напрямую, вместо использования документированных API. На самом деле, Win16 был спроектирован с возможностью навязывания раздельного адресного пространства в будущих версиях Windows (обратите внимание на флаг GMEM_SHARED), но повсеместное злоупотребление трюками типа прямого вызова hmemcpy свело эти возможности к нулю.

В этом была причина аргумента hPrevInstance в WinMain. Если hPrevInstance был не равен нулю (non-NULL), то это был описатель экземпляра (instance handle) уже запущенной копии вашей программы. Вы могли использовать функцию GetInstanceData для копирования с него данных, и быстрее запуститься. Например, вы могли скопировать описатель главного окна с предыдущего экземпляра, так, что вы могли взаимодействовать с ним.

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

Люди, которые проектировали Win32, встали перед проблемой, когда пришло время портировать WinMain: что передавать в hPrevInstance? В конце концов, вся эта путаница с module/instance более не существовала в Win32, а раздельные адресные пространства означали, что программы не могут пропускать инициализацию, иначе они не будут работать. Поэтому в Win32 стали всегда передавать NULL, заставляя все программы верить, что они - первый экземпляр.

И, удивительно, но это на самом деле сработало.

1 комментарий:

  1. Спасибо, теперь буду знать зачем это параметр нужен, точнее не нужен.

    ОтветитьУдалить

Можно использовать некоторые HTML-теги, например:

<b>Жирный</b>
<i>Курсив</i>
<a href="http://www.example.com/">Ссылка</a>

Вам необязательно регистрироваться для комментирования - для этого просто выберите из списка "Анонимный" (для анонимного комментария) или "Имя/URL" (для указания вашего имени и ссылки на сайт). Все прочие варианты потребуют от вас входа в вашу учётку (поддерживается OpenID).

Пожалуйста, по возможности используйте "Имя/URL" вместо "Анонимный". URL можно просто не указывать.

Ваше сообщение может быть помечено как спам спам-фильтром - не волнуйтесь, оно появится после проверки администратором.