1

I added this class :

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Tests
{
    class WindowUtility
    {
        [DllImport("user32.dll", SetLastError = true)]
        static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        [DllImport("user32.dll", SetLastError = true)]
        static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);

        const uint SWP_NOSIZE = 0x0001;
        const uint SWP_NOZORDER = 0x0004;

        private static Size GetScreenSize() => new Size(GetSystemMetrics(0), GetSystemMetrics(1));

        private struct Size
        {
            public int Width { get; set; }
            public int Height { get; set; }

            public Size(int width, int height)
            {
                Width = width;
                Height = height;
            }
        }

        [DllImport("User32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
        private static extern int GetSystemMetrics(int nIndex);

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool GetWindowRect(HandleRef hWnd, out Rect lpRect);

        [StructLayout(LayoutKind.Sequential)]
        private struct Rect
        {
            public int Left;        // x position of upper-left corner
            public int Top;         // y position of upper-left corner
            public int Right;       // x position of lower-right corner
            public int Bottom;      // y position of lower-right corner
        }

        private static Size GetWindowSize(IntPtr window)
        {
            if (!GetWindowRect(new HandleRef(null, window), out Rect rect))
                throw new Exception("Unable to get window rect!");

            int width = rect.Right - rect.Left;
            int height = rect.Bottom - rect.Top;

            return new Size(width, height);
        }

        public static void MoveWindowToCenter()
        {
            IntPtr window = Process.GetCurrentProcess().MainWindowHandle;

            if (window == IntPtr.Zero)
                throw new Exception("Couldn't find a window to center!");

            Size screenSize = GetScreenSize();
            Size windowSize = GetWindowSize(window);

            int x = (screenSize.Width - windowSize.Width) / 2;
            int y = (screenSize.Height - windowSize.Height) / 2;

            SetWindowPos(window, IntPtr.Zero, x, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
        }
    }
}

Using it in Program.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Tests
{
    class Program
    {
        static void Main(string[] args)
        {
            WindowUtility.MoveWindowToCenter();

The problem is that it's showing for a second the window in some random position when running the application and then move it to the screen center.

Is there a way to make that when starting the application the window already will be in the center of the screen ?

I tried to use the accepted answer in this question in the link :

Show/Hide the console window of a C# console application

but then when i'm hiding the window then try to center it then to show it again when it's trying to center it can't find the window because it's hidden so it's throwing this message in the WindowUtility class :

"Couldn't find a window to center!"

Sharo SA
  • 131
  • 1
  • 7
  • 1
    Does this answer your question? [Position a small console window to the bottom left of the screen?](https://stackoverflow.com/questions/27715004/position-a-small-console-window-to-the-bottom-left-of-the-screen) – Abdullah Leghari Jun 05 '22 at 07:09
  • BTW, it wasn't necessary to delete your [other question](https://stackoverflow.com/questions/72511667/why-when-the-player-character-is-moving-back-the-area-after-exited-ontriggerexit). You already had 1 upvote on the question and you could have posted your [last comment](https://stackoverflow.com/questions/72511667/why-when-the-player-character-is-moving-back-the-area-after-exited-ontriggerexit#comment128094652_72511667) as _an answer_ where you could have gotten extra reputation if you accepted it. :) –  Jun 06 '22 at 06:04

1 Answers1

2

I know you have your answer but this is I created for your question.

internal class WindowUtility
{
// 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;
    }
  }
}

internal enum AnchorWindow
{
  None = 0x0,
  Top = 0x1,
  Bottom = 0x2,
  Left = 0x4,
  Right = 0x8,
  Center = 0x10,
  Fill = 0x20
}
internal static void SetConsoleWindowPosition(AnchorWindow position)
{
  // 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;
  int _left = 0, _top = 0;
  switch (position)
  {
    case AnchorWindow.Left|AnchorWindow.Top:
      wp.NormalPosition = new RECT()
      {
        Left = -fudgeOffset,
        Top = mi.rcWork.Top,
        Right = (wp.NormalPosition.Right - wp.NormalPosition.Left) - fudgeOffset,
        Bottom = (wp.NormalPosition.Bottom - wp.NormalPosition.Top)
      };
      break;
    case AnchorWindow.Right| AnchorWindow.Top:
      wp.NormalPosition = new RECT()
      {
        Left = mi.rcWork.Right - wp.NormalPosition.Right + wp.NormalPosition.Left + fudgeOffset,
        Top = mi.rcWork.Top,
        Right = mi.rcWork.Right + fudgeOffset,
        Bottom = (wp.NormalPosition.Bottom - wp.NormalPosition.Top)
      };
      break;
    case AnchorWindow.Left | AnchorWindow.Bottom:
      wp.NormalPosition = new RECT()
      {
        Left = -fudgeOffset,
        Top = mi.rcWork.Bottom - (wp.NormalPosition.Bottom - wp.NormalPosition.Top),
        Right = (wp.NormalPosition.Right - wp.NormalPosition.Left) - fudgeOffset,
        Bottom = fudgeOffset + mi.rcWork.Bottom
      };
      break;
    case AnchorWindow.Right | AnchorWindow.Bottom:
      wp.NormalPosition = new RECT()
      {
        Left = mi.rcWork.Right - wp.NormalPosition.Right + wp.NormalPosition.Left + fudgeOffset,
        Top = mi.rcWork.Bottom - (wp.NormalPosition.Bottom - wp.NormalPosition.Top),
        Right = mi.rcWork.Right + fudgeOffset,
        Bottom = fudgeOffset + mi.rcWork.Bottom
      };
      break;
    case AnchorWindow.Center|AnchorWindow.Top:
      _left = mi.rcWork.Right / 2 - (wp.NormalPosition.Right - wp.NormalPosition.Left) / 2;
      wp.NormalPosition = new RECT()
      {
        Left = _left,
        Top = mi.rcWork.Top,
        Right = mi.rcWork.Right + fudgeOffset - _left,
        Bottom = (wp.NormalPosition.Bottom - wp.NormalPosition.Top)
      };
      break;
    case AnchorWindow.Center | AnchorWindow.Bottom:
      _left = mi.rcWork.Right / 2 - (wp.NormalPosition.Right - wp.NormalPosition.Left) / 2;
      wp.NormalPosition = new RECT()
      {
        Left = _left,
        Top = mi.rcWork.Bottom - (wp.NormalPosition.Bottom - wp.NormalPosition.Top),
        Right = mi.rcWork.Right + fudgeOffset - _left,
        Bottom = fudgeOffset + mi.rcWork.Bottom
      };
      break;
    case AnchorWindow.Center:
      _left = mi.rcWork.Right / 2 - (wp.NormalPosition.Right - wp.NormalPosition.Left) / 2;
      _top = mi.rcWork.Bottom / 2 - (wp.NormalPosition.Bottom - wp.NormalPosition.Top) / 2;
      wp.NormalPosition = new RECT()
      {
        Left = _left,
        Top = _top,
        Right = mi.rcWork.Right + fudgeOffset - _left,
        Bottom = mi.rcWork.Bottom + fudgeOffset - _top
      };
      break;
    case AnchorWindow.Fill:
      wp.NormalPosition = new RECT()
      {
        Left = -fudgeOffset,
        Top = mi.rcWork.Top,
        Right = mi.rcWork.Right + fudgeOffset,
        Bottom = mi.rcWork.Bottom + fudgeOffset
      };
      break;
    default:
      return;
  }
  // Place the window at the new position.
  SetWindowPlacement(hWnd, ref wp);
}

}

You can use it like this.

WindowUtility.SetConsoleWindowPosition(WindowUtility.AnchorWindow.Left | WindowUtility.AnchorWindow.Top);
// or
WindowUtility.SetConsoleWindowPosition(WindowUtility.AnchorWindow.Center);
// or
WindowUtility.SetConsoleWindowPosition(WindowUtility.AnchorWindow.Fill);
Ahmad Reza
  • 68
  • 6
  • Tip: If this code doesn't move a window, it could be because the window is elevated (e.g. admin rights) and the program running the move code isn't. – blue Jan 31 '23 at 13:37