1

I'm hosting an executable within my windows forms. I'm trying to also host every dialog (pop ups) the executable creates in my windows forms. It is possible, done it before, but forgot how and don't have the code anymore :/

Anyone has any suggestion?

How to run exe inside windows forms (Luke Quinane has a good answer): StackOverflow Solution

Basically, how do I get the handle from pop ups/dialog boxes from the executable? So I can change their parent handle.

My code so far:

public partial class Inception: Form
{
    private Process extApp;
    public Inception()
    {
        InitializeComponent();
        pnl1.BackColor = Color.Gray;
    }

    //set exe parent
    [DllImport("user32.dll")]
    static extern IntPtr SetParent(IntPtr hwc, IntPtr hwp);

    //move the exe window
    [DllImport("user32.dll")]
    private static extern bool MoveWindow(IntPtr hwnd, int x, int y, int cx, int cy, bool repaint);

    //get the exe window size
    [DllImport("user32.dll")]
    public static extern bool GetWindowRect(IntPtr hWnd, out Rectangle lpRect);

    private void Inception_Load(object sender, EventArgs e)
    {
        extApp = new Process();
        extApp.StartInfo.FileName = @"C:\Program Files (x86)\RandomAppDir\RandomApp.exe";
        extApp.Start();

        //myProcess.WaitForInputIdle();
        while (extApp.MainWindowHandle == IntPtr.Zero) ;
        SetParent(extApp.MainWindowHandle, pnl1.Handle);
        MoveWindow(extApp.MainWindowHandle, 0, 0, 0, 0, true);
        ResizePanel();

    }

    private void ResizePanel()
    {
        Rectangle Rect;
        GetWindowRect(extApp.MainWindowHandle, out Rect);
        pnl1.Width = Rect.Width - Rect.X;
        pnl1.Height = Rect.Height - Rect.Y;
    }
    private void Inception_FormClosed(object sender, FormClosedEventArgs e)
    {
        if (!extApp.HasExited)
        {
            extApp.Kill();
        }
    }

    private void myTimer_Tick(object sender, EventArgs e)
    {
        if (!extApp.HasExited)
        { 
            //retrieve dialog handles??

        }
    }
}

Any help is appreciated. And thank you!

MY SOLUTION

This has done the trick for me.

Every Pop Up from the external executable will have his parent handle modified.

    [DllImport("user32.dll")]
    private static extern IntPtr GetForegroundWindow();

    [DllImport("User32.dll")]
    static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
    private void myTimer_Tick(object sender, EventArgs e)
    {
        if (!extApp.HasExited)
        {
            //retrieve dialog handles
            IntPtr activeHandle = GetForegroundWindow();
            if (activeHandle != extApp.MainWindowHandle)
            {
                uint activeProcessId;
                GetWindowThreadProcessId(activeHandle, out activeProcessId);
                if (extApp.Id == activeProcessId)
                {
                    SetParent(activeHandle, pnl1.Handle);
                }
            }       
        }
    }
Community
  • 1
  • 1
Hades
  • 865
  • 2
  • 11
  • 28
  • 1
    You might want to read [Is it legal to have a cross-process parent/child or owner/owned window relationship?](http://blogs.msdn.com/b/oldnewthing/archive/2013/04/12/10410454.aspx) by Raymond Chen before you take this too far. "Yes, it is technically legal. It is also technically legal to juggle chainsaws. ... they become near-impossible to manage if one or both of the windows involved is unaware that it is participating in a cross-process window tree" – Damien_The_Unbeliever Dec 01 '15 at 13:10
  • In the past, putting "Thread.Sleep(amountofmillisecondstowait);" before "SetParent();" has worked for me. – Sophie Coyne Dec 01 '15 at 14:05
  • @Damien_The_Unbeliever, I appreciate your concern, but managing it won't be an issue. – Hades Dec 01 '15 at 14:12
  • @Rariolu, the application works, just for the main window. It's capturing the dialog boxes of that executable and assigning it to the windows forms mainwindowhandle that is a bit tricky. – Hades Dec 01 '15 at 14:14
  • The overall point of my concern is that, if you have a way to manage it, then you already have control over *both* programs, and there are better ways to deal with this. As it is, this seems to be a case where you *don't* have control over one of the programs, and you cannot predict what behaviour it will exhibit as you continually break its expectations. That's what's called out in the post I linked to. You cannot fix this purely from one side of this "re-parenting" activity. – Damien_The_Unbeliever Dec 01 '15 at 18:41
  • @Damien_The_Unbeliever, for my application the external executable just has to run inside the windows form. It doesn't interact with anything else. It's like having windows calculator or paint floating around in your App. The way it behaves is of little concern to me as long as I start and kill the app appropriately. – Hades Dec 01 '15 at 22:18

0 Answers0