Как задержать выполнение EnumChildWindows до полной инициализации окна?
Методом EnumWindows я перебираю все окна, пока не появится нужное - с определенным заголовком и классом. При нахождении, я собираю все его дочерние окна методом EnumChildWindows.
Проблема: зачастую к моменту сбора дочерних элементов, они еще успевают появиться.
Вопрос: что делать?
Костыль: вставлена задержка в 300 мс.
Проблема с костылем: в числе прочих параметров, я могу ждать окно с конкретным текстом дочерних элементов, который складывается из Titile'ов всех имеющихся. Задержка в 300 мс при таком раскладе подвешивает программу навеки (с учетом того, что будет вызываться также и для каждого дочернего окна, чтобы собрать его дочерние окна).
- В случае рекомендации использовать WaitForInputIdle, пожалуйста, пример использования (с наследниками). Не получилось. от Vitamant, 17 февраля 2012 года
Зачем? Это имеет значение?
Спрашиваю не потому что мне лень, а потому что это достаточно объемный распределенный фрагмент кода, который выдирать из проекта мне будет очень сложно. Я рисую управляемую оболочку над WinAPI. Так что, если интересует что-то более конкретное - пиши, покажу. А весь механизм не хотелось бы...
Если вдруг недостаточно хорошо описал ситуацию, приведу пример:
В системе создается экземпляр окна диалога "Открытие файла". Его хэндл тут же помещается в системный реестр окон, из которого несколькими миллисекундами позже извлекается методом EnumWindows. Сразу же после этого запускается EnumChildWindows по его хэндлу для нахождения контролов, однако само окно еще не успело инциализироваться. Контролы только падают на форму, задаются их координаты, а я уже пытаюсь их посчитать. Мне нужно дождаться момента, когда все они физически появятся в окне. Метод, аналогичный WaitForInputIdle. Почему я помянул последний - потому что он, как я понял, натравливается не на окно, а на поток. И в случае с запуском, например, блокнота, вполне сойдет, чтобы дождаться момента его появления. А вот если главное окно уже существует и создается его дочернее, например все тот же диалог открытия файла, WaitForInputIdle считает, что поток уже готов воспринимать ввод, не обращая внимания на то, что окно еще не инициализировано. Правда, я могу ошибаться, и просто неверно использую WaitForInputIdle. Тогда хотелось бы увидеть пример использования в описанной ситуации.
Я в свое время задачу решил впендюриванием хука на активацию окна. В вашем случае, может, нужен другой хук.
Если хотите выполнять свой код ПОСЛЕ обработки WM_CREATE целевым окном (предполагаем, что именно там создаются дочерние), попробуйте SetWindowsHookEx (WH_CALLWNDPROCRET, ...)
см. http://msdn.microsoft.com/en-us/library/windows/desktop/ms644975(v=vs.85).aspx
1) Если это мой процесс, то я не буду пользоваться WinAPI для создания и перехвата окон.
2) Если это чужое приложение, то инъекция DLL - вещь сложная, ненадежная и не самая лучшая.
P..S. Я нашел решение. Если кому-нибудь будет интересно - пишите в приват. Если коротко - есть WinAPI-функция, определяющая "висит" ли окно.