Студопедия

КАТЕГОРИИ:

АстрономияБиологияГеографияДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРиторикаСоциологияСпортСтроительствоТехнологияФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника


Синхронная посылка сообщений




Синхронная посылка выполняется с помощью функции:

 

LRESULT SendMessage( // Синхронная посылка окну или нити

HWND hWnd, // хэндл окна-приемника

UINT Msg, // тип сообщения

WPARAM wParam, // первый параметр сообщения

LPARAM lParam // второй параметр сообщения

);

Принципиальное отличие от асинхронной посылки заключается в том, что нить, пославшая сообщение, не возобновляет свою работу до тех пор, пока не будет получено подтверждение окончания обработки сообщения. Кроме того, при обработке некоторых типов сообщений программа может выдавать определенные данные в качестве ответа на сообщение. Для передачи ответа может использоваться либо результат, возвращаемый функцией SendMessage, либо содержимое области памяти, адресуемой одним из параметров сообщения. Выше отмечалось, например, что в ответ на WM_GETMINMAXINFO программа может сообщить системе допустимые размеры окна, а результат обработки WM_MOUSEACTIVATE определяет, должна ли система активизировать окно. Разумеется, при асинхронной посылке отправитель не может получить достоверный ответ, поскольку не ждет окончания обработки.

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

Если посылается сообщение окну другой нити или другого процесса, то синхронное сообщение, как было описано выше, ставится в очередь «вне очереди» и посылается оконной функции, как только это становится возможным. Работа нити-отправителя блокируется до наступления одного из двух событий:

· выполнение вызванной оконной функции завершается;

· оконная функция вызывает функцию ReplyMessage (означающую примерно следующее: «Пусть я еще не все сделала, но с оставшейся работой справлюсь сама, не стойте над душой»).

Забавно отметить, что пока нить-отправитель ждет завершения обработки сообщения, ее собственные оконные функции могут быть вызваны для выполнения синхронной обработки сообщений от других процессов и нитей.

Что касается оконных функций, выполняющих обработку синхронных сообщений, следует отметить действующие ограничения на вызовы системных функций. Запрещено (по крайней мере, до вызова ReplyMessage) вызывать любые функции, которые могут вызвать переключение системы на выполнение другой нити. К таким функциям относятся, в частности, GetMessage, PeekMessage, WaitMessage, Yield, Sleep, SleepEx, WaitForSingleObject, WaitForMultipleObjects, а также функции, вызывающие запуск либо завершение процесса или нити.

Однако каким образом оконная функция может узнать, какого рода сообщение, синхронное или асинхронное, она обрабатывает? Для этого служит системная функция InSendMessage, которая возвращает значение TRUE, если обрабатываемое сообщение было послано синхронно (причем послано не той нитью, которой принадлежит окно) и функция ReplyMessage еще не вызывалась.

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

Функция SendNotifyMessage представляет собой нечто среднее между синхронной и асинхронной посылкой. Посланные сообщения, как и для SendMessage, обрабатываются до сообщений из очереди, но нить-отправитель, как при PostMessage, не ожидает ответа.

Функция SendMessageTimeout аналогична SendMessage, однако ожидает ответа лишь в пределах указанного интервала времени.

Функция SendMessageCallback задает адрес функции, которая должна быть вызвана после окончания обработки посланного сообщения, при этом функция не ожидает немедленного ответа на сообщение.

2.2 Программа Spy++

Microsoft Spy++ – это программа, позволяющая получить в наглядном виде информацию о всех процессах в системе, нитях процессов (threads) и окнах, а также дающая возможность отслеживать поток сообщений. Spy++ входит в стандартную поставку пакета Microsoft Visual Studio.

Следует иметь в виду, что программа Spy++ существует как в 32-разрядной версии (spyxx.exe), так и в 64-разрядной (spyxx_amd64.exe). Используемая версия должна соответствовать версии операционной системы Windows, в противном случае программа хотя и будет запускаться, но поток сообщений отслеживаться не будет.

В 32-разрядной Windows вместо Spy++ можно также использовать программу WinSight32, поставлявшуюся ранее с продуктами фирмы Borland/Inprise, или свободно распространяемые программы Winspector, Window Detective, возможности которых даже шире, чем у Spy++. К сожалению, эти программы пока не имеют 64-разрядных версий.

Ниже будет описана работа с программой Spy++ версии 9.00.

Интерфейс Spy++ достаточно прост и понятен. Меню Spy позволяет открыть новое окно для просмотра потока сообщений (Log Messages), списка существующих окон (Windows), списка процессов (Processes) или нитей (Threads). В каждом окне можно выделить объект для дальнейшей работы. Можно также открыть несколько окон одного типа, например, для отслеживания сообщений, адресованных разным окнам. Mеню Window позволяет переключаться между открытыми окнами.

