【问题标题】:Position a small console window to the bottom left of the screen?在屏幕左下角放置一个小控制台窗口?
【发布时间】:2014-12-31 01:26:19
【问题描述】:

正如标题所说,我想将它定位在屏幕的左下角。这是我到目前为止的代码:

    Console.WindowWidth = 50
    Console.WindowHeight = 3
    Console.BufferWidth = 50
    Console.BufferHeight = 3
    Console.BackgroundColor = ConsoleColor.Black
    Console.ForegroundColor = ConsoleColor.DarkMagenta
    Console.Title = "My Title"
    Console.WriteLine("")
    Console.Write(" Press any key to close this window ...")

    Console.ReadKey()

【问题讨论】:

  • Dim x = 0 Dim y = Screen.PrimaryScreen.WorkingArea.Height - console.height console.Location = New Size(x, y)

标签: c# .net vb.net console position


【解决方案1】:

注意:尽管有他们的名字,设置System.Console classConsole.WindowLeftConsole.WindowTop 并不会改变窗口在屏幕上的位置。强>
相反,它们将窗口的可见部分相对于(可能更大的)窗口 缓冲区 - 您不能使用类型 System.Console 来更改控制台窗口在屏幕上的位置 - 您需要为此使用 Windows API


以下是完整控制台应用程序的代码,它将自己的窗口定位在屏幕的左下角,尊重任务栏的位置

注意:

  • 应该适用于多显示器设置 - 将窗口定位在它(主要)正在显示的特定显示器(显示器、屏幕)上 - 但我没有亲自验证它。

  • 仅通过 P/Invoke 声明使用 Windows API 函数,避免了引用 WinForms 程序集 (System.Windows.Forms) 的需要,这在 控制台 中通常不需要应用程序。

    • 您会看到大部分代码专门用于 P/Invoke 签名(声明),用于与本机 Windows API 进行交互;非常感谢这些改编自pinvoke.net

    • 相比之下,Main() 方法中的实际代码比较短。

  • 如果您从 Visual Studio 中的控制台应用程序项目编译下面的代码并从 cmd.exe 控制台窗口(命令提示符)运行生成的可执行文件,则该控制台窗口应移动到(包含屏幕)。

    • 要在从 Visual Studio 运行时验证功能,请在关闭 } 处放置一个断点,并在执行暂停时按 Alt-Tab 到控制台窗口以验证其位置。

using System;
using System.Runtime.InteropServices; // To enable P/Invoke signatures.

public static class PositionConsoleWindowDemo
{

    // P/Invoke declarations.

    [DllImport("kernel32.dll")]
    static extern IntPtr GetConsoleWindow();

    [DllImport("user32.dll")]
    static extern IntPtr MonitorFromWindow(IntPtr hwnd, uint dwFlags);

    const int MONITOR_DEFAULTTOPRIMARY = 1;

    [DllImport("user32.dll")]
    static extern bool GetMonitorInfo(IntPtr hMonitor, ref MONITORINFO lpmi);

    [StructLayout(LayoutKind.Sequential)]
    struct MONITORINFO
    {
        public uint cbSize;
        public RECT rcMonitor;
        public RECT rcWork;
        public uint dwFlags;
        public static MONITORINFO Default
        {
            get { var inst= new MONITORINFO(); inst.cbSize = (uint)Marshal.SizeOf(inst); return inst; }
        }
    }

    [StructLayout(LayoutKind.Sequential)]
    struct RECT
    {
        public int Left, Top, Right, Bottom;
    }

    [StructLayout(LayoutKind.Sequential)]
    struct POINT
    {
        public int x, y;
    }

