vb.net 在屏幕左下角放置一个小的控制台窗口?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27715004/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 18:36:37  来源:igfitidea点击:

Position a small console window to the bottom left of the screen?

c#.netvb.netconsoleposition

提问by J. Scott Elblein

As the title says, I want to position it to the bottom left corner of the screen. Here's the code I have so far:

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

    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()

采纳答案by Abhishek

You can use Console.WindowTopand Console.WindowWidthof the System.Consoleclass to set the location of the console window.

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

Hereis an example on MSDN

是 MSDN 上的一个例子

The BufferHeightand BufferWidthproperty gets/sets the number of rows and columns to be displayed.

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

WindowHeightand WindowWidthproperties must always be less than BufferHeightand BufferWidthrespectively.

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

WindowLeftmust be less than BufferWidth - WindowWidthand WindowTopmust be less than BufferHeight - WindowHeight.

WindowLeft必须小于BufferWidth - WindowWidthWindowTop必须小于BufferHeight - WindowHeight

WindowLeftand WindowTopare relative to the buffer.

WindowLeft并且WindowTop是相对于缓冲区的。

To move the actual console window, thisarticle has a good example.

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

I have used some of your code and code from the CodeProject sample. You can set window location and size both in a single function. No need to set Console.WindowHeightand Console.WindowWidthagain. This is how my class looks:

我使用了您的一些代码和 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();
        }
    }

}

回答by mklement0

Note: Despite their names, setting Console.WindowLeftand Console.WindowTopof the System.Consoleclassdoes notchange the window's position on screen.
Instead, they position the visible part of the window relative to the (potentially larger) window buffer- you cannot use type System.Consoleto change the position of console windows on the screen - you need to use the Windows API for that.

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



The following is code for a complete console applicationthat positions its own window in the lower left corner of the screen, respecting the location of the taskbar.

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

Note:

笔记:

  • It shouldwork with multi-monitor setups - positioning the window on the specific monitor (display, screen) it is (mostly) being displayed on - but I haven't personally verified it.

  • Only Windows API functions are used via P/Invoke declarations, avoiding the need for referencing the WinForms assembly (System.Windows.Forms), which is not normally needed in consoleapplications.

    • You'll see that a good portion of the code is devoted to P/Invoke signatures (declaration) for interfacing with the native Windows APIs; these were gratefully adapted from pinvoke.net

    • The actual code in the Main()method is short by comparison.

  • If you compile the code below from a console-application project in Visual Studio and run the resulting executable from a cmd.execonsole window (Command Prompt), that console window should shift to the lower left corner of the (containing screen).

    • To verify the functionality while running from Visual Studio, place a breakpoint at the closing }and, when execution pauses, Alt-Tab to the console window to verify its position.
  • 应该适用于多显示器设置 - 将窗口定位在它(主要)正在显示的特定显示器(显示器,屏幕)上 - 但我还没有亲自验证它。

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

    • 您会看到代码的很大一部分专门用于与本地 Windows API 接口的 P/Invoke 签名(声明);这些都非常感谢地改编自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);

    }

}