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);
}
}
}
}