Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка по курс_Windows.doc
Скачиваний:
11
Добавлен:
22.04.2019
Размер:
1.02 Mб
Скачать

5 Операции с окнами

5.1 Оконные сообщения

Разрабатывая подсистему управления окнами в Windows 2000 и Windows 98, Microsoft преследовала две основные цели:

  • обратная совместимость с 16-разрядной Windows, облегчающая перенос существующих 16-разрядных приложении,

  • отказоустойчивость подсистемы управления окнами, чтобы ни один поток не мог нарушить работу других потоков в системе.

К сожалению, эти цели прямо противоречат друг другу. В 16-разрядной Windows передача сообщения в окно всегда осуществляется синхронно отправитель не может продолжить работу, пока окно не обработает полученное сообщение. Обычно так и нужно. Но, если на обработку сообщения потребуется длительное время или если окно «зависнет», выполнение отправителя просто прекратится. А значит, такая операционная система не вправе претендовать на устойчивость к сбоям.

Это противоречие было серьезным вызовом для команды разработчиков из Microsoft. В итоге было выбрано компромиссное решение, отвечающее двум вышеупомянутым целям. Помните о них, читая эту главу, и Вы поймете, почему Microsoft сделала именно такой выбор.

Для начала рассмотрим некоторые базовые принципы. Один процесс в Windows может создать до 10 000 User-объектов различных типов — значков, курсоров, оконных классов, меню таблиц клавиш-акселераторов и тд. Когда поток из какого-либо процесса вызывает функцию, создающую один из этих объектов, последний переходит во владение процесса. Поэтому, если процесс завершается, не уничтожив данный объект явным образом, операционная система делает этo за него. Однако два User объектa (окна и ловушки) принадлежат только создавшему их потоку. И вновь, если поток создает окно или устанавливает ловушку, а потом завершается, операционная система автоматически уничтожает окно или удаляет ловушку.

Этот принцип принадлежности окон и ловушек создавшему их потоку оказывает существенное влияние на механизм функционирования окон поток создавший окно, должен обрабатывать все его сообщения. Поясню данный принцип на примере До пустим, поток создал окно, а затем прекратил работу Тогда его окно уже не получит сообщение WM_DESTROY или WM_NCDESTROY, потому что поток уже завершился и обрабатывать сообщения, посылаемые этому окну, больше некому.

Это также означает, чью каждому потоку, создавшему хотя бы одно окно, система выделяет очередь сообщений, используемую для их диспетчеризации. Чтобы окно в конечном счете получило эти сообщения поток должен иметь собственный цикл выборки сообщений. В этой главе мы детально рассмотрим, что представляют собой очереди сообщений потоков. В частности, я расскажу, как сообщения помещаются в эту очередь и как они извлекаются из нее, а потом обрабатываются.

5.2 Очередь сообщений потока

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

Создавая какой-либо поток, система предполагает, что он не будет иметь отношения к поддержке пользовательского интерфейса. Это позволяет уменьшить объем выделяемых ему системных ресурсов. Но, как только поток обратится к той или иной GUI-функции (например, для проверки очереди сообщений или создания окна), система автоматически выделит ему дополнительные ресурсы, необходимые для выполнения задач, связанных с пользовательским интерфейсом. А если конкретнее, то система создает структуру THREADINFO и сопоставляет ее с этим потоком.

Элементы этой структуры используются, чтобы обмануть поток — заставить его считать, будто он выполняется в среде, принадлежащей только ему. THREADINFO — это внутренняя (недокументированная) структура, идентифицирующая очередь асинхронных сообщений потока (posted-message queue), очередь синхронных сообщений потока (sent-message queue), очередь ответных сообщений (reply-message queue), оче редь виртуального ввода (virtualized input queue) и флаги пробуждения (wakc flags), она также включает ряд других переменных-членов, характеризующих локальное состояние ввода для данного потока.