Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2005.11.13;
Скачать: [xml.tar.bz2];

Вниз

При каких условиях отрабатывает WaitFoInputIdle ?   Найти похожие ветки 

 
ANB ©   (2005-09-08 17:58) [0]

При каких условиях функция WaitFoInputIdle может возращать таймаут (при вызове для чужого процесса) и как сделать (в чужом приложении), чтобы она отрабатывала нормально ?

Ситуация. Нажимаю клавиши через PostMessage. Синхронизируюсь через WaitFoInputIdle. Для всех приложений все нормально отрабатывает. Для одного (наши писали) - ждет указанное количество времени и вертает таймаут. Причем события обрабатываются, приложение не виснет. Приложение на VC, все окна созданы ручками. Создал автоматом - все работает. Скопировал цикл обработки сообщений, процедуру создания окон, процедуру обработки сообщений - ничего не поломалось. А в реальном приложении - не работает.


 
ANB ©   (2005-09-08 18:01) [1]

Очепятка - WaitForInputIdle


 
Игорь Шевченко ©   (2005-09-08 18:03) [2]


> При каких условиях функция WaitFoInputIdle может возращать
> таймаут


Когда вызываемый процесс не выбирает сообщения из очереди в течение указанного времени


 
ANB ©   (2005-09-08 18:07) [3]


> Игорь Шевченко ©   (08.09.05 18:03) [2]
- указанного - это я которое в параметрах пишу ?


 
ANB ©   (2005-09-08 18:10) [4]


> Игорь Шевченко ©   (08.09.05 18:03) [2]
- так оно выбирает. Я шлю WM_CHAR, вижу (визуально), что нажатие отработало, следом у меня идет WaitForInputIdle - мое приложение подвисает и фукнция возвращает таймаут. Читал справку (не один) - там маловато написано. И ничего не понял.


 
Игорь Шевченко ©   (2005-09-08 18:19) [5]

ANB ©   (08.09.05 18:10) [4]

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


 
alpet ©   (2005-09-08 18:28) [6]

ANB ©   (08.09.05 18:10) [4]

Может hProcess не правильное значение получает, или ты CreateProcess используешь?


 
ANB ©   (2005-09-09 09:42) [7]


> Игорь Шевченко ©   (08.09.05 18:19) [5]
- очень жаль. Придется извращаться. А другой способ есть ?


> alpet ©   (08.09.05 18:28) [6]
- не, нормально я все получаю. Для других приложений все работает. Кстати, это же ты мне этот способ предложил. Очень эффективным оказался. При работе с приложениями на Delphi и Magic скорость тестов резко увеличилась и сбоев нет. Спасибо. Кстати, сгенерил пустое приложение на VC и оно нормально отрабатывает.

В чем я вижу проблемы неуправляемого приложения :
1) Используется таймер
2) Не очень шустрая отрисовка
3) Используется 2 потока, основной - работает с обычным циклом выборки сообщений + процедура обработки. Этот поток пересылает события от клавиатуры в собственный буфер второго потока. Во втором потоке реализован эмулятор терминального приложения. В нем ожидание нажатие клавиши производится циклическим опросом буфера (как в DOS и на старых бытовых компьютерах).
4) У основного потока 2 окна (верхнего уровня и дочернее) и у каждого своя процедура обработки сообщений, при чем логика пересылки клавиш и отрисовка реализованы в дочернем окне. Я перенес цикл обработки сообщений, создание окна и процедуру обработки дочернего окна в пустой проект - все заработало. Естественно, я не создавал доп.поток, заменил отрисовку на свою и вместо записи в буфер клавиш я их рисую на экране.


 
Игорь Шевченко ©   (2005-09-09 09:57) [8]

ANB ©   (09.09.05 09:42) [7]


> - очень жаль. Придется извращаться. А другой способ есть
> ?


Есть. PostMessage


 
ANB ©   (2005-09-09 10:16) [9]


> Игорь Шевченко ©   (09.09.05 09:57) [8]
- дык я им и пользуюсь, alpet посоветовал. А как узнать, что клавиша уже обработана и можно слать следующую ?


 
alpet ©   (2005-09-09 10:52) [10]

ANB ©   (09.09.05 10:16) [9]
Забить в очередь можно довольно много сообщений (например целую строку WM_CHAR), и только потом выжидать (Sleep).

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


 
Игорь Шевченко ©   (2005-09-09 10:58) [11]

ANB ©   (09.09.05 10:16) [9]


> А как узнать, что клавиша уже обработана и можно слать следующую
> ?


А зачем это узнавать ?

Кроме того, можно использовать SendMessageCallback и SendNotifyMessage с гарантированным уведомлением о получении сообщения.


 
ANB ©   (2005-09-09 15:01) [12]


> Игорь Шевченко ©   (09.09.05 10:58) [11]
- я как раз и использую везде SendMessageCallback - очень удобно. Но некоторые приложения таким образом клавиши не понимают, они PostMessage хотят.


