Usando SetParent para roubar a janela principal de outro processo, mas mantendo os loops de mensagem separados

Antecedentes: Eu e meu colega de trabalho estamos mantendo um aplicativo herdado de milhões de linhas que herdamos. Seu front-end está escrito em VB6 e, como estamos dedicando quase todos os nossos recursos para convertê-lo em C #, estamos procurando soluções rápidas e sujas para o nosso problema específico.

O aplicativo se comporta de maneira isenta de plug-ins. Existem até 20 controles ActiveX separados que podem ser carregados ao mesmo tempo em um layout no estilo de grade. O problema é que os controles ActiveX executam todo o processamento em seu próprio thread da interface do usuário e, como muitos deles estão bloqueando a espera no acesso à rede, a interface do usuário fica muito complicada. Quando nosso aplicativo C # de hospedagem carrega esses controles, ele não responde por causa de quantos controles estão consumindo recursos da interface do usuário sem fazer nada. Para completar, os controles são frágeis e travam com a menor provocação. Quando eles são hospedados no aplicativo C # principal, isso cria uma instabilidade séria.

O melhor que eu e meu colega de trabalho descobrimos até agora está iniciando um processo por controle ActiveX. Esse processo, que chamamos de proxy, é outro aplicativo winforms. Ele usa pipes nomeados para se comunicar com o processo de hospedagem. O processo de hospedagem cria uma janela, carrega um controle ActiveX de nossa escolha (por meio de algumas reflexões e magia do AxHost) e informa ao processo principal qual é o manuseio da janela por meio do pipe nomeado. O processo principal usa uma combinação de SetParent e SetWindowPos para mover o aplicativo proxy para si mesmo emular um plug-in. As atualizações de tamanho são enviadas através do canal nomeado.

Isso funciona bem o suficiente até que o aplicativo ActiveX realize algum tipo de processo demorado e clicamos na janela principal enquanto ele está funcionando. Por um tempo, a janela principal é responsiva, mas, eventualmente, ela não responde, enquanto a janela filho aguarda o encadeamento da interface do usuário. Como podemos manter as janelas filho em seu próprio segmento completo enquanto ainda obtemos os benefícios do SetParent?

(informe-me se algo não estiver claro!)

questionAnswers(1)

yourAnswerToTheQuestion