【问题标题】:How to get the size of the windows console form?如何获取 Windows 控制台窗体的大小?
【发布时间】:2019-11-10 03:36:25
【问题描述】:

我正在寻找一种方法来获取控制台实际窗口的大小(以像素为单位)。到目前为止,我发现的所有内容都是使用 winforms 或 WPF,这两种我都不使用。我不是在寻找如何获得控制台窗口内的大小,而是窗口本身有多大。

【问题讨论】:

  • 控制台实际上是在 Windows/DOS 控制之下,而不是在你的控制之下。你认为你需要它的原因也很奇怪。听起来你有一个 XY 问题:meta.stackexchange.com/questions/66377/what-is-the-xy-problem |您能否具体说明您需要这个做什么,以便我们寻找可行的方法?
  • 使用 windows API 应该很容易获得窗口的大小和屏幕位置。我认为,困难的任务是找到运行控制台的窗口。 Microsoft 正在开发一种新的终端,它将或可能取代 ConHost.exe。但是即使在今天,您也不能假设您的进程总是会在 ConHost.exe 中运行。所以你不能只寻找ConHost.exe 进程来找到你正在寻找的窗口。因此,我不同意@GerardoGrignoli 在这一点上的评论。我仍然想知道为什么有人想知道这些信息
  • @Christopher 所以我真正的问题是将实际的控制台窗口移动特定数量的像素。这就是为什么我认为我需要像素值。我想做的主要事情之一是将窗口居中在屏幕中间,因此需要屏幕大小和窗口大小,因为我还没有找到任何方法来使用除绝对定位之外的任何东西来使控制台居中.实际移动是通过 SetWindowPos (docs.microsoft.com/en-us/windows/win32/api/winuser/…) 完成的。

标签: c# .net console


【解决方案1】:

我在网上搜索,但没有发现任何有用的东西。

所有答案都返回任一字符数或全屏分辨率。

Windows 控制台在历史上是 DOS shell 的模拟。

来自How to get the screen size of Console Application?

using System.Management;  // Need assembly reference added to project

Console.Write("Console resolution in char:");
Console.Write(Console.WindowWidth + "x" + Console.WindowHeight);

var scope = new ManagementScope();
scope.Connect();
var query = new ObjectQuery("SELECT * FROM Win32_VideoController");
using ( var searcher = new ManagementObjectSearcher(scope, query) )
  foreach ( var result in searcher.Get() )
    Console.WriteLine("Screen resolution in pixels: {0}x{1}",
                      result.GetPropertyValue("CurrentHorizontalResolution"),
                      result.GetPropertyValue("CurrentVerticalResolution"));

它返回当前视频驱动模式的屏幕分辨率。

Windows 命令行不再是 DOS 命令行,而是简化的 shell。

很多东西和很多 DOS 命令都丢失了。

您不能再在控制台本身中创建程序了。

命令行输出 API 现在非常简单和基本。

今天,控制台应用程序只能以字符形式知道其分辨率。

没有更高级的 API,也没有可用的中断。

Windows Me 之后,Windows DOS shell COMMAND.COM 已被命令提示符 CMD.EXE 抛弃。

没有简单的方法可以知道“托管”内部控制台的 Windows 的像素分辨率是多少。

using System.Diagnostics;
using System.Drawing;
using System.Runtime.InteropServices;

[DllImport("user32.dll")]
private static extern int GetWindowRect(IntPtr hwnd, out Rectangle rect);

Rectangle rect;
GetWindowRect(Process.GetCurrentProcess().MainWindowHandle, out rect);
Console.WriteLine($"Console window location: {rect.X}x{rect.Y}");
Console.WriteLine($"Console window resolution: {rect.Width}x{rect.Height}");

但结果不是很准确。

例如它显示:

Console window location: 187x174
Console window resolution: 1336x812

当实际分辨率为 1149x638 时...

而且这个控制台窗口的分辨率在每次运行时都会有所不同...

Console window location: 99x58
Console window resolution: 1248x696

Console window location: 143x116
Console window resolution: 1292x754

Console window location: 77x29
Console window resolution: 1226x667

Console window location: 187x174
Console window resolution: 1336x812

真正的控制台表单大小是:

RealWidth = rect.Width - rect.X;
RealHeight = rect.Height - rect.Y;

【讨论】:

  • 我将此标记为我的答案,因为通过使用提供的第二种解决方案,我可以从分辨率中减去位置并获得大小。当我测试它以达到我需要的目的时,这很有效。
  • 确实!我没有看到那个。它很奇怪。谢谢。
【解决方案2】:

问题及其历史

我怀疑控制台是否在您需要的控制级别之下。基本上,在最初设计控制台时,还没有想到 Window 的idea。它们被假定为以非常低的分辨率全屏显示,这在当时很常见。从那以后,他们从未真正改变过。

在更高的分辨率上,最好的等式是制作一个覆盖部分屏幕的窗口。但它是一个只受操作系统控制的窗口,而不是你的。

您可以拥有一个与普通桌面 GUI 界面并行的控制台窗口。 It is actually pretty simple。但它仍然是您现在获得的所有限制的旧控制台。

我最好的建议是:

停止尝试使用控制台。相反,伪造一个使用 WindowsForms、WPF 或 UWP 的控制台窗口。

使用 Process 和 Input/Output stream redirection,您可以轻松地从 WinForms/WPF 程序控制命令行。请注意,有 3 个 Stream。输入、输出和错误(通常也发送到控制台窗口)。没有控制台显示。它曾经是一种仅通过命令行控制程序的常用方法,但现在它在 Unix/Linux 世界之外几乎被遗忘了,因为几乎所有东西都有前端。

然后,您可以将输入/输出映射到标签、文本框、richtTextBox 等,这些标签、文本框、richtTextBox 或类似的东西大多表现得像控制台窗口,而不是一个。而且,由于它是您选择的显示技术的窗口,因此您可以使用所有选项来操作它。

【讨论】:

  • 我知道控制台是个垃圾,但遗憾的是,这就是我对我的这个项目的限制。尽管对于除了我正在做的事情之外做任何事情的人来说,只是假装它可能是明智的,因为解决方法的麻烦会变得更大。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-05
相关资源
最近更新 更多