Skip to content

Instantly share code, notes, and snippets.

@Ch3shireDev
Last active December 22, 2021 15:01
Show Gist options
  • Select an option

  • Save Ch3shireDev/10195a6f0324218d0ebd432153bcf669 to your computer and use it in GitHub Desktop.

Select an option

Save Ch3shireDev/10195a6f0324218d0ebd432153bcf669 to your computer and use it in GitHub Desktop.
wpf_embedding.cs
using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;
namespace TestWpfAppControl
{
/// <summary>
/// AppControl.xaml
/// </summary>
public partial class AppControl : IDisposable
{
private const int GWL_STYLE = -16;
private const int WS_VISIBLE = 0x10000000;
private IntPtr _appWin;
private Process _childp;
private bool _iscreated;
private bool _isdisposed;
public string ExeName { get; set; } = "notepad.exe";
public AppControl()
{
InitializeComponent();
SizeChanged += OnSizeChanged;
Loaded += OnVisibleChanged;
SizeChanged += OnResize;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~AppControl()
{
Dispose();
}
[DllImport("user32.dll", SetLastError = true)]
private static extern long SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
[DllImport("user32.dll", EntryPoint = "SetWindowLongA", SetLastError = true)]
public static extern int SetWindowLongA([In] IntPtr hWnd, int nIndex, int dwNewLong);
[DllImport("user32.dll", SetLastError = true)]
private static extern bool MoveWindow(IntPtr hwnd, int x, int y, int cx, int cy, bool repaint);
protected void OnSizeChanged(object s, SizeChangedEventArgs e)
{
InvalidateVisual();
}
protected void OnVisibleChanged(object s, RoutedEventArgs e)
{
if (_iscreated) return;
_iscreated = true;
_appWin = IntPtr.Zero;
try
{
var procInfo = new ProcessStartInfo(ExeName) {WorkingDirectory = Path.GetDirectoryName(ExeName)};
_childp = Process.Start(procInfo);
_childp.WaitForInputIdle();
_appWin = _childp.MainWindowHandle;
}
catch (Exception ex)
{
Debug.Print(ex.Message + "Error");
}
var helper = new WindowInteropHelper(Window.GetWindow(AppContainer));
SetParent(_appWin, helper.Handle);
SetWindowLongA(_appWin, GWL_STYLE, WS_VISIBLE);
MoveWindow(_appWin, 0, 0, (int) ActualWidth, (int) ActualHeight, true);
}
protected void OnResize(object s, SizeChangedEventArgs e)
{
if (_appWin == IntPtr.Zero) return;
MoveWindow(_appWin, 0, 0, (int) ActualWidth, (int) ActualHeight, true);
}
protected virtual void Dispose(bool disposing)
{
if (_isdisposed) return;
if (disposing)
{
if (_iscreated && _appWin != IntPtr.Zero && !_childp.HasExited)
{
_childp.Kill();
_appWin = IntPtr.Zero;
}
}
_isdisposed = true;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment