Относительно моего предыдущего вопроса :
Я предложил следующий подход, в котором я создал этот элемент управления WinForms:
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows.Forms;
public class ConsoleWindow : Control
{
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool AllocConsole();
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool FreeConsole();
[DllImport("kernel32.dll")]
static extern IntPtr GetConsoleWindow();
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
[DllImport("user32.dll", SetLastError = true)]
static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
[DllImport("user32.dll")]
public static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
private static ConsoleWindow _theWindow;
public ConsoleWindow()
{
if (!DesignMode)
{
if (_theWindow != null)
{
throw new Exception("An application can have only one ConsoleWindow");
}
_theWindow = this;
AllocConsole();
var newOut = new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = true };
Console.SetOut(newOut);
Console.SetError(newOut);
var consoleHwnd = GetConsoleWindow();
SizeChanged += (sender, args) =>
{
SetWindowPos(consoleHwnd, IntPtr.Zero, 0, 0, Width, Height, 0);
};
SetWindowLong(consoleHwnd, -16 /*GWL_STYLE*/, 0x50000000 /* WS_CHILD|WS_VISIBLE*/);
SetParent(consoleHwnd, Handle);
SetWindowPos(consoleHwnd, IntPtr.Zero, 0, 0, 0, 0, 0);
}
}
protected override void Dispose(bool disposing)
{
if (disposing && _theWindow != null)
{
FreeConsole();
_theWindow = null;
}
base.Dispose(disposing);
}
}
... которыйЗатем я могу использовать в своем приложении WPF через XAML, например:
<WindowsFormsHost>
<WindowsFormsHost.Child>
<controls:ConsoleWindow></controls:ConsoleWindow>
</WindowsFormsHost.Child>
</WindowsFormsHost>
Это в основном работает, за исключением того, что взаимодействие с мышью кажется нарушенным.Когда вы создаете консольное окно (обычно оно работает как окно верхнего уровня), вы можете использовать мышь, чтобы щелкнуть / перетащить произвольное выделение, но это больше не работает после того, как я стал родительским элементом управления, как я это сделал.Я могу щелкнуть правой кнопкой мыши, чтобы вызвать контекстное меню окна консоли, чтобы выделить / скопировать весь текст, но я не могу сделать выбор щелчком / перетаскиванием.
Есть ли способ исправить это (пропущенные / неправильные стили иливозможно маршрутизация сообщений?), чтобы я мог взаимодействовать с окном консоли, как ожидается, или есть фундаментальная проблема с родительским окном консоли таким образом?