|
|
@@ -1,109 +1,85 @@ |
|
|
<# |
|
|
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. |
|
|
#> |
|
|
|
|
|
# Embed the C# code in PowerShell |
|
|
# Fork from: https://gist.github.com/JohnLBevan/1593bbb860c2d2af436a1c9414e8adfa |
|
|
Add-Type @" |
|
|
using System; |
|
|
using System.Runtime.InteropServices; |
|
|
using System; |
|
|
using System.Runtime.InteropServices; |
|
|
|
|
|
// https://msdn.microsoft.com/en-us/library/windows/desktop/dd162805(v=vs.85).aspx |
|
|
public struct POINT |
|
|
public class WindowMover |
|
|
{ |
|
|
[StructLayout(LayoutKind.Sequential)] |
|
|
public struct POINT |
|
|
{ |
|
|
public long x; |
|
|
public long y; |
|
|
public int x; |
|
|
public int y; |
|
|
} |
|
|
|
|
|
// https://msdn.microsoft.com/en-us/library/windows/desktop/dd162897(v=vs.85).aspx |
|
|
public struct RECT |
|
|
[StructLayout(LayoutKind.Sequential)] |
|
|
public struct RECT |
|
|
{ |
|
|
public long left; |
|
|
public long top; |
|
|
public long right; |
|
|
public long bottom; |
|
|
public int left; |
|
|
public int top; |
|
|
public int right; |
|
|
public int bottom; |
|
|
} |
|
|
|
|
|
public class User32WinApi |
|
|
public class User32 |
|
|
{ |
|
|
|
|
|
// 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 |
|
|
public static void MoveActiveWindowToCursor() |
|
|
{ |
|
|
POINT cursorPos; |
|
|
if (!User32.GetCursorPos(out cursorPos)) |
|
|
{ |
|
|
throw new Exception("Failed to get cursor position."); |
|
|
} |
|
|
|
|
|
"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" |
|
|
IntPtr hWnd = User32.GetForegroundWindow(); |
|
|
if (hWnd == IntPtr.Zero) |
|
|
{ |
|
|
throw new Exception("No active window found."); |
|
|
} |
|
|
} else { |
|
|
Write-Warning "Failed to get position of cursor" |
|
|
} |
|
|
} else { |
|
|
Write-Warning "No active window found" |
|
|
} |
|
|
|
|
|
RECT windowRect; |
|
|
if (!User32.GetClientRect(hWnd, out windowRect)) |
|
|
{ |
|
|
throw new Exception("Failed to get window size."); |
|
|
} |
|
|
|
|
|
int width = windowRect.right; |
|
|
int height = windowRect.bottom; |
|
|
|
|
|
if (!User32.MoveWindow(hWnd, cursorPos.x, cursorPos.y, width, height, true)) |
|
|
{ |
|
|
throw new Exception("Failed to move the window."); |
|
|
} |
|
|
} |
|
|
} |
|
|
"@ |
|
|
|
|
|
# Allow some time to focus the window and move the cursor |
|
|
Write-Output "Quick; get the window in question in focus, then put your mouse in position!" |
|
|
Start-Sleep -Seconds 5 |
|
|
|
|
|
# Call the C# method to move the window |
|
|
try { |
|
|
[WindowMover]::MoveActiveWindowToCursor() |
|
|
Write-Output "Window moved successfully (hope you agree!)" |
|
|
} |
|
|
catch { |
|
|
Write-Warning $_.Exception.Message |
|
|
} |