Для выполнения данной работы наиболее ценной возможностью является просмотр (протоколирование) сообщений. Имеется несколько способов настройки просмотра на нужные сообщения. При выполнении команды Spy+Log Messages открывается сначала диалог Message Options, позволяющий указать, для каких окон следует отслеживать сообщения, какие именно сообщения и куда записывать протокол. На вкладке Windows пользователь может выбрать конкретное окно на экране, оттащив на него значок Finder Tool. Разумеется, для этого окно должно быть видимо.

Если окно выделено в списке окон и при этом является видимым, то можно найти его на экране с помощью команды контекстного меню Highlight. Граница окна будет мерцать в течение нескольких секунд.

Свойства выделенного объекта отображаются по команде View+Properties. Состав отображаемых свойств зависит от типа выбранного объекта.

Для процесса отображаются имя модуля (т.е. выполняемого файла), идентификатор процесса, его базовый приоритет и число нитей, а также статистика времени, затраченного процессом, и показатели использования процессом виртуальной и физической памяти.

Для нити отображаются имя модуля, идентификаторы процесса и нити, базовый приоритет процесса и текущий приоритет нити, текущее состояние нити, статистика затраченного времени. Можно перейти к отображению свойств процесса, щелкнув на его идентификаторе.

Для окна отображается большое количество информации о его размерах, заголовке, стилях, классе, родительском окне, первом из дочерних окон, «братских» окнах, окне-владельце, а также о процессе и нити, которым принадлежит окно.

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

Для каждого отслеженного сообщения программа показывает его порядковый номер в протоколе, хэндл окна-получателя, способ посылки, тип сообщения и, если этот тип известен программе, содержательный смысл параметров wParam и lParam. Для неизвестных программе сообщений (к которым относятся сообщения, определенные не в системе Windows, а в конкретной прикладной программе, а также, возможно, сообщения, добавленные в новых версиях Windows и пока еще неизвестные Spy++) указываются только wParam и lParam, без расшифровки. Способ посылки обозначается буквой: P – асинхронная посылка, S – синхронная посылка, R – ответ оконной функции на синхронную посылку. В ходе обработки одного синхронного сообщения (между сообщениями S и R) могут посылаться и обрабатываться другие сообщения.

Меню Windows позволяет переключаться между ранее открытыми окнами. Меню Tree дает возможность изменять глубину вложения при отображении списков окон (показывать ли дочерние окна), процессов (показывать ли нити процесса) и нитей (показывать ли окна каждой нити).

Меню Message активно, только когда отображается поток сообщений. Команда Message+Logging Options дает возможность выбрать, для каких окон следует отслеживать сообщения, какие именно сообщения и куда записывать протокол. На вкладке Windows пользователь может выбрать конкретное окно с помощью Finder Tool. (Другой способ выбрать окно – выделить его в списке окон и выполнить команду контекстного меню Messages.) Можно также добавить отображение сообщений для родительского окна, для дочерних окон, для всех окон той же нити или того же процесса либо для всех окон в системе.

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

На вкладке Messages выбираются типы сообщений, которые нужно отслеживать. Можно включить или отключить целые группы сообщений (например, сообщения от клавиатуры или от командных кнопок) либо выбрать нужные сообщения из полного списка. На вкладке Output пользователь может изменить формат и максимальное количество отображаемых сообщений.

Команды Messages+Start Logging и Messages+Stop Logging включают и выключают протоколирование сообщений. Чтобы сделать это поскорее (и тем самым сократить число ненужных сообщений), можно воспользоваться значком «светофора» в панели инструментов или клавишей F8. Команда Messages+Clear удаляет из окна все сообщения.

Для вывода копии протокола в файл можно использовать команду Messages+Save Log to File.

Команда контекстного меню Refresh обновляет содержимое текущего окна. Это может понадобиться, если состав отображаемых объектов изменился (например, были закрыты некоторые окна или открыты новые).

Замечание. В некоторых случаях Spy++ конфликтует с антивирусными программами. Если выдается ошибка “Spy++ has encountered a problem in the message hook” или Spy++ прекращает работу, есть смысл временно отключить антивирус.


Поделиться:

Дата добавления: 2015-09-15; просмотров: 101; Мы поможем в написании вашей работы!; Нарушение авторских прав





lektsii.com - Лекции.Ком - 2014-2024 год. (0.005 сек.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав
Главная страница Случайная страница Контакты