Цитата:
4. Главные потоки приложений циклически проверяют свой буфер (очередь) сообщений и если там обнаруживается информация о произошедшем событии, то вызывается главный обработчик событий приложения (например, OnMessage объекта Application).
5. Главный обработчик событий приложения сам обрабатывает это событие, затем по очереди вызывает обработчики
DefWindowProc всех графических элементов приложения, находящихся в непосредственном владении приложения, в частности (и обычно) главного окна приложения.
6. Затем свои обработчики DefWindowProc этих подчинённых графических элементов сами обрабатывают событие и по очереди вызывают обработчики DefWindowProc уже своих подчинённых графических элементов (например, кнопки на форме) и т.д.
7. Обработчики DefWindowProc всех графических элементов приложения в зависимости от события и наличия обработчиков этих событий вызывают эти обработчики (код которых и пишут прикладные программисты).
Ну вот, приблизительно всё так, но в то же время и не так...
8)__________________________________________________
Ну, и вопрос по фоновым процессам.
Если обработка очереди сообщения приложения происходит в цикле (т.е. главный поток приложения всё время работает), то потоки фоновых процессов (у которых самый низкий приоритет) вообще не будут выполняться...
|
Не так. Есть одна системная очередь, а так же у каждого потока
своя очередь сообщений (если поток создаёт хотя бы одно окно, то эта очередь автоматически создаётся. По умолчанию её нет) и свой цикл GetMessage/DispatchMessage). Каждый системный (например, окно) объект создаётся в неком потоке, ему он и принадлежит, и все его сообщения идут именно в этот поток.
Затем, никакого "главного" обработчика событий (кроме цикла выборки сообщений из очереди потока) нет. DispatchMessage высылает сообщение сразу соответствующему обработчику. DefWindowProc - это вообще стандартная функция (как ни странно, для реализации поведения окна "по умолчанию"). Из твоего кода она вызывать ничего никогда не будет (но может послать некие события).
Для реализации "красивого" апи окошек C++ Builder делает нечто похожее на следующее. Создаёт свою оконную процедуру, которой будут поступать все сообщения окна. Затем с помощью GetWindowLong получает указатель на объект формы, которой это окно является. Если пришедшее сообщение соответствует некому обработчику (например WM_KEYDOWN -> OnKeyDown), то вызывает соответствующий метод объекта и возвращает 0. Иначе вызывает DefWindowProc для реализации поведения по умолчанию. (
Примерно так. Билдер даже никогда не щупал, но принципиально по другому и не сделаешь).
Цитата:
Если обработка очереди сообщения приложения происходит в цикле (т.е. главный поток приложения всё время работает), то потоки фоновых процессов (у которых самый низкий приоритет) вообще не будут выполняться...
|
Есть такая штука как вытесняющая многозадачность. Как бы поток не хотел что-нибудь делать, когда придёт время - обязательно даст и другим поделать. И даже потоки самых низких приоритетов получают чуточку времени (чем ниже приоритет, тем меньше, логично). Да и в эпоху кооператичной многозадачности первый же вызов некой системной функции приводил к смене потока, если она должна была быть.
Кстати, вот что нашёл:
http://winpro.narod.ru/Messages.htm Достаточно популярное объяснение.