Skip to content

Instantly share code, notes, and snippets.

@JohnLBevan
Created June 20, 2017 17:07
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JohnLBevan/1593bbb860c2d2af436a1c9414e8adfa to your computer and use it in GitHub Desktop.
Save JohnLBevan/1593bbb860c2d2af436a1c9414e8adfa to your computer and use it in GitHub Desktop.
Move Window To Top Left Corner of Parent Container
<#
Originally coded to move the window to where the mouse cursor is; most code left
However, due to issues this only moves the window to the top left corner of it's parent container
That's good enough for my scenario; i.e. puts the window back on screen.
#>
Add-Type @"
using System;
using System.Runtime.InteropServices;
// https://msdn.microsoft.com/en-us/library/windows/desktop/dd162805(v=vs.85).aspx
public struct POINT
{
public long x;
public long y;
}
// https://msdn.microsoft.com/en-us/library/windows/desktop/dd162897(v=vs.85).aspx
public struct RECT
{
public long left;
public long top;
public long right;
public long bottom;
}
public class User32WinApi
{
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms648390(v=vs.85).aspx
/*
Gets the coordinates of the mouse cursor
(I've not added logic for other "remote desktop" or similar support; see above link for notes on OpenInputDesktop if that's required for your scenario
*/
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetCursorPos(out POINT lpPoint);
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms633505(v=vs.85).aspx
/*
Gets the handle of the in-focus window
NB: In some scenarios this can be NULL; so code needed to handle such an event
*/
[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms633519(v=vs.85).aspx
/*
Gets the coordinates of the rectangle relative to the top left corner of the screen.
NB: bottom right is 1 pixed beyond the bottom right boundary of the shape; i.e. defines the border, not the filled area.
*/
/* no need to find the before or after positions; let's just assume it works
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
*/
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms633503(v=vs.85).aspx
/*
top & left are always 0 (i.e. since the rectangle is relative to the window itself)
bottom & right equal the windows hieght and width, respectively.
*/
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetClientRect(IntPtr hWnd, out RECT lpRect);
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms633534(v=vs.85).aspx
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
}
"@
$repaint = $true #presumably it's best to always repaint the window after a move, just in case being offscreen blanked it in some way / something like that?
$positionOfCursor = New-Object POINT
$windowSize = New-Object RECT
"Quick; get the window in question in focus, then put your mouse in position!"
Start-Sleep -Seconds 5 #allow 5 seconds for the user to get the window they're after in focus (e.g. using ALT+TAB / whatever), and move their mouse to the required positoin
$activeWindow = [User32WinApi]::GetForegroundWindow()
if ($activeWindow) {
if([User32WinApi]::GetCursorPos([ref]$positionOfCursor)) {
if([User32WinApi]::GetClientRect($activeWindow, [ref]$windowSize)) {
$Name = @((Get-Process | ?{$_.MainWindowHandle -eq $activeWindow } | select -ExpandProperty MainWindowTitle),"No Name Found for Handle $activeWindow" -ne $null)[0]
"Moving window for $Name to Mouse Cursor Position ($($positionOfCursor.x), $($positionOfCursor.y))"
#have replaced `$positionOfCursor.x, $positionOfCursor.y` with `0, 0` as having issues converting long values to ints as returned values are out of range
#this works for my scenario; just aligns the window with its parent's top left corner
if ([User32WinApi]::MoveWindow($activeWindow, 0, 0, $windowSize.right, $windowSize.bottom, $repaint)) {
"Window moved successfully (hope you agree!)"
} else {
Write-Warning "Failed to move the window"
}
} else {
Write-Warning "Failed to get size of the active window"
}
} else {
Write-Warning "Failed to get position of cursor"
}
} else {
Write-Warning "No active window found"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment