Добро или зло - Win32 API SetParent() между различными процессами

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

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

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

1 ответ

Решение

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

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

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

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

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

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

Спасибо IInspectable, который указал на ошибку в моем предыдущем ответе.

Просто удали WS_CHILDWINDOWиз дочернего окна. Это позволяет избежать замков.
Извините, это не помогло

Другие вопросы по тегам