2010-08-11 11 views
23

La funzione SetParent accetta un handle di finestra figlio e nuovo genitore. Anche questo sembra funzionare quando la finestra secondaria si trova in un processo Windows diverso.Buona o cattiva - API Win32 SetParent() tra diversi processi

Ho visto a post che afferma che questo non è ufficialmente supportato, ma lo current docs non lo menziona più. È un difetto nei documenti attuali o questo comportamento è cambiato?

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

risposta

23

È possibile hanno una relazione padre-figlio con le finestre in diversi processi. È complicato farlo funzionare in tutti i casi. Potrebbe essere necessario eseguire il debug di vari sintomi strani.

In genere, le finestre in processi separati ricevono i loro messaggi da code di input separate utilizzando pompe di messaggi separate. Quando si utilizza SendMessage in una finestra in un altro processo, in realtà è inviato nella coda dell'altra finestra, elaborato lì e il ritorno viene effettivamente eseguito il marshalling nel processo originale. Pertanto, se uno dei processi interrompe la gestione dei messaggi, è possibile bloccare in modo efficace anche l'altro. (È vero anche all'interno di un processo quando le finestre sono create su thread diversi e le code di thread non sono state allegate.)

Ma quando si imposta la relazione padre/figlio tra finestre in thread diversi, Windows allega tali input le code insieme, forzando l'elaborazione del messaggio in sincrono. Non sei più nel caso normale, ma affronta lo stesso tipo di problemi: un blocco nell'elaborazione di una finestra blocca in modo efficace l'altro processo.

Controllare i messaggi che passano i puntatori nei parametri. I puntatori non saranno validi nel processo di ricezione. (Ci sono un paio di eccezioni, come WM_COPYDATA, che ricrea per te i dati nel processo di ricezione, ma anche quelli hanno limitazioni.)

Devi prestare particolare attenzione quando le finestre vengono distrutte. Se possibile, disconnetti la relazione genitore-figlio prima di distruggere una finestra. Se non è possibile, probabilmente è meglio distruggere manualmente la finestra secondaria prima del il genitore viene distrutto. Normalmente, la distruzione di un genitore causerà la distruzione automatica dei bambini, ma è facile ottenere blocchi quando il bambino si trova in un altro processo (o thread non collegato).

Nelle versioni più recenti di Windows (Vista +), è anche possibile eseguire alcuni speedbum di sicurezza se i processi vengono eseguiti a diversi livelli di integrità.

Grazie a IInspectable che ha rilevato un errore nella mia risposta precedente.

+4

Si ha torto sulle code dei messaggi. Quando si chiama 'SetParent' con finestre di proprietà di thread diversi, il sistema chiama' AttachThreadInput' dietro le spalle. Una volta fatto, entrambi i thread condividono la stessa coda di input. Questo vale anche per i processi. Vedi [È legale avere una relazione tra parentela/figlio o proprietario/finestra di proprietà?] (Http://blogs.msdn.com/b/oldnewthing/archive/2013/04/12/10410454.aspx) e [Condivisione di una coda di input prende ciò che era asincrono e lo rende sincrono, come le modifiche allo stato attivo] (http://blogs.msdn.com/b/oldnewthing/archive/2013/06/07/10424279.aspx). – IInspectable

+0

@IInspectable: interessante! Non pensavo che AttachThreadInput funzionasse attraverso i processi. Questo sembra aggiungere un ulteriore ruga: cosa succede se ogni thread ha un messaggio pump?Con le code di thread allegate, mi aspetto una chiamata GetMessage in entrambi i thread per recuperare i messaggi per entrambe le finestre, tuttavia non sembra plausibile che DispatchMessage nel thread A possa indirizzare un messaggio a un WndProc nel thread B di un processo diverso. Forse il GetMessage tirerà solo i messaggi per il thread corrente ma saranno sincronizzati? Non sono sicuro di come correggere la mia risposta. –

Problemi correlati