Подтвердить что ты не робот

Хорошее или злое - API SetParent() win32 между различными процессами

Функция SetParent принимает дочерний элемент и новый родительский дескриптор окна. Это также работает, когда дочернее окно находится в другом процессе Windows.

Я видел сообщение, утверждающее, что это официально не поддерживается, но текущие документы не упоминают об этом больше. Является ли это недостатком в текущих документах или изменилось это поведение?

HWND WINAPI SetParent(
  __in      HWND hWndChild,
  __in_opt  HWND hWndNewParent
);
4b9b3361

Ответ 1

У вас могут быть отношения родитель-потомок с окнами в разных процессах. Трудно заставить его работать во всех случаях. Возможно, вам придется отлаживать различные странные симптомы.

Обычно окна в отдельных процессах получат свои сообщения из отдельных входных очередей с использованием отдельных сообщений. Когда вы используете SendMessage для окна в другом процессе, он фактически отправляется в другую оконную очередь, обрабатывается там, а возврат эффективно переводится обратно в исходный процесс. Поэтому, если один из процессов перестает обрабатывать сообщения, вы можете эффективно блокировать и другие. (Это верно даже в процессе, когда окна создаются в разных потоках, и очереди потоков не были присоединены.)

Но когда вы устанавливаете отношения между родителями и дочерними элементами между окнами в разных потоках, Windows присоединяет эти входные очереди вместе, заставляя обработку сообщений быть синхронной. Вы больше не в нормальном случае, но сталкиваетесь с теми же проблемами: зависание в обработке для одного окна эффективно зависает в другом процессе.

Следите за сообщениями, которые передают указатели в параметрах. Указатели не будут действительны в процессе приема. (Есть несколько исключений, например WM_COPYDATA, которые воссоздают данные в процессе приема для вас. Но даже те имеют ограничения.)

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

В более поздних версиях Windows (Vista +) вы также можете нажать несколько ошибок безопасности, если процессы выполняются с разными уровнями целостности.

Благодаря IInspectable, который указал на ошибку в моем более раннем ответе.