Last active
December 22, 2021 15:01
-
-
Save Ch3shireDev/10195a6f0324218d0ebd432153bcf669 to your computer and use it in GitHub Desktop.
wpf_embedding.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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