![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
При каких условиях отрабатывает WaitFoInputIdle ? [WinXP]
ANB © (2005-09-08 17:58:00)При каких условиях функция WaitFoInputIdle может возращать таймаут (при вызове для чужого процесса) и как сделать (в чужом приложении), чтобы она отрабатывала нормально ?
Ситуация. Нажимаю клавиши через PostMessage. Синхронизируюсь через WaitFoInputIdle. Для всех приложений все нормально отрабатывает. Для одного (наши писали) - ждет указанное количество времени и вертает таймаут. Причем события обрабатываются, приложение не виснет. Приложение на VC, все окна созданы ручками. Создал автоматом - все работает. Скопировал цикл обработки сообщений, процедуру создания окон, процедуру обработки сообщений - ничего не поломалось. А в реальном приложении - не работает.
ANB (2005-09-09 16:20:00) [21]
> alpet © (09.09.05 16:12) [16]
- мне тоже !!! Я по всякому пытался изгаляться, все равно нормально работает. Прямо копировал куски из "неправильного"
> Игорь Шевченко © (09.09.05 15:49) [15]
- Мне нужно комбинировать SetKeyboardState и PostMessage. Иначе ничего не кушается, так как управляемая программа проверяет состояние клавиатуры. Например : мне нужно нажать Ctrl+L. Чтобы это сработало я посылаю WM_DOWN VK_CONTROL, устнавливаю флаг, что Ctrl нажата, затем шлю WM_DOWN VK_L. Тогда работает. Но если не подождать, пока обработается VK_CONTROL, ничего не получается. Можно просто слипом, но через WaitForInputIdle оказалось быстрее и надежнее.
alpet (2005-09-09 16:20:00) [22]Более того, она (WaitForInputIdle) после извлечения первого сообщения вообще получается не ждет пока подопытный процесс (точнее его поток) обработает отправленные сообщения, тем более по части клавиатуры. Поэтому ее применение в данном случае вообще оказывается бессмысленным - она не играет роли при синхронизации, не смотря что внешне это выглядит именно так. Не правильный (хоть и визуально действенный) был совет с моей стороны ее использовать.
alpet (2005-09-09 16:12:00) [23]ANB ©
Мне так и не удалось получить приложение, которое обрабатывая сообщения, при этом не переходило в Idle состояние детектируемое WaitForInputIdle.
Игорь Шевченко (2005-09-09 15:49:00) [24]ANB © (09.09.05 15:35) [14]
???????????????????????????????????????????? Поясни
ANB (2005-09-09 15:35:00) [25]
> Игорь Шевченко © (09.09.05 15:11) [13]
- знаю. Просто ставит сообщение в очередь. Но мне нужно знать, когда оно обработалось, так как нужно еще синхронно и вовремя переключать состояние клавиатуры. А иначе все идет в разнобой и буквы сбиваются.
Игорь Шевченко (2005-09-09 15:11:00) [26]
> Но некоторые приложения таким образом клавиши не понимают,
> они PostMessage хотят.
PostMessage не требует от приложения готовности обработать сообщение.
ANB (2005-09-09 15:01:00) [27]
> Игорь Шевченко © (09.09.05 10:58) [11]
- я как раз и использую везде SendMessageCallback - очень удобно. Но некоторые приложения таким образом клавиши не понимают, они PostMessage хотят.
> alpet © (09.09.05 10:52) [10]
- так нечестно. Сначала сам посоветовал WaitForInputIdle :))) Все так клево работает, а теперь отказываться ?
Вообще то мы хотели починить стороннее приложение (наши же его писали), чтобы WaitForInputIdle работало. Но чего то не выходит. Я пока на них забил и сделал флаг, по которому эмуляция идет через SendMessageCallback. Так работает все, только флаги нужно переключать.
Игорь Шевченко (2005-09-09 10:58:00) [28]ANB © (09.09.05 10:16) [9]
> А как узнать, что клавиша уже обработана и можно слать следующую
> ?
А зачем это узнавать ?
Кроме того, можно использовать SendMessageCallback и SendNotifyMessage с гарантированным уведомлением о получении сообщения.
alpet (2005-09-09 10:52:00) [29]ANB © (09.09.05 10:16) [9]
Забить в очередь можно довольно много сообщений (например целую строку WM_CHAR), и только потом выжидать (Sleep).
Второй вариант - использовать ловушку на WH_GETMESSAGE, тогда факт получения твоего сообщения можно будет регистрировать.
ANB (2005-09-09 10:16:00) [30]
> Игорь Шевченко © (09.09.05 09:57) [8]
- дык я им и пользуюсь, alpet посоветовал. А как узнать, что клавиша уже обработана и можно слать следующую ?
Игорь Шевченко (2005-09-09 09:57:00) [31]ANB © (09.09.05 09:42) [7]
> - очень жаль. Придется извращаться. А другой способ есть
> ?
Есть. PostMessage
ANB (2005-09-09 09:42:00) [32]
> Игорь Шевченко © (08.09.05 18:19) [5]
- очень жаль. Придется извращаться. А другой способ есть ?
> alpet © (08.09.05 18:28) [6]
- не, нормально я все получаю. Для других приложений все работает. Кстати, это же ты мне этот способ предложил. Очень эффективным оказался. При работе с приложениями на Delphi и Magic скорость тестов резко увеличилась и сбоев нет. Спасибо. Кстати, сгенерил пустое приложение на VC и оно нормально отрабатывает.
В чем я вижу проблемы неуправляемого приложения :
1) Используется таймер
2) Не очень шустрая отрисовка
3) Используется 2 потока, основной - работает с обычным циклом выборки сообщений + процедура обработки. Этот поток пересылает события от клавиатуры в собственный буфер второго потока. Во втором потоке реализован эмулятор терминального приложения. В нем ожидание нажатие клавиши производится циклическим опросом буфера (как в DOS и на старых бытовых компьютерах).
4) У основного потока 2 окна (верхнего уровня и дочернее) и у каждого своя процедура обработки сообщений, при чем логика пересылки клавиш и отрисовка реализованы в дочернем окне. Я перенес цикл обработки сообщений, создание окна и процедуру обработки дочернего окна в пустой проект - все заработало. Естественно, я не создавал доп.поток, заменил отрисовку на свою и вместо записи в буфер клавиш я их рисую на экране.
alpet (2005-09-08 18:28:00) [33]ANB © (08.09.05 18:10) [4]
Может hProcess не правильное значение получает, или ты CreateProcess используешь?
Игорь Шевченко (2005-09-08 18:19:00) [34]ANB © (08.09.05 18:10) [4]
В справке написано, что WaitForInputIdle служит для определения завершения инициализации созданного процесса. Критерием инициализации служит начало выборки сообщений. WaitForInputIdle не служит признаком готовности процесса принять очередное сообщение.
ANB (2005-09-08 18:10:00) [35]
> Игорь Шевченко © (08.09.05 18:03) [2]
- так оно выбирает. Я шлю WM_CHAR, вижу (визуально), что нажатие отработало, следом у меня идет WaitForInputIdle - мое приложение подвисает и фукнция возвращает таймаут. Читал справку (не один) - там маловато написано. И ничего не понял.
ANB (2005-09-08 18:07:00) [36]
> Игорь Шевченко © (08.09.05 18:03) [2]
- указанного - это я которое в параметрах пишу ?
Игорь Шевченко (2005-09-08 18:03:00) [37]
> При каких условиях функция WaitFoInputIdle может возращать
> таймаут
Когда вызываемый процесс не выбирает сообщения из очереди в течение указанного времени
ANB (2005-09-08 18:01:00) [38]Очепятка - WaitForInputIdle