SetWindowPos doesn't work with VSCode windows

120 Views Asked by At

I'm trying to move the VSCode window using SetWindowPos (in PowerShell, however the same should apply to C++ or C# PInvoke) and I cannot get it to work.

Even more frustratingly NirSoft's GUIPropView utility does manage to move (using the Center Selected Windows option) the VSCode window somehow. (And of course there's no source code available for that program...)

I'm able to get some kind of handle using the following PowerShell code:

$hwnd = (Get-Process code).MainWindowHandle | where { $_ -ne 0 }

This yields the handle as when using FindWindow (supplying the window class and title of the VSCode instance).

Using this handle for SetWindowPos does absolutely nothing apart from making SetWindowPos return True (meaning it at least didn't fail completely, I suppose?).

$user32 = Add-Type -MemberDefinition @'
[DllImport("user32.dll", SetLastError = true)]
public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, UInt32 uFlags);
'@ -Name user32 -PassThru

# just some test coordinates and sizes
$user32::SetWindowPos($hwnd, 0, 100, 100, 500, 500, 0)

GUIPropView also gave me two other handles (shown in a bottom panel in the program), of which I have no idea where they came from, and one of those allows me to resize and reposition the rendered content, but not the whole window itself, producing a result like this: weirdness

Is there something obvious I'm missing? Should I obtain the window handle differently? What's going on?

1

There are 1 best solutions below

0
On

Turns out the code I had for finding the handle to the VSCode window was actually fine. The issue was trying to move/resize the window while it was still maximized. (Note that other applications I tested this with, such as Firefox, do not have any issues with that.)

To unmaximize/unminimize/unarrange the window, we can use ShowWindow with SWP_RESTORE.

The full script is as follows:

$user32 = Add-Type -MemberDefinition @'
[DllImport("user32.dll", SetLastError = true)]
public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, UInt32 uFlags);

[DllImport("user32.dll")]
public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
'@ -Name user32 -PassThru

$hwnd = (Get-Process code).MainWindowHandle | Where-Object { $_ -ne 0 }

$user32::ShowWindow($hwnd, 0x0009 <# SW_RESTORE #>);
$user32::SetWindowPos($hwnd, 0, 100, 100, 500, 500, 0);