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

Published Sat, Jul 23 2011 11:24 by RichardSiddaway

Comments

# re: Moving Windows

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!

Wednesday, February 15, 2012 6:56 PM by Clement Cherlin

Leave a Comment

(required) 
(required) 
(optional)
(required) 
If you can't read this number refresh your screen
Enter the numbers above: