19

My question is how to run an application(.exe) inside WPF application. I mean running inside a window of an application, not an external running an application.

Thanks in advance :D

user617275
  • 319
  • 1
  • 3
  • 6
  • 1
    Why would you possibly need to do this? Just launch the application normally. I can't imagine any possible reason that it would need to run *inside* the window of another application. – Cody Gray - on strike Jun 25 '11 at 13:37
  • Thank you for your reply:) just I wanted to use such kind of app's like notepad inside of my WPF application.I've found a solution for my question,but it was an example for WinForm.I don't know how to write it for WPF.Any ideas will be regarded :) – user617275 Jun 25 '11 at 17:28
  • Why would you want to do that? – svick Jun 25 '11 at 20:05
  • You're looking for an edit control. That's all that Notepad consists of. In WinForms, this is called a `TextBox` control. I'm not sure what it's called in WPF. If you wanted more features (like WordPad), you could use the `RichTextBox` control (again, not sure what WPF calls it). You don't need to host the other application inside your window at all. – Cody Gray - on strike Jun 26 '11 at 08:48
  • 46
    'Why would you possibly need to do this' this type of answer should be banned. Please answer the questions instead of lecturing people on the 'do' and 'not to do'. You want a reason, I give you one among many: In my Video Surveillance software I have cameras matrices monitoring a site, but I would like to dedicate one of the cell of one matrix (WPF Grid) to host a 3rd party Windows application that for instance allows to command the heating and ventilation of the site I am monitoring. – Jean-Marie Jun 08 '13 at 10:12

1 Answers1

21

What you are looking to do is entirely possible, but it does come with a few bugs, so don't expect an easy ride. What you need to do is create a class that inherits from HwndHost and overrides the BuildWindowCore() method. See the example from Microsoft at http://msdn.microsoft.com/en-us/library/ms752055.aspx

In the above example, they give you the notion of being able to put a Win32 control within your WPF form, but you can use the same architecture to load the MainWindowhandle of your created Notepad process into the child of the border. Like this:

protected override HandleRef BuildWindowCore(HandleRef hwndParent)
    {
        ProcessStartInfo psi = new ProcessStartInfo("notepad.exe");
        psi.WindowStyle = ProcessWindowStyle.Minimized;
        _process = Process.Start(psi);
        _process.WaitForInputIdle();

        // The main window handle may be unavailable for a while, just wait for it
        while (_process.MainWindowHandle == IntPtr.Zero)
        {
            Thread.Yield();
        }

        IntPtr notepadHandle = _process.MainWindowHandle;

        int style = GetWindowLong(notepadHandle, GWL_STYLE);
        style = style & ~((int)WS_CAPTION) & ~((int)WS_THICKFRAME); // Removes Caption bar and the sizing border
        style |= ((int)WS_CHILD); // Must be a child window to be hosted

        SetWindowLong(notepadHandle, GWL_STYLE, style);
        SetParent(notepadHandle, hwndParent.Handle);

        this.InvalidateVisual();

        HandleRef hwnd = new HandleRef(this, notepadHandle);
        return hwnd;
    }

Please keep in mind that you will need to import a few functions from the User32.dll to be able to set the style of the window and set the parent window handle:

[DllImport("user32.dll")]
private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);

[DllImport("user32.dll", SetLastError = true)]
private static extern int GetWindowLong(IntPtr hWnd, int nIndex);

[DllImport("user32")]
private static extern IntPtr SetParent(IntPtr hWnd, IntPtr hWndParent);

Also make sure that you are including:

using System.Windows.Interop;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;

This is my first answer on a forum so please let me know if it needs some work. Also reference Hosting external app in WPF window but don't worry about DwayneNeed stuff. Just use SetParent() as you see in my code above. Just be careful if you try embedding the app inside a tab page. You will encounter some fun there.

Community
  • 1
  • 1
Youngy
  • 516
  • 4
  • 8
  • 1
    Thanks for that. I have a problem though : I have a main window opening another window which displays the hosted window. My problem is that my main window is freezing because it looks stuck in the while loop... It doesn't work with my sample app but it does with notepad by the way. – LMeyer Jan 08 '14 at 12:36
  • 6
    Where are the constants defined? – Karl Gjertsen Feb 10 '16 at 13:32
  • The `BuildWindowCore` method in this answer seems to be taken from the answer [here](https://stackoverflow.com/a/13375366/6735035); the link has the full class but inherits from `HwndHostEx` instead of `HwndHost`. – somethingRandom Mar 25 '21 at 07:35