using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Interop; using Monolith.Models; namespace Monolith.View { public class HostingPanel : HwndHost { private Process m_hostedProcess; private const int GWL_STYLE = -16; private const int WS_CAPTION = 0x00C00000; private const int WS_THICKFRAME = 0x00040000; private const int WS_CHILD = 0x40000000; public HostingPanel() { DataContextChanged += OnDataContextChanged; } private void OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e) { HostedProcessModel model = DataContext as HostedProcessModel; if (model != null) m_hostedProcess = model.RequestProcessHandle(this); } public static void OnHostedProcessFullPathChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (e.NewValue == null) throw new NotSupportedException("This control does not support changing its running process in runtime. "); } protected override System.Runtime.InteropServices.HandleRef BuildWindowCore(System.Runtime.InteropServices.HandleRef hwndParent) { // The main window handle may be unavailable for a while, just wait for it while (m_hostedProcess.MainWindowHandle == IntPtr.Zero) { Thread.Yield(); } IntPtr notepadHandle = m_hostedProcess.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; } protected override void DestroyWindowCore(System.Runtime.InteropServices.HandleRef hwnd) { m_hostedProcess = null; HostedProcessModel model = DataContext as HostedProcessModel; if (model != null) model.DisposeProcessHandle(this); } [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); } }