[Function] WinRestorePlus

Post your working scripts, libraries and tools for AHK v1.1 and older
iPhilip
Posts: 822
Joined: 02 Oct 2013, 12:21

[Function] WinRestorePlus

07 Nov 2017, 13:56

Hi folks,

If you ever restore a window and immediately move it or resize it, the function below might be of interest to you. The function WinRestorePlus() combines the WinRestore and WinMove commands into one function, i.e. it restores a window directly to a new set of coordinates and/or dimensions. The key benefit is that it does so without any flicker.

Here is the function:

Code: Select all

; =============================================================================================================================
; WinRestorePlus(hwnd:="", X:="", Y:="", W:="", H:="")
; Function:       Restore a window to a new set of coordinates/dimensions, regardless of its state (maximized, minimized, or normal).
;                 Combines the WinRestore and WinMove commands into one function with the benefit of no flicker.
;                 If the window is a normal window, this function will simply move/resize the window.
;                 If no parameters are specified, this function restores the active window, as in WinRestore, A.
; Tested with:    AHK 1.1.26.01 (A32/U32/U64)
;                 AHK 2.0-a081-cad307c (U32/U64)
; Tested on:      Win 7 (x64)
; Parameters:     hwnd - (Optional) The handle of the window being restored. If not specified, the active window will be restored.
;                 X    - (Optional) The x coordinate of the upper-left corner of the target window's new location*
;                 Y    - (Optional) The y coordinate of the upper-left corner of the target window's new location*
;                 W    - (Optional) The new width of the target window*
;                 H    - (Optional) The new height of the target window*
;                 *If a coordinate is not specified, the corresponding value of the window in its restored state is used.
; Return values:  nonzero if the window was successfully restored
;                 zero if the window was not successfully restored
; MSDN links:     https://msdn.microsoft.com/en-us/library/windows/desktop/ms633518(v=vs.85).aspx - GetWindowPlacement function
;                 https://msdn.microsoft.com/en-us/library/windows/desktop/ms633544(v=vs.85).aspx - SetWindowPlacement function
;                 https://msdn.microsoft.com/en-us/library/windows/desktop/ms632611(v=vs.85).aspx - WINDOWPLACEMENT structure
; =============================================================================================================================

WinRestorePlus(hwnd:="", X:="", Y:="", W:="", H:="") {
   hwnd := hwnd = "" ? WinExist("A") : hwnd
   VarSetCapacity(WP, 44, 0), NumPut(44, WP, "UInt")
   DllCall("User32.dll\GetWindowPlacement", "Ptr", hwnd, "Ptr", &WP)
   Lo := NumGet(WP, 28, "Int")        ; X coordinate of the upper-left corner of the window in its original restored state
   To := NumGet(WP, 32, "Int")        ; Y coordinate of the upper-left corner of the window in its original restored state
   Wo := NumGet(WP, 36, "Int") - Lo   ; Width of the window in its original restored state
   Ho := NumGet(WP, 40, "Int") - To   ; Height of the window in its original restored state
   L := X = "" ? Lo : X               ; X coordinate of the upper-left corner of the window in its new restored state
   T := Y = "" ? To : Y               ; Y coordinate of the upper-left corner of the window in its new restored state
   R := L + (W = "" ? Wo : W)         ; X coordinate of the bottom-right corner of the window in its new restored state
   B := T + (H = "" ? Ho : H)         ; Y coordinate of the bottom-right corner of the window in its new restored state
   NumPut(9, WP, 8, "UInt")           ; SW_RESTORE = 9
   NumPut(L, WP, 28, "Int")
   NumPut(T, WP, 32, "Int")
   NumPut(R, WP, 36, "Int")
   NumPut(B, WP, 40, "Int")
   Return DllCall("User32.dll\SetWindowPlacement", "Ptr", hwnd, "Ptr", &WP)
}
Here is a self-contained AHK v1.1 example:

Code: Select all

