Я пытаюсь разместить/запустить приложение Exe внутри панели внутри главного окна моей программы. В главном окне есть сетка с тремя столбцами - два столбца разделены равномерно с помощью вертикального разделителя сетки для разделения левого и правого столбцов. В левом столбце есть элемент управления вкладкой, но правый столбец - это то, что я хочу разместить в exe-приложении внутри и, по существу, изменить размер приложения на основе док-станции внутри правого столбца.Внешнее приложение-хозяин в панели WPF
Я разработал программу аналогично Hosting external app in WPF window. Этот пример намного проще, чем то, что я буду использовать для exe и дополнительных функций, но пример должен объяснить мою текущую проблему.
Я могу запустить exe в окно, но не внутри Dockpanel, или любой другой в правой колонке. exe просто остается внутри окна статически, где он помещен, а не размещен внутри столбца. Я могу войти и изменить начальное местоположение окна процесса, чтобы оно действительно открывалось поверх правая колонка и, как представляется, находится в панели док-станции этого столбца, но опять же она статична.
Все примеры, которые я видел, размещают процесс внутри окна, а не внутри контейнера. WindowsInteropHelper на панель док-станции, но он все еще просто отправляет это в главное окно.
var helper = new WindowInteropHelper(GetWindow(this.ApplicationDock));
Я также попробовал несколько статей, включая два ниже, но все еще не нашли решение, которое я "ищу.
How can I run another application within a panel of my C# program?
Docking Window inside another Window
Одним из возможных вариантов Я думал о том, что при обновлении окна обновляется обработчик окна процесса, который должен быть помещен в правильные координаты, где начинается правый столбец. Мне кажется, что это должно быть последним средством, хотя и не соответствующим ct способ справиться с этим.
Моя главная заявка
<Window x:Class="ProgramInProgram.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:ProgramInProgram"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TabControl Grid.Column="0">
<TabItem Header="Blue Tab">
<Grid Background="Blue"></Grid>
</TabItem>
<TabItem Header="Red Tab" >
<Grid Background="Red"></Grid>
</TabItem>
</TabControl>
<GridSplitter Grid.Column="1" Width="5" HorizontalAlignment="Stretch" />
<DockPanel Grid.Column="2" x:Name="ApplicationDock">
</DockPanel>
</Grid>
</Window>
Кодекс за
public partial class MainWindow : Window
{
[DllImport("user32.dll")]
public static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
[DllImport("user32.dll", SetLastError = true)]
public static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll")]
private static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
[DllImport("user32.dll")]
private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, int uFlags);
private Process process;
private const int SWP_ZOZORDER = 0x0004;
private const int SWP_NOACTIVATE = 0x0010;
private const int GWL_STYLE = (-16);
private const int WS_CAPTION = 0x00C00000;
private const int WS_VISIBLE = 0x10000000;
private const int WS_THICKFRAME = 0x00040000;
const string patran = "patran";
public MainWindow()
{
InitializeComponent();
Loaded += (s, e) => LaunchChildProcess();
}
private void LaunchChildProcess()
{
this.process = Process.Start("Notepad.exe");
this.process.WaitForInputIdle();
var helper = new WindowInteropHelper(GetWindow(this.ApplicationDock));
SetParent(this.process.MainWindowHandle, helper.Handle);
int style = GetWindowLong(this.process.MainWindowHandle, GWL_STYLE);
style = style & ~WS_CAPTION & ~WS_THICKFRAME;
SetWindowLong(this.process.MainWindowHandle, GWL_STYLE, style);
ResizeEmbeddedApp();
}
private void ResizeEmbeddedApp()
{
if (this.process == null)
{
return;
}
UIElement container = VisualTreeHelper.GetParent(this.ApplicationDock) as UIElement;
Point relativeLocation = this.ApplicationDock.TranslatePoint(new Point(0, 0), container);
}
protected override Size MeasureOverride(Size availableSize)
{
Size size = base.MeasureOverride(availableSize);
ResizeEmbeddedApp();
return size;
}
}
Я постараюсь избежать таких хаков. Если вам действительно нужен блокнот, используйте TextBox. Вы можете использовать OLE, в то время как это действительно избыток для простого редактирования файла. https://en.wikipedia.org/wiki/Object_Linking_and_Embedding – Mat
Возможный дубликат [Хостинг внешнего приложения в окне WPF] (http://stackoverflow.com/questions/5028598/hosting-external-app-in-wpf-window) – FreeMan
Это пример программы, в моей реальной программе я использую другое приложение для EXE, которое является более сложным - ничего подобного редактированию текстового файла. – Caleb