WaitForInputIdle работает, но не так, как вы предполагаете. Это в значительной степени связано с тем, что документация вводит в заблуждение (или, по крайней мере, не так явно, как она должна быть):
Ожидает, что указанный процесс завершит обработку своего исходного ввода и ожидает ввода пользователем с нет ожидающего ввода или до истечения интервала времени ожидания.
blockquote>Это почти уголовно неточно. В разделе Примечания отмечается, что
WaitForInputIdle
ждет не более одного раза за процесс, он никогда не упоминает важные детали. В частности:
WaitForInputIdle
возвращает, как только начальный запуск переместился в точку, где любой поток процесса готов к обработке сообщений. Эти сообщения не обязательно должны вводиться пользователем.WaitForInputIdle
был изобретен, чтобы позволить процессу связываться с дочерним процессом с использованием протокола на основе сообщений. В качестве конкретного сценария использовался DDE , который больше не используется 1).
WaitForInputIdle
не может использоваться как надежное решение вашей проблемы: Ожидание ребенка процесса ". Вам действительно нужно дождаться появления пользовательского интерфейса.Система предлагает два решения, которые вы можете использовать:
- Глобальный CBT hook и дождитесь обратного вызова
HCBT_CREATEWND
. Вы можете проверить член CREATESTRUCT lpszClass и / или lpszName , чтобы отфильтровать интересующее вас окно.- Используйте WinEvents и ответьте на событие
EVENT_OBJECT_CREATE
.Вызывается глобальный крючок CBT, когда окно приближается к быть создан. Структуры ядра, в которых ссылки
HWND
были полностью заполнены, но клиентский вызовCreateWindow[Ex]
может по-прежнему прекращать создание окна. В отличие от этого, WinEvent выдается после того, как окно полностью построено и готово к взаимодействию.В общем, решение, основанное на крюке CBT, используется, когда приложение должно обновлять некоторые аспекты окна перед тем, как вызывающий абонент
CreateWindowEx
впервые увидитHWND
. WinEvents, как правило, являются инструментом выбора при реализации решений для обеспечения доступности или автоматизации пользовательского интерфейса.Дополнительные ресурсы:
- WaitForInputIdle действительно нужно называть WaitForProcessStartupComplete
- WaitForInputIdle ждет какой-либо поток, который, возможно, не является тем типом, который вам интересен
1) Да, я знаю , некоторые приложения могут использовать DDE. Но если Раймонд Чен предложил в 2007 году, что мы должны перестать использовать DDE , я просто передам это как авторитетное руководство.
Вот простое решение вашей проблемы. Я оставлю это вам, чтобы изменить и сделать так, чтобы он выглядел и работал именно так, как вы хотите:)
Изучение языка kv НЕВЕРОЯТНО полезно, легко и его можно довольно быстро освоить.
main.py
from kivy.app import App
class MainApp(App):
alphabet = 'abcdefghijklmnopqrstuvwxyz'
def next_letter(self):
# Get a reference to the widget that shows the letters
# self.root refers to the root widget of the kv file -- in this case,
# the GridLayout
current_letter_widget = self.root.ids['the_letter_label']
# Get the letter currently shown
current_letter = current_letter_widget.text
# Find the next letter in the alphabet
next_letter_index = self.alphabet.find(current_letter) + 1
next_letter = self.alphabet[next_letter_index]
# Set the new letter in the widget that shows the letters
current_letter_widget.text = next_letter
MainApp().run()
main.kv
GridLayout: # This is the `root` widget of the main app class
cols: 1
Label:
text: "g"
id: the_letter_label # Setting an id for a widget lets you refer to it later
Button:
text: "Previous"
Button:
text: "Next"
on_release:
# the keyword `app` references the main app class, so we can call
# the `next_letter` function
app.next_letter()
Я с удовольствием отвечу на конкретные вопросы, если они у вас есть.