    [DllImport("user32.dll", SetLastError = true)]
    static extern bool GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);

    [DllImport("user32.dll", SetLastError = true)]
    static extern bool SetWindowPlacement(IntPtr hWnd, [In] ref WINDOWPLACEMENT lpwndpl);

    const uint SW_RESTORE= 9;

    [StructLayout(LayoutKind.Sequential)]
    struct WINDOWPLACEMENT
    {
        public uint Length;
        public uint Flags;
        public uint ShowCmd;
        public POINT MinPosition;
        public POINT MaxPosition;
        public RECT NormalPosition;
        public static WINDOWPLACEMENT Default
        {
            get
            {
                var instance = new WINDOWPLACEMENT();
                instance.Length = (uint) Marshal.SizeOf(instance);
                return instance;
            }
        }
    }

    public static void Main()
    {
        // Get this console window's hWnd (window handle).
        IntPtr hWnd = GetConsoleWindow();

        // Get information about the monitor (display) that the window is (mostly) displayed on.
        // The .rcWork field contains the monitor's work area, i.e., the usable space excluding
        // the taskbar (and "application desktop toolbars" - see https://msdn.microsoft.com/en-us/library/windows/desktop/ms724947(v=vs.85).aspx)
        var mi = MONITORINFO.Default;
        GetMonitorInfo(MonitorFromWindow(hWnd, MONITOR_DEFAULTTOPRIMARY), ref mi);

        // Get information about this window's current placement.
        var wp = WINDOWPLACEMENT.Default;
        GetWindowPlacement(hWnd, ref wp);

        // Calculate the window's new position: lower left corner.
        // !! Inexplicably, on W10, work-area coordinates (0,0) appear to be (7,7) pixels 
        // !! away from the true edge of the screen / taskbar.
        int fudgeOffset = 7;
        wp.NormalPosition = new RECT() {
            Left = -fudgeOffset,
            Top = mi.rcWork.Bottom - (wp.NormalPosition.Bottom - wp.NormalPosition.Top),
            Right = (wp.NormalPosition.Right - wp.NormalPosition.Left),
            Bottom = fudgeOffset + mi.rcWork.Bottom
        };

        // Place the window at the new position.
        SetWindowPlacement(hWnd, ref wp);

    }

}

【讨论】:

    【解决方案2】:

    您可以使用System.Console 类的Console.WindowTopConsole.WindowWidth 来设置控制台窗口的位置。

    Here 是 MSDN 上的示例

    BufferHeightBufferWidth 属性获取/设置要显示的行数和列数。

    WindowHeightWindowWidth 属性必须始终分别小于 BufferHeightBufferWidth

    WindowLeft 必须小于BufferWidth - WindowWidth 并且WindowTop 必须小于BufferHeight - WindowHeight

    WindowLeftWindowTop 是相对于缓冲区的。

    要移动实际的控制台窗口,this 文章有一个很好的例子。

    我使用了您的一些代码和 CodeProject 示例中的代码。您可以在一个函数中设置窗口位置和大小。无需再次设置Console.WindowHeightConsole.WindowWidth。这就是我的班级的样子:

    class Program
    {
        const int SWP_NOZORDER = 0x4;
        const int SWP_NOACTIVATE = 0x10;
    
        [DllImport("kernel32")]
        static extern IntPtr GetConsoleWindow();
    
    
        [DllImport("user32")]
        static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter,
            int x, int y, int cx, int cy, int flags);
    
        static void Main(string[] args)
        {
            Console.WindowWidth = 50;
            Console.WindowHeight = 3;
            Console.BufferWidth = 50;
            Console.BufferHeight = 3;
            Console.BackgroundColor = ConsoleColor.Black;
            Console.ForegroundColor = ConsoleColor.DarkMagenta;
    
            var screen = System.Windows.Forms.Screen.PrimaryScreen.Bounds;
            var width = screen.Width;
            var height = screen.Height;
    
            SetWindowPosition(100, height - 300, 500, 100);
            Console.Title = "My Title";
            Console.WriteLine("");
            Console.Write(" Press any key to close this window ...");
    
            Console.ReadKey();
        }
    
    
        /// <summary>
        /// Sets the console window location and size in pixels
        /// </summary>
        public static void SetWindowPosition(int x, int y, int width, int height)
        {
            SetWindowPos(Handle, IntPtr.Zero, x, y, width, height, SWP_NOZORDER | SWP_NOACTIVATE);
        }
    
        public static IntPtr Handle
        {
            get
            {
                //Initialize();
                return GetConsoleWindow();
            }
        }
    
    }
    

    【讨论】:

    • 我一直在努力解决这个错误:Additional information: The window position must be set such that the current window size fits within the console's buffer, and the numbers must not be negative.
    • 很好的信息,很好的代码示例,但是第一句话是误导性的:问题都是关于在屏幕上移动窗口。我建Console 班级。
    【解决方案3】:
    1. 运行任何控制台应用程序
    2. 在标题上点击人民币。
    3. 选择属性选项。
    4. 选择“位置”选项卡。
    5. 取消选中“自动选择”复选框
    6. 根据需要设置控制台位置。

    【讨论】:

    • 很明显 OP 正在寻找一种以编程方式进行的方法。
    猜你喜欢
    • 2012-09-02
    • 1970-01-01
    • 2023-03-14
    • 1970-01-01
    • 2021-04-25
    • 1970-01-01
    • 1970-01-01
    • 2012-06-06
    • 2017-05-19
    相关资源
    最近更新 更多