JD2022-TU1/main/tools/apps/Monolith/View/HostingPanel.cs

82 lines
2.9 KiB
C#

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