Categories

Moving Windows

In answer to a forum question I started to look at how you could move the PowerShell window from within PowerShell. Its not straight forward as we have to dig into the Win32 APIs

I came up with this code

function move-window {            
param(            
 [int]$newX,            
 [int]$newY            
)             
BEGIN {            
$signature = @'

[DllImport("user32.dll")]
public static extern bool MoveWindow(
    IntPtr hWnd,
    int X,
    int Y,
    int nWidth,
    int nHeight,
    bool bRepaint);

[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();

[DllImport("user32.dll")]
public static extern bool GetWindowRect(
    HandleRef hWnd,
    out RECT lpRect);

public 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
}

'@            
            
Add-Type -MemberDefinition $signature -Name Wutils -Namespace WindowsUtils             
            
}            
PROCESS{            
 $phandle = [WindowsUtils.Wutils]::GetForegroundWindow()            
            
 $o = New-Object -TypeName System.Object            
 $href = New-Object -TypeName System.RunTime.InteropServices.HandleRef -ArgumentList $o, $phandle            
            
 $rct = New-Object WindowsUtils.Wutils+RECT            
            
 [WindowsUtils.Wutils]::GetWindowRect($href, [ref]$rct)            
             
 $width = $rct.Right - $rct.Left            
 $height = 700            
<#
 $height = $rct.Bottom = $rct.Top
 
 $rct.Right
 $rct.Left
 $rct.Bottom
 $rct.Top
 
 $width
 $height
#>             
 [WindowsUtils.Wutils]::MoveWindow($phandle, $newX, $newY, $width, $height, $true)            
            
}             
}


We start by creating a piece of inline C# that creates a .NET class we can use to call the Win32 API functions. The names of the these functions are self explanatory



The move is accomplished by getting the handle of the foreground window and then creating a handle reference. The current window size is obtained using GetWindowRect – on my Windows 7 machine it doesn’t report the height correctly so I hard code that but calculate the width.



The MoveWindow method can be used to perform the move.  Remember that 0,0 is top left corner of the screen



I’m intrigued as to why the height isn’t reported correctly but haven’t found a good reason

One Response to Moving Windows

  • Clement Cherlin says:

    Calculating the height didn’t work because you wrote

    $height = $rct.Bottom = $rct.Top

    instead of

    $height = $rct.Bottom – $rct.Top

    Thanks for the great script!

Leave a Reply