oscilatingcretin
oscilatingcretin

Reputation: 10959

Is there a way to set the physical top/left desktop pixel position of the console app window itself?

Some research has told me that the .NET console app API doesn't natively support setting the position of the console window itself at any X/Y location on your destop. This is disheartening because I have two monitors, one being my primary code monitor and the other where I display my UI (ASP.NET web page, console app, WinForms window, etc). When I execute my console app, it wants to open behind Visual Studio, but I want it to open on my other monitor.

Do I need to call the Win32 API in order to do this? Is there another way?

Update: kingalligator's solution works perfectly when using arbitrary, hardcoded values in the MoveWindow() API call. However, when applying RECT dimensions taken from the GetWindowRect() API call, you need to set the height by subtracting .top from .bottom as shown below. If you just pass in .bottom, the window will incrementally increase height. Oddly, you don't have to do this math with .left and .right which is what had me so confused.

RECT rect = new RECT();
IntPtr ptr = GetConsoleWindow();

for (int i = 0; i < 5; i++)
{
    GetWindowRect(ptr, ref rect);
    MoveWindow(ptr, rect.left, rect.top, rect.right, rect.bottom - rect.top, true);
}

Upvotes: 2

Views: 547

Answers (1)

Dave H
Dave H

Reputation: 653

Yes, it looks like there is a way - at least in C#, for that matter. You specified .NET, so I tried to do this in VB as well, but I could not make it work. The most important part of the following code is MoveWindow(IntPtr hwnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);

The parameters are: handle, window x position, window y position, window width, window height, and a boolean value that represents whether you want the window to be repainted or not.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

public struct RECT
{
    public int left;
    public int top;
    public int right;
    public int bottom;
}

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {

            Console.Title = "Test";
            IntPtr handle = FindWindowByCaption(IntPtr.Zero, Console.Title);
            MoveWindow(handle, 100, 300, 200, 200, true);
            Console.WriteLine("Hi");

            RECT thisRect = new RECT();
            GetWindowRect(handle, ref thisRect);
            Console.WriteLine(thisRect.left);
            Console.WriteLine(thisRect.top);
            Console.ReadKey();
            return;

        }

        [DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
        public static extern IntPtr FindWindowByCaption(IntPtr zeroOnly, string lpWindowName);

        [DllImport("user32.dll", SetLastError = true)]
        internal static extern bool MoveWindow(IntPtr hwnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);

        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention =      CallingConvention.StdCall, ExactSpelling = true, SetLastError = true)]
        public static extern bool GetWindowRect(IntPtr hWnd, ref RECT rect);

    }
}

Upvotes: 3

Related Questions