> alpet ©   (09.09.05 10:52) [10]
- так нечестно. Сначала сам посоветовал WaitForInputIdle :))) Все так клево работает, а теперь отказываться ?

Вообще то мы хотели починить стороннее приложение (наши же его писали), чтобы WaitForInputIdle работало. Но чего то не выходит. Я пока на них забил и сделал флаг, по которому эмуляция идет через SendMessageCallback. Так работает все, только флаги нужно переключать.


 
Игорь Шевченко ©   (2005-09-09 15:11) [13]


>  Но некоторые приложения таким образом клавиши не понимают,
> они PostMessage хотят.


PostMessage не требует от приложения готовности обработать сообщение.


 
ANB ©   (2005-09-09 15:35) [14]


> Игорь Шевченко ©   (09.09.05 15:11) [13]
- знаю. Просто ставит сообщение в очередь. Но мне нужно знать, когда оно обработалось, так как нужно еще синхронно и вовремя переключать состояние клавиатуры. А иначе все идет в разнобой и буквы сбиваются.


 
Игорь Шевченко ©   (2005-09-09 15:49) [15]

ANB ©   (09.09.05 15:35) [14]

???????????????????????????????????????????? Поясни


 
alpet ©   (2005-09-09 16:12) [16]

ANB ©

Мне так и не удалось получить приложение, которое обрабатывая сообщения, при этом не переходило в Idle состояние детектируемое WaitForInputIdle.


 
alpet ©   (2005-09-09 16:20) [17]

Более того, она (WaitForInputIdle) после извлечения первого сообщения вообще получается не ждет пока подопытный процесс (точнее его поток) обработает отправленные сообщения, тем более по части клавиатуры. Поэтому ее применение в данном случае вообще оказывается бессмысленным - она не играет роли при синхронизации, не смотря что внешне это выглядит именно так. Не правильный (хоть и визуально действенный) был совет с моей стороны ее использовать.


 
ANB ©   (2005-09-09 16:20) [18]


> 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 оказалось быстрее и надежнее.


 
Игорь Шевченко ©   (2005-09-09 16:23) [19]

ANB ©   (09.09.05 16:20) [18]

А WM_CHAR послать ?


 
ANB ©   (2005-09-09 16:25) [20]


> alpet ©   (09.09.05 16:20) [17]
- да нет, с ней стало все нормально, даже без слипов. Я шлю клавишу, поток в программе (с которой были проблемы) - один. На время обработки клавиши она подвисает и когда отрабатывает WaitForInputIdle программа уже готова принимать следующую кнопку. Самый прикол - на слипах паузы, как правило, великоваты, но иногда их не хватало. А по твоему совету все работает шустро (без лишних задержек) и надежно. А после каждой команды я все равно паузу делаю, а то проц перегружается.


 
ANB ©   (2005-09-09 16:28) [21]


> Игорь Шевченко ©   (09.09.05 16:23) [19]
- не жрет. Для обычных букв обрабатывается именно WM_CHAR, правда заодно WM_DOWN и WM_UP (пробовал посылать по очереди - печатается 3 символа), а для комбинаций - только WM_DOWN. Правда я на всякий случай все равно кнопки отпускаю. Давай я выложу получившиеся функции, а вы их покритикуете.


 
alpet ©   (2005-09-09 16:41) [22]

ANB ©   (09.09.05 16:25) [20]
А мои эксперименты показывают, что никакого ожидания не происходит, не зависимо от того, каким способом поток извлекает из очереди сообщения. Единственный раз ожидание производится когда еще не начат цикл обработки сообщений. Это все как ни странно соответсвует описанию функции в MSDN. Если хочешь попробывать - замеряй сколько функция реально ожидает, с помощью GetTickCount -  у меня все кроме первого значения равны нулю. Так что это недостоверный способ проверять дошло ли сообщение.


 
alpet ©   (2005-09-09 16:43) [23]

Вобщем имхо достоверным и быстрым способом будет только использование ловушек (можно использовать так же WH_CALLWNDPROCRET), с установкой флага размещеного в MMF.


 
ANB ©   (2005-09-09 16:48) [24]


> alpet ©   (09.09.05 16:43) [23]
- ловушка сработает во время выборки сообщения из очереди. А когда оно обработается - не определить.


 
ANB ©   (2005-09-09 16:50) [25]


> alpet ©   (09.09.05 16:43) [23]
- почитал справку. Ты прав. Но. Эта ловушка - для SendMessage, а при ее использовании и так все нормально работает. А PostMessage эта ловушка ловить не будет.


 
alpet ©   (2005-09-09 16:58) [26]

ANB ©   (09.09.05 16:50) [25]

Да уж, все в какие-то сложности упирается. Можно сабклассировать злостное окно - но для этого придется внедрять DLL. Но это вроде как самый простой способ.


 
ANB ©   (2005-09-09 17:20) [27]


