2011-12-26 2 views
3

Что такое «очередь ввода потоков»? Я видел, как он упоминался в MSDN несколько раз, и может перестать задаваться вопросом, просто ли это очередь сообщений для окна, созданная потоком, который они имеют в виду, или что-то еще.Текущая очередь ввода

Пример:

WH_MOUSE_LL крючок позволяет контролировать входные мыши события о быть размещены во входной очереди в нити.

+0

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

+0

@UweKeim, Это примерно означает, что, когда я бываю. Щелкните левой кнопкой мыши на мыши, событие сначала добавляется в очередь ввода потока. Как только он будет удален, и что он должен сделать, он создаст сообщение 'WM_LBUTTONDBLCLK' и запустит его в очереди сообщений определенного окна? - Итак, в общем, для того, чтобы вставить событие мыши, сначала нужно пройти очередь ввода потока, и это логика - или я все не так? – ebb

+0

Да, вот как я это представляю себе в голове. Я не совсем понимаю, как здесь «нить» и «окно» отличаются, но я уверен, что кто-то опубликует гораздо более подробный ответ :-) –

ответ

2

Во-первых, обратите внимание, что окна не имеют отдельных очередей сообщений; сообщения для окна помещаются в очередь сообщений связанного потока.

According to MSDN, вводные сообщения клавиатуры и мыши отправляются в очередь сообщений потока, связанного с соответствующим окном. Поэтому я считаю, что «очередь ввода потоков» - это просто еще один способ сказать «очередь сообщений потока».

EDIT: Раймонд указал (см. Комментарии), что ввод может быть перенаправлен в очередь сообщений другого потока, используя функцию AttachThreadInput. Таким образом, «очередь ввода потоков» означает, что очередь сообщений принимает вход для данного потока; по умолчанию это очередь сообщений одного потока, но это может быть очередь сообщений для другого потока.

+2

Каждый поток имеет очередь сообщений. Каждый поток * group * имеет входную очередь. –

+0

@RaymondChen, любая документация где-то, что объясняет это? – ebb

+1

Для 16-битного представления см. «GetMessage и PeekMessage Internals» Боба Гандерсона. В Win16 существует единая общесистемная входная очередь, но в Win32 каждая группа потоков имеет свою собственную очередь ввода. (Группы темы создаются функцией AttachThreadInput. Вы задавались вопросом, для чего эта функция была, да?) См. Также «Пять вещей, которые должен знать каждый программист Win32». –

0

Реальный ответ немного сложнее, чем логические абстракции offered by the MSDN. Я могу ответить более подробно, чем то, что было подтверждено в комментариях принятого ответа.

Да, есть два набора сообщений. Существует «очередь сообщений» и «очередь входных сообщений». Последний содержит список необработанных событий сообщения мыши и клавиатуры. Первые содержат опубликованные и синтезированные сообщения.

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

Они также взаимозаменяемо называются «очередь приложений» и «системная очередь» соответственно.

GetMessage() обрабатывает их отдельно.

THREADINFO содержит указатель непосредственно на список сообщений/очередь. Это сканируется, если установлено QS_POSTMESSAGE.

Если либо очереди статуи QS_INPUT или QS_EVENT установлены, список ввода/очередь сканирования пути получения начального указателя на структуру очереди из THREADINFO, а затем указателя на входной список из этой структуры очереди. Странно, я знаю.

Если флаг Статус QS_TIMER очереди установлен, GetMessage() (или PeekMessage()) будет на самом деле должны запустить из сканирования полного списка таймера неядрового найти самый ранний таймер с оповещена статусом, который «принадлежит» к тому, кто называется GetMessage(). Очереди на самом деле не хранят ничего о том, какой таймер был запущен. Они содержат только связанную информацию, которую они хранят, - это флаг QS_TIMER и подсчет количества срабатывающих таймеров (так что GetMessage() знает, когда нужно очистить статус очереди QS_TIMER после того, как он синтезировал сообщение для последнего доступного таймера.)

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

Смежные вопросы