Почему edit.com может быть успешно завершен, нажав Файл → Выход, но не нажав кнопку закрытия ☒? Почему кнопка закрытия вызывает запрос убить его?
TL; DR
Поскольку Edit - это программа для DOS, поэтому File → Exit не имеет ничего общего с Windows или ☒
кнопкой.
Подсистемы
В Windows есть две основные подсистемы («рамки», если хотите), которые программа может использовать, чтобы упростить задачу и избежать того, чтобы программисту приходилось делать все вручную и заново изобретать колесо. Существует стандартная подсистема Windows и консольная подсистема.
Программы Windows - это программы с графическим интерфейсом (GUI), в то время как консольные программы - это программы с интерфейсом командной строки. Это очень разные дизайны, и то, что работает для одного, не работает для другого.
Подсистема Windows
Подсистема windows является более распространенной, и программы, которые имеют графические окна и элементы управления, будут использовать ее. «Сердцем» программы является цикл сообщений Windows . После того, как программа инициализирована и подготовлена к запуску, она войдет в бесконечный цикл, где бездействует, терпеливо ожидая, что что-то произойдет. Это может включать ввод от пользователя, отключение таймера, сетевую активность и т. Д. Когда Windows обнаруживает некоторые изменения, на которые программа должна или может захотеть ответить, она отправит этой программе сообщения . В этот момент, если сообщение о чем-то, в чем заинтересована программа, оно ответит на него обработчиком, который является просто функцией, которая что-то делает.
(Так же работает большинство игр. У них будет основной игровой цикл, который ожидает ввода от кнопок геймпада, таймеров и т. Д., Затем он обновляет игровой мир, отображает фрейм, выводит его на экран и начинает заново. .)
Зависшие программы
Обычно, когда программа получает сообщение, она либо обрабатывает его, либо передает его. Обычно это происходит быстро. Однако иногда программа может зависнуть по какой-то причине, что приведет к тому, что она не будет обрабатывать сообщения. Windows может определить, когда это происходит, и если это займет слишком много времени, она сочтет программу замороженной и предложит пользователю убить не отвечающую программу вместо того, чтобы позволить ее корректно завершить работу. Это означает, что он внезапно завершится и не только потеряет несохраненные файлы, но потенциально оставит открытые файлы в несогласованном состоянии, что приведет к их повреждению.
Консольная подсистема
Консольные программы отличаются от графических программ Windows. Они произошли от своих предков DOS, и хотя они получили много новой функциональности из командной строки Windows, под всем этим они функционируют во многом как старые программы DOS, включая то, как они запускаются, работают и закрываются.
Закрытие программы
Давайте рассмотрим, что происходит, когда вы нажимаете ☒
кнопку для обоих видов программ.
Закрытие программы Windows
Когда вы нажимаете ☒
кнопку программы Windows, Windows отправляет этой программе WM_CLOSE
сообщение. Цикл программы обнаруживает сообщение и отвечает, вызывая функцию, которая проходит стандартную процедуру завершения программы Windows (надеюсь, после первой очистки, такой как освобождение выделенных ресурсов, сохранение файлов и т. Д.). Помимо любой работы по очистке, фактическая маршрутизация при отключении происходит довольно быстро, и Windows переходит к следующей задаче.
Закрытие консольной программы
Когда вы нажимаете ☒
кнопку командной строки, вы предлагаете командной строке закрыть. Когда он получает это сообщение, он пытается закрыться, и если вы бездействуете в приглашении, он, безусловно, может сделать это без особых колебаний. Но что произойдет, если у вас есть какая-то программа, открытая и работающая в командной строке? Эта программа является отдельным процессом в целом. Командная строка не может просто убить эту программу, которая не будет удобной для пользователя и может повредить данные или потерять несохраненные файлы. Вместо этого он пытается передать закрытое сообщение программе. Есть два сценария, которые могут разыграться на этом этапе:
Если программа является консольной программой Windows, то отправка сообщения о закрытии обычно работает немедленно, поскольку она была скомпилирована с помощью консольной подсистемы Windows, и, хотя вы можете потерять некоторые несохраненные файлы, поскольку она использует специфичный для Windows консольный код, существует без задержки, и поэтому Windows не нужно прибегать к его уничтожению.
Если программа является программой для DOS (например, Edit), то она была скомпилирована для запуска в DOS и, таким образом, ничего не знает о Windows и поэтому не отвечает, поэтому Windows думает, что она зависла, и предлагает убить программу.
Файл → Выход
В Windows-программе команда выхода (обычно File → Exit
) является просто псевдонимом для WM_CLOSE
. Когда вы выходите из программы, она получает сообщение о закрытии, как если бы вы нажали кнопку закрытия.
С Edit, команда выхода (также File → Exit
) не имеет ничего общего с Windows. Это встроенная функция самой программы DOS. Поэтому, когда вы нажимаете кнопку закрытия, это совсем не то, что выход из режима редактирования, поэтому нажатие ☒
не сообщает программе о закрытии.
Разные результаты
Но почему Кевин получает другой результат от других (и меня)? Вероятно, это связано с разницей в тайм-ауте, который Windows настроил для своих подпрограмм, определяющих, когда программа «зависла». На самом деле есть несколько различных настроек, которые влияют на это. Изменение настроек приведет к тому, что Windows будет ждать больше или меньше времени, прежде чем появится диалоговое окно.
Я буду перечислять их все, но, глядя их, я в конечном итоге найти в пост, что я сделал некоторое время назад, что уже перечислил их всех, так что если кто - либо заинтересован в деталях, вы можете найти их там.