> alpet ©   (09.09.05 16:58) [26]
- как раз для этого окна я сделал ветку в функции и теперь оно замечательно через SendMessage работает. Я вот думаю - не наступлю я на грабли с PostMessage + WaitForInputIdle. А хрен с ним, наступлю - буду править. Ожидание в отдельной функции, весь код править не придется. И все таки интересно - убираю Wait, все ломается, ставлю - все работает . . .


 
homm ©   (2005-09-10 05:31) [28]

ANB, все имхо на много проще. Посылаеш свой WM_CHAR, или чего там у тебя Через PostMessage, а кагда надо изменить состояние клавиатуры, шлеш SendMessageCallback с сообщением WM_USER+$XX.
Правда есть вероятность что WM_USER+$XX уже забито самимприложением, тогда появятся побочные эффекты. Надо правильно подобрать его. А может есть чтото вроде WM_NULL, специально для такого рода афер, но такого что-то не помню.


 
ANB ©   (2005-09-12 09:20) [29]


> homm ©   (10.09.05 05:31) [28]
- чего то я перелистал Рихтера, сильно не понял, но вроде как там написано, что сообщение, посланное SendMessage может обработаться раньше, чем посланное PostMessage. Или я не прав ?


 
Игорь Шевченко ©   (2005-09-12 10:59) [30]


> там написано, что сообщение, посланное SendMessage может
> обработаться раньше, чем посланное PostMessage


Конечно может


 
ANB ©   (2005-09-12 11:31) [31]


> Игорь Шевченко ©   (12.09.05 10:59) [30]
- тогда предложение homm ©   (10.09.05 05:31) [28] не рабочее. И что, только Sleep меня спасет ?


 
alpet ©   (2005-09-12 16:52) [32]

ANB ©   (12.09.05 11:31) [31]
Теоретически может не помочь и Sleep. Попробуй все-таки подумать в сторону сабклассирования окна, которого ты сообщениями кормишь. Детектировать обработку сообщения при этом станет намного проще.


 
ANB ©   (2005-09-12 17:36) [33]


> alpet ©   (12.09.05 16:52) [32]
- это внедряться придеться ?


 
alpet ©   (2005-09-13 10:12) [34]

ANB ©   (12.09.05 17:36) [33]

Ну да. Самое простое - внедрить DLL с помощью ловушек (у Рихтера есть пример), найти злополучное окно, запомнить его старую оконную процедуру, и заместить ее своей. Потом при каждом вызове твоей оконной процедуры (и соответственно вызове из нее старой), можно будет устанавливать флажок в MMF, дескать сообщение получено и обработано.


 
ANB ©   (2005-09-13 14:28) [35]


> alpet ©   (13.09.05 10:12) [34]
- вот блин. Не хотел я делать внедрение. Приложение больно дурацкое, его и само по себе иногда конкретно клинит. Видимо придется, но попозже.
Я для делфи придумал клевую штуку - подкладываю в тестируемом приложении вместо TForm свой базовый класс и работаю спокойно изнутри через сообщения. Становиться доступно все, что можно вытащить через RTTI и некоторые нужные вещи, которые я зашил в код жестко.

Кстати, а для PostMessage облом мне будет с внедрением. Для SendMessageCallback есть специальная метка dwData, по которой я могу отличать сообщения. А у PostMessage такой метки нету. :(((


 
alpet ©   (2005-09-13 15:16) [36]

ANB ©   (13.09.05 14:28) [35]
Думаю облом будет незначительный, поскольку сообщения WM_CHAR могут приходить либо от клавиатуры (точнее TranslateMessage), либо от твоей проги, и очень это будет по времени пересекаться редко. Важнее продумать как будет осуществляться реальная синхронизация. Мое предложение такое - твоя программа отправляет в подопытную сообщение, и несколько миллисекунд ждет установки некоторого event.  Факт установки события свидетельствует о том что сообщение обработалось. Само событие устанавливается из новой оконной процедуры.


 
ANB ©   (2005-09-13 15:51) [37]


> alpet ©   (13.09.05 15:16) [36]
- вообще то можно и так. Но я ID для CallBack не просто так заводил. Слал сообщения, а они обрабатывались не в том порядке. Пришлось пометить их ID. Сообщения от клавиатуры я никак не откину, но согласиь, было бы глупо пытаться жать кнопки во время прогона теста. Надо заняться. Пошел я искать, куда я Рихтера засунул.


 
alpet ©   (2005-09-13 16:40) [38]

ANB ©   (13.09.05 15:51) [37]
Можно и откинуть, только смысла имхо нету.



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2005.11.13;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.56 MB
Время: 0.039 c
8-1119478025
Strech
2005-06-23 02:07
2005.11.13
масштабирование изображений


2-1129991572
MakedoneZ
2005-10-22 18:32
2005.11.13
Изменение типа указателя.


1-1130156823
Its2L8
2005-10-24 16:27
2005.11.13
Автоматическая сборка проекта


4-1124876130
Scordion
2005-08-24 13:35
2005.11.13
Как сделать форму поверх всех приложений?


3-1127800437
XGarik
2005-09-27 09:53
2005.11.13
Обращение к полю XML





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский