Добро или зло - 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
из дочернего окна. Это позволяет избежать замков.
Извините, это не помогло