Насколько целесообразно не иметь цикл сообщений в WinMain? - PullRequest
6 голосов
/ 02 июня 2009

Это может быть самая простая программа на Win32 из когда-либо ..

#include <windows.h>

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR cmdLine, int show)
{
    MessageBox(0, "Hello world..", "Salutations!", MB_OK);
    return 0;
}

.. который не делает никаких вызовов обычному вызову GetMessage (). У меня такой вопрос: если моя программа не обрабатывает никаких оконных сообщений, может ли ОС справиться с этим? Т.е. это вызывает утечку памяти? Или какой-то другой ресурс, который не был бы очевиден, если бы я не запускал его 16K раз?

В более широком смысле, насколько именно Win32 зависит от приложений, заботящихся о своих сообщениях? Я надеюсь, что когда компилятор связывает исполняемый файл как программу Windows, среда выполнения сможет очистить любую очередь сообщений, независимо от того, очищена она или нет.

Ответы [ 6 ]

11 голосов
/ 02 июня 2009

Просто технически, но у вас есть окно, и у вас есть цикл сообщений, просто нет в вашем коде.

Вызов MessageBox() создает окно (класса # 32770) и запускает локальный цикл сообщений, не возвращаясь к вашему коду до тех пор, пока цикл сообщений не выпадет, предположительно при отправке WM_NCDESTROY. Я думаю, что это тот же цикл сообщений, который запускается в ответ на DialogBox().

Но вы могли бы заменить ваш звонок на MessageBox() чем-то другим, что действительно не создает цикл сообщений, и у вас все будет хорошо. Windows не заботится о том, есть ли у вас цикл обработки сообщений, хотя некоторые функции (в основном связанные с пользовательским интерфейсом) трудно или невозможно использовать без них. На самом деле вам вообще не нужно ссылаться на user32, а некоторые приложения, не имеющие пользовательского интерфейса, этого не делают.

Теперь, если вы создаете окно и не обрабатываете для него сообщения некоторым способом, Windows XP и выше заменит ваше окно "призрачным" окном с белой клиентской областью и диспетчером задач. скажет пользователю, что приложение не отвечает.

Хотя на первый взгляд кажется, что цикл обработки сообщений не является волшебным или строго обязательным элементом стандартной Windows-системы. Он является высоко укоренившимся в качестве стандарта в большинстве приложений Windows, потому что это лучший способ справиться с отправкой оконных сообщений. «Управляемая событиями» природа большинства приложений Windows заставляет нас иногда забывать, что приложения Windows изначально разрабатывались как однопоточные, и в этой модели это код, выполняющийся в этом единственном потоке, а не какая-то невидимая сила внутри операционной системы, это должно сделать каждый вызов функции в нашем коде. Добавление многопоточности несколько изменило это, но базовая модель все еще остается прежней.

EDIT

Примечание об очередях сообщений:

Как упоминалось в другом месте, очередь сообщений создается (и для каждого потока), только когда окно создано этим потоком. Ваша примерная программа после создания окна сообщения создает очередь сообщений. Но эта очередь не должна быть пустой при выходе из приложения. Эта очередь просто структура памяти. Это блок памяти, который может содержать определенное количество объектов сообщения (с указанием целевого hWnd, идентификатора сообщения, wParam, lParam, системного времени, когда сообщение было отправлено, позиции мыши, когда сообщение было отправлено, и некоторых данных, которые позволяют получить клавиатуру и состояние кнопки мыши, когда сообщение было отправлено), а также указатели на начало и конец очереди (я предполагаю, что это круговая очередь). При выходе из приложения эта память, как и вся память, принадлежащая процессу, освобождается в итоге.

Есть, конечно, и другие вещи, которые должны быть очищены вне вашего процесса. ОС должна вести таблицу всех существующих окон, например, вместе с потоком и процессом, который их создал. Конечно, все они также очищаются автоматически.

4 голосов
/ 02 июня 2009

Поскольку у вас нет окна, вам не нужен цикл сообщений. В Win32 сообщения отправляются в окна, а не в приложения.

3 голосов
/ 02 июня 2009

У вас есть цикл сообщений - MessageBox является модальным диалоговым окном и поэтому содержит цикл сообщений внутри.

2 голосов
/ 02 июня 2009

Вам не нужно создавать окна. Но все же есть сообщения вроде

  • WM_TIMER
  • WM_TIMECHANGE
  • WM_CLIPBOARDUPDATE
  • WM_COPYDATA
  • WM_POWER

что вам может понадобиться. Таким образом, окно призрак , висящее вокруг, не будет плохим.

1 голос
/ 02 июня 2009

Если у вас нет окна, то это нормально, но если у вас есть, то вам нужно убедиться, что вы качаете сообщения для него. В противном случае система может зависнуть на широковещательных сообщениях, ожидающих вашего ответа. Это важно для таких вещей, как COM, которые создают скрытые окна для обработки сообщений. Если ваш основной поток не перекачивает сообщения (например, путем вызова WaitForSingleObject), то вызовы ваших COM-объектов не будут обрабатываться, и любые программы, отправляющие широковещательные сообщения, будут зависать.

0 голосов
/ 02 июня 2009

Я где-то читал (и не могу найти ссылку), что Windows создаст очередь сообщений по требованию. Если вы никогда не вызовете функцию, которая ищет очередь сообщений, она никогда не будет создана. И это происходит для каждого потока.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...