Почему 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
. Когда вы выходите из программы, она получает сообщение о закрытии, как если бы вы нажали кнопку закрытия.
При редактировании команда выхода (также File → Exit
) не имеет ничего общего с Windows. Это встроенная функция самой программы DOS. Поэтому, когда вы нажимаете кнопку закрытия, это совсем не то, что выход из режима редактирования, поэтому нажатие ☒
не сообщает программе о закрытии.
Разные результаты
Но почему Кевин получает другой результат от других (и меня)? Вероятно, это связано с разницей в тайм-ауте, который Windows настроил для своих подпрограмм, определяющих, когда программа «зависла». На самом деле есть несколько различных настроек, которые влияют на это. Изменение настроек приведет к тому, что Windows будет ждать больше или меньше времени, прежде чем появится диалоговое окно.
Я собирался перечислить их все, но, отыскивая их, я в конечном итоге нашел сообщение, которое я сделал недавно, в котором уже перечислены все их, поэтому, если кто-то заинтересован в деталях, вы можете найти их там.