gpt4 book ai didi

c# - 是否可以创建一个控制台窗口(由 AllocConsole 创建)作为 GUI 子窗口?如果是这样,如何?

转载 作者:行者123 更新时间:2023-11-30 22:55:57 30 4
gpt4 key购买 nike

出于多种目的,我想在我的 WPF 应用程序中包含控制台窗口功能,包括:

  • 屏幕记录
  • 显示应用程序执行的控制台命令的结果
  • 诊断

我使用的两种技术是:

  • 创建一个 TextBox 并通过赋值或数据绑定(bind)设置其 Text 属性。这很好地将 View 集成到应用程序中,但随着文本“缓冲区”变大,会出现性能问题。
  • AllocConsole 进行互操作调用以创建控制台窗口。对于相对较大的文本“缓冲区”没有性能问题,但创建为顶级窗口(在视觉上与具有自己的标题栏等的应用程序分开)。

理想情况下,我想创建一个控制台窗口(如 AllocConsole)作为我的 WPF 应用程序窗口的子窗口,类似于将窗体窗口托管为 WPF 应用程序的子窗口的方式,以便它可以生活在标签等中。

据我所知,一旦创建窗口就无法更改其父窗口,创建新控制台窗口的唯一方法是 AllocConsole,它不带任何参数,因此父窗口(例如 Forms主机)无法指定。我错过了什么吗?

我的问题的重点不是使用 TextBox、ListBox 等来近似/模拟类似控制台的行为,而是将实际的控制台窗口托管为 WPF 应用程序的 GUI 元素。

编辑

目前我在哪里:

主窗口 XAML 片段:

<TabControl>
<TabItem Header="Log">
<Grid>
<WindowsFormsHost x:Name="FormsHost">

</WindowsFormsHost>
</Grid>
</TabItem>
</TabControl>

主窗口代码隐藏:

using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Forms;

public partial class MainWindow : Window
{
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool AllocConsole();

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

[DllImport("user32.dll")]
public static extern int GetWindowLong(IntPtr hWnd, int nIndex);

public MainWindow()
{
InitializeComponent();

AllocConsole();

var newOut = new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = true };
Console.SetOut(newOut);
Console.SetError(newOut);

var ptr = GetConsoleWindow();

FormsHost.Child = new Control();

SetWindowLong(ptr, -16, GetWindowLong(ptr, -16) | 0x40000000);
SetParent(ptr, FormsHost.Child.Handle);
SetWindowPos(ptr, IntPtr.Zero, 0, 0, 300, 300, 0);

Console.WriteLine("Hello, World");
}
}

上面确实将控制台窗口带入了 WPF 选项卡,但它仍然具有顶级窗口的外观,并且在其宿主中仍然很大且可移动。此外,虽然我可以在控制台区域中单击鼠标右键以获取用于文本选择的上下文菜单,但我无法使用鼠标来选择文本。

更新

我通过更改解决了窗口样式的问题

SetWindowLong(ptr, -16, GetWindowLong(ptr, -16) | 0x40000000)

SetWindowLong(ptr, -16, 0x50000000)

并解决了窗口大小调整问题,但鼠标交互仍然存在问题 - 鼠标右键可以激活上下文菜单,但鼠标左键无法进行选择。

最佳答案

根据我收集到的信息,您的意图仅用于输出(而非输入),然后是类似 Console.SetOut 的简单内容符合要求。

这会将控制台输出重定向到您选择的 TextWriter。然后您可以根据需要显示。

当然,您也可以使用众多日志记录库之一,而不是写入控制台。或者使用类似 Debug.Write 等...

但这是一种快速而简单的方法,可以读取任何输出到控制台的内容并以您想要的方式显示。或者,如果您愿意,可以重定向到一个文件。

关于性能,我必须查看您使用的代码。对于大量的日志记录数据,我个人会使用 ListBox 而不是 TextBox

关于c# - 是否可以创建一个控制台窗口(由 AllocConsole 创建)作为 GUI 子窗口?如果是这样,如何?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54811209/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com