WinSize := 400
MsgBox,
( Join
First, let's create a Notepad window and move it`n
to the bottom-right of the screen.
)
Run, Notepad, , , pid
WinWaitActive, ahk_pid %pid%
hwnd := WinExist("A")
SysGet, MonitorPos, MonitorWorkArea
WinMove, , , MonitorPosRight-MonitorPosLeft-WinSize, MonitorPosBottom-MonitorPosTop-WinSize, WinSize, WinSize
MsgBox Now, let's maximize it.
WinMaximize
MsgBox,
( Join
Now, let's restore and move the window using the built-in WinRestore and WinMove commands.`n`n
Note that the window is restored to the bottom-right and then quickly moved to the upper-left.
 The flicker is visible even when a delay of -1 is used in the SetWinDelay command.
)
WinRestore
WinMove, 0, 0
MsgBox,
( Join
Now, let's try with the WinRestorePlus() function.`n`n
First, let's move the window to the bottom-right of the screen.
)
WinMove, , , MonitorPosRight-MonitorPosLeft-WinSize, MonitorPosBottom-MonitorPosTop-WinSize, WinSize, WinSize
MsgBox Now, let's maximize it again.
WinMaximize
MsgBox,
( Join
Now, let's restore and move the window using the WinRestorePlus() function.`n`n
Note that this is done in a single step, with no flicker, as the window is restored to the new position.
)
WinRestorePlus(hwnd, 0, 0)
MsgBox Now that we are done, let's close the window and quit.
WinClose
ExitApp

; =============================================================================================================================
; WinRestorePlus(hwnd:="", X:="", Y:="", W:="", H:="")
; Function:       Restore a window to a new set of coordinates/dimensions, regardless of its state (maximized, minimized, or normal).
;                 Combines the WinRestore and WinMove commands into one function with the benefit of no flicker.
;                 If the window is a normal window, this function will simply move/resize the window.
;                 If no parameters are specified, this function restores the active window, as in WinRestore, A.
; Tested with:    AHK 1.1.26.01 (A32/U32/U64)
;                 AHK 2.0-a081-cad307c (U32/U64)
; Tested on:      Win 7 (x64)
; Parameters:     hwnd - (Optional) The handle of the window being restored. If not specified, the active window will be restored.
;                 X    - (Optional) The x coordinate of the upper-left corner of the target window's new location*
;                 Y    - (Optional) The y coordinate of the upper-left corner of the target window's new location*
;                 W    - (Optional) The new width of the target window*
;                 H    - (Optional) The new height of the target window*
;                 *If a coordinate is not specified, the corresponding value of the window in its restored state is used.
; Return values:  nonzero if the window was successfully restored
;                 zero if the window was not successfully restored
; MSDN links:     https://msdn.microsoft.com/en-us/library/windows/desktop/ms633518(v=vs.85).aspx - GetWindowPlacement function
;                 https://msdn.microsoft.com/en-us/library/windows/desktop/ms633544(v=vs.85).aspx - SetWindowPlacement function
;                 https://msdn.microsoft.com/en-us/library/windows/desktop/ms632611(v=vs.85).aspx - WINDOWPLACEMENT structure
; =============================================================================================================================

WinRestorePlus(hwnd:="", X:="", Y:="", W:="", H:="") {
   hwnd := hwnd = "" ? WinExist("A") : hwnd
   VarSetCapacity(WP, 44, 0), NumPut(44, WP, "UInt")
   DllCall("User32.dll\GetWindowPlacement", "Ptr", hwnd, "Ptr", &WP)
   Lo := NumGet(WP, 28, "Int")        ; X coordinate of the upper-left corner of the window in its original restored state
   To := NumGet(WP, 32, "Int")        ; Y coordinate of the upper-left corner of the window in its original restored state
   Wo := NumGet(WP, 36, "Int") - Lo   ; Width of the window in its original restored state
   Ho := NumGet(WP, 40, "Int") - To   ; Height of the window in its original restored state
   L := X = "" ? Lo : X               ; X coordinate of the upper-left corner of the window in its new restored state
   T := Y = "" ? To : Y               ; Y coordinate of the upper-left corner of the window in its new restored state
   R := L + (W = "" ? Wo : W)         ; X coordinate of the bottom-right corner of the window in its new restored state
   B := T + (H = "" ? Ho : H)         ; Y coordinate of the bottom-right corner of the window in its new restored state
   NumPut(9, WP, 8, "UInt")           ; SW_RESTORE = 9
   NumPut(L, WP, 28, "Int")
   NumPut(T, WP, 32, "Int")
   NumPut(R, WP, 36, "Int")
   NumPut(B, WP, 40, "Int")
   Return DllCall("User32.dll\SetWindowPlacement", "Ptr", hwnd, "Ptr", &WP)
}
Finally, here is a self-contained AHK v2.0 example:

