Добро или зло - SetParent () Win32 API между различными процессами - PullRequest
26 голосов
/ 11 августа 2010

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

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

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

1 Ответ

25 голосов
/ 11 августа 2010

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

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

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

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...