Code: Select all

WinSize := 400
MsgBox "
( Join
First, let's create a Notepad window and move it`n
to the bottom-right of the screen.
)"
Run "Notepad", , , pid
WinWaitActive "ahk_pid " pid
hwnd := WinExist("A")
MonitorGetWorkArea(, MonitorPosLeft, MonitorPosTop, MonitorPosRight, MonitorPosBottom)
WinMove MonitorPosRight-MonitorPosLeft-WinSize, MonitorPosBottom-MonitorPosTop-WinSize, WinSize, WinSize
MsgBox "Now, let's maximize it."
WinMaximize
MsgBox "
( Join
Now, let's restore and move the window using the built-in WinRestore and WinMove commands.`n`n
Note that the window is restored to the bottom-right and then quickly moved to the upper-left.
 The flicker is visible even when a delay of -1 is used in the SetWinDelay command.
)"
WinRestore
WinMove 0, 0
MsgBox "
( Join
Now, let's try with the WinRestorePlus() function.`n`n
First, let's move the window to the bottom-right of the screen.
)"
WinMove MonitorPosRight-MonitorPosLeft-WinSize, MonitorPosBottom-MonitorPosTop-WinSize, WinSize, WinSize
MsgBox "Now, let's maximize it again."
WinMaximize
MsgBox "
( Join
Now, let's restore and move the window using the WinRestorePlus() function.`n`n
Note that this is done in a single step, with no flicker, as the window is restored to the new position.
)"
WinRestorePlus(hwnd, 0, 0)
MsgBox "Now that we are done, let's close the window and quit."
WinClose
ExitApp

; =============================================================================================================================
; WinRestorePlus(hwnd:="", X:="", Y:="", W:="", H:="")
; Function:       Restore a window to a new set of coordinates/dimensions, regardless of its state (maximized, minimized, or normal).
;                 Combines the WinRestore and WinMove commands into one function with the benefit of no flicker.
;                 If the window is a normal window, this function will simply move/resize the window.
;                 If no parameters are specified, this function restores the active window, as in WinRestore, A.
; Tested with:    AHK 1.1.26.01 (A32/U32/U64)
;                 AHK 2.0-a081-cad307c (U32/U64)
; Tested on:      Win 7 (x64)
; Parameters:     hwnd - (Optional) The handle of the window being restored. If not specified, the active window will be restored.
;                 X    - (Optional) The x coordinate of the upper-left corner of the target window's new location*
;                 Y    - (Optional) The y coordinate of the upper-left corner of the target window's new location*
;                 W    - (Optional) The new width of the target window*
;                 H    - (Optional) The new height of the target window*
;                 *If a coordinate is not specified, the corresponding value of the window in its restored state is used.
; Return values:  nonzero if the window was successfully restored
;                 zero if the window was not successfully restored
; MSDN links:     https://msdn.microsoft.com/en-us/library/windows/desktop/ms633518(v=vs.85).aspx - GetWindowPlacement function
;                 https://msdn.microsoft.com/en-us/library/windows/desktop/ms633544(v=vs.85).aspx - SetWindowPlacement function
;                 https://msdn.microsoft.com/en-us/library/windows/desktop/ms632611(v=vs.85).aspx - WINDOWPLACEMENT structure
; =============================================================================================================================

WinRestorePlus(hwnd:="", X:="", Y:="", W:="", H:="") {
   hwnd := hwnd = "" ? WinExist("A") : hwnd
   VarSetCapacity(WP, 44, 0), NumPut(44, WP, "UInt")
   DllCall("User32.dll\GetWindowPlacement", "Ptr", hwnd, "Ptr", &WP)
   Lo := NumGet(WP, 28, "Int")        ; X coordinate of the upper-left corner of the window in its original restored state
   To := NumGet(WP, 32, "Int")        ; Y coordinate of the upper-left corner of the window in its original restored state
   Wo := NumGet(WP, 36, "Int") - Lo   ; Width of the window in its original restored state
   Ho := NumGet(WP, 40, "Int") - To   ; Height of the window in its original restored state
   L := X = "" ? Lo : X               ; X coordinate of the upper-left corner of the window in its new restored state
   T := Y = "" ? To : Y               ; Y coordinate of the upper-left corner of the window in its new restored state
   R := L + (W = "" ? Wo : W)         ; X coordinate of the bottom-right corner of the window in its new restored state
   B := T + (H = "" ? Ho : H)         ; Y coordinate of the bottom-right corner of the window in its new restored state
   NumPut(9, WP, 8, "UInt")           ; SW_RESTORE = 9
   NumPut(L, WP, 28, "Int")
   NumPut(T, WP, 32, "Int")
   NumPut(R, WP, 36, "Int")
   NumPut(B, WP, 40, "Int")
   Return DllCall("User32.dll\SetWindowPlacement", "Ptr", hwnd, "Ptr", &WP)
}
I hope you find it useful.

- iPhilip
Last edited by iPhilip on 07 Nov 2017, 16:02, edited 1 time in total.
Windows 10 Pro (64 bit) - AutoHotkey v2.0+ (Unicode 64-bit)
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: [Function] WinRestorePlus

07 Nov 2017, 14:19

Excellent demo, it works as promised. I didn't know there was a problem, I'm glad to have found the solution first :D.
Thanks for sharing, and nice to see v2 being used :thumbup: :clap:

Cheers.
burque505
Posts: 1736
Joined: 22 Jan 2017, 19:37

Re: [Function] WinRestorePlus

07 Nov 2017, 18:41

Thanks, iPhilip, works exactly as described on my Win7, 64-bit, AHK 1.1.26.01. I tried it with A32_L, U32_L, U64_L, A32_H, U32_H, and U64_H, all work great.
I appreciate you sharing it!
Regards,
burque505
ozzii
Posts: 481
Joined: 30 Oct 2013, 06:04

Re: [Function] WinRestorePlus

08 Nov 2017, 03:43

Great demo. thanks for this.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: [Function] WinRestorePlus

08 Nov 2017, 04:37

You've had some great Winapi finds. Cheers.
[Function] MsgBox Font Information - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=6&t=9122
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
RiseUp
Posts: 28
Joined: 01 Oct 2013, 21:27

Re: [Function] WinRestorePlus

08 Nov 2017, 11:21

Wow, I don't know what's more impressive—your well-designed and commented function, or your completely self-contained examples that clearly demonstrate the difference between the normal method and yours!

Well done! :bravo:
iPhilip
Posts: 822
Joined: 02 Oct 2013, 12:21

Re: [Function] WinRestorePlus

08 Nov 2017, 19:34

Helgef wrote:Excellent demo, it works as promised. I didn't know there was a problem, I'm glad to have found the solution first :D.
Thanks for sharing, and nice to see v2 being used :thumbup: :clap:
Thank you, Helgef. I appreciate your words of encouragement. The flicker is not a big problem, but I am glad to offer a solution to it. :)
burque505 wrote:Thanks, iPhilip, works exactly as described on my Win7, 64-bit, AHK 1.1.26.01. I tried it with A32_L, U32_L, U64_L, A32_H, U32_H, and U64_H, all work great.
I appreciate you sharing it!
Than you for all the testing, burque505. I am glad to share it with this community as I have learned so much from many people. :)
ozzii wrote:Great demo. thanks for this.
You are welcome. :)
jeeswg wrote:You've had some great Winapi finds. Cheers.
[Function] MsgBox Font Information - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=6&t=9122
I am glad you liked it, as well as the GetMsgBoxFontInfo and SetMsgBoxFontInfo functions in that earlier post. :)
RiseUp wrote:Wow, I don't know what's more impressive—your well-designed and commented function, or your completely self-contained examples that clearly demonstrate the difference between the normal method and yours!

Well done! :bravo:
Thank you! I am flattered and very appreciative of your comment. :)
Windows 10 Pro (64 bit) - AutoHotkey v2.0+ (Unicode 64-bit)

Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: No registered users and 244 guests