WinMoveZ() : Moves, but confines a window to the work area of target monitor

Post your working scripts, libraries and tools for AHK v1.1 and older
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

WinMoveZ() : Moves, but confines a window to the work area of target monitor

01 Jun 2020, 10:21

The function:

Code: Select all

WinMoveZ(hWnd, C, X, Y, W, H, Redraw:=0) { ;  WinMoveZ v0.5 by SKAN on D35V/D361 @ tiny.cc/winmovez 
Local V:=VarSetCapacity(R,48,0), A:=&R+16, S:=&R+24, E:=&R, NR:=&R+32, TPM_WORKAREA:=0x10000
  C:=( C:=Abs(C) ) ? DllCall("SetRect", "Ptr",&R, "Int",X-C, "Int",Y-C, "Int",X+C, "Int",Y+C) : 0
  DllCall("SetRect", "Ptr",&R+16, "Int",X, "Int",Y, "Int",W, "Int",H)
  DllCall("CalculatePopupWindowPosition", "Ptr",A, "Ptr",S, "UInt",TPM_WORKAREA, "Ptr",E, "Ptr",NR)
  X:=NumGet(NR+0,"Int"),  Y:=NumGet(NR+4,"Int")
Return DllCall("MoveWindow", "Ptr",hWnd, "Int",X, "Int",Y, "Int",W, "Int",H, "Int",Redraw)
}



WinMoveZ(hWnd, C, X, Y, W, H [, Redraw])
Moves a window like WinMove, but confines the window within the work area of the target monitor.

  • What WinMoveZ() will not do? : It will not move a window offscreen
  • What WinMoveZ() will do? : Confine a window within the work area of target monitor.
  • Which target monitor? : Whichever monitor POINT (X, Y) belongs to
  • What if POINT doesn't belong to any monitor? : The monitor nearest to the POINT will house the window.
  • Can you explain parameters? : Except second parameter others are passed to MoveWindow which is similar to WinMove
    DllCall("MoveWindow", "Ptr",hWnd, "Int",X, "Int",Y, "Int",W, "Int",H, "Int",Redraw)
  • What is the second parameter C required for? : It is like a social distancing (in pixels) to be maintained between cursor hotspot and your POINT (X, Y)
    This parameter should be used only if you're calling WinMoveZ() from a loop/timer, to move a window to follow your mouse. (Try example #2)
    A value of 16 should be good. That is, 16x16 = 256 pixels surrounding the cursor hotspot will be excluded from work area.
  • Bordered windows are not moved correctly? : Apparently. I will update the topic if I find my own solution.
  • Example #1 : Show a notification at right bottom corner of primary monitor

    Code: Select all

    #SingleInstance, Force
    Gui, New, -Caption +Border +AlwaysOnTop +Disabled +Owner +hWndhWnd
    Gui, Font, s20, Segoe UI
    Gui, Add, Text,, Hello World !
    Gui, Show, Hide
    DetectHiddenWindows, On
    WinGetPos, X, Y, W, H, ahk_id %hWnd%
    WinMoveZ(hWnd, 0, A_ScreenWidth-1, A_ScreenHeight-1, W, H)
    DetectHiddenWindows, Off
    Gui, Show, NA
    Return
    

  • Example #2 : A window follows the mouse while maintaining a 16 pixels distance.

    Code: Select all

    #NoEnv
    #SingleInstance, Force
    CoordMode, Mouse, Screen
    CoordMode, Pixel, Screen
    
    Gui New, -Caption +Border +hWndhWnd +Disabled +AlwaysOnTop
    Gui, Margin, 15, 30
    Gui, Add, Edit, w60 Center, FFFFFF
    Gui, Show
    
    WinGetPos, X, Y, W, H, ahk_id %hWnd%
    PX:=X, PY:=Y
    Loop
    {
      MouseGetPos, X, Y
      If ! (X=PX and Y=PY)                          
        { 
          WinMoveZ(hWnd, 16, X, Y, W, H), PX:=X, PY:=Y
          PixelGetColor, C, %X%, %Y%, RGB
          Gui, Color, % PC:=C
          GuiControl,,Edit1, % Format("{:06X}",C)
        }       
      Sleep 50  
    }
    
    
    F2::Gui +AlwaysOnTop
    Esc:: ExitApp
    
My Scripts and Functions: V1  V2
User avatar
Cerberus
Posts: 172
Joined: 12 Jan 2016, 15:46

Re: WinMoveZ() : Moves, but confines a window to the work area of target monitor

01 Jun 2020, 17:32

This looks very useful! great work. So it says "confine": suppose the window would be placed partly outside the screen, what would happen: Would the window keep the same size but be moved such that it is entirely inside the screen? Or will it be resized at the sides that partly fall outside the window? (I would be really interested in the latter for a script I'm working on.)
User avatar
Delta Pythagorean
Posts: 627
Joined: 13 Feb 2017, 13:44
Location: Somewhere in the US
Contact:

Re: WinMoveZ() : Moves, but confines a window to the work area of target monitor

01 Jun 2020, 18:50

With how compact you confine your functions, I'd almost expect you to create a full UI in less than a few lines :D

[AHK]......: v2.0.12 | 64-bit
[OS].......: Windows 11 | 23H2 (OS Build: 22621.3296)
[GITHUB]...: github.com/DelPyth
[PAYPAL]...: paypal.me/DelPyth
[DISCORD]..: tophatcat

User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Re: WinMoveZ() : Moves, but confines a window to the work area of target monitor

01 Jun 2020, 18:54

@Cerberus
will it be resized at the sides that partly fall outside the window?
No
Would the window keep the same size but be moved such that it is entirely inside the screen?
Yes. This function is loosely based on the functionality of Tooltip command.
A Tooltip will never go offscreen. for eg: Tooltip, Hello World, % A_ScreenWidth-1, A_ScreenWidth-1
will confine it inside the right bottom of the primary monitor.

Also, if you run the following code on a multi-monitor setup..

Code: Select all

Loop
{
  Tooltip, Hello World
  Sleep 0
}
.. you will notice that the Tooltip is always confined to whichever monitor the mouse cursor is on... without losing its dimensions.
In other words, a Tooltip doesn't seem to span between monitors. It simply jumps over to the monitor the cursor is in.

Thanks for the feedback. :)
My Scripts and Functions: V1  V2
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Re: WinMoveZ() : Moves, but confines a window to the work area of target monitor

01 Jun 2020, 19:20

Delta Pythagorean wrote:how compact you confine your functions,
Confine to 11 lines or less.. So that "Expand view" doesn't appear on the [code] box :D
My Scripts and Functions: V1  V2
User avatar
SirSocks
Posts: 360
Joined: 26 Oct 2018, 08:14

Re: WinMoveZ() : Moves, but confines a window to the work area of target monitor

01 Jun 2020, 22:15

@SKAN you write amazing code! This seems very useful! Thank you so much for sharing your code with the community. :clap:
By the way I can't get enough of xstr().
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Re: WinMoveZ() : Moves, but confines a window to the work area of target monitor

02 Jun 2020, 06:52

Thank you @SirSocks :)
My Scripts and Functions: V1  V2
guest3456
Posts: 3463
Joined: 09 Oct 2013, 10:31

Re: WinMoveZ() : Moves, but confines a window to the work area of target monitor

30 Apr 2023, 13:27

SKAN wrote:
01 Jun 2020, 10:21
The function:

Code: Select all

WinMoveZ(hWnd, C, X, Y, W, H, Redraw:=0) { ;  WinMoveZ v0.5 by SKAN on D35V/D361 @ tiny.cc/winmovez 
Local V:=VarSetCapacity(R,48,0), A:=&R+16, S:=&R+24, E:=&R, NR:=&R+32, TPM_WORKAREA:=0x10000
  C:=( C:=Abs(C) ) ? DllCall("SetRect", "Ptr",&R, "Int",X-C, "Int",Y-C, "Int",X+C, "Int",Y+C) : 0
  DllCall("SetRect", "Ptr",&R+16, "Int",X, "Int",Y, "Int",W, "Int",H)
  DllCall("CalculatePopupWindowPosition", "Ptr",A, "Ptr",S, "UInt",TPM_WORKAREA, "Ptr",E, "Ptr",NR)
  X:=NumGet(NR+0,"Int"),  Y:=NumGet(NR+4,"Int")
Return DllCall("MoveWindow", "Ptr",hWnd, "Int",X, "Int",Y, "Int",W, "Int",H, "Int",Redraw)
}
why do you declare the variables with the local keyword, which ends up making the function itself assume-global?

TAC109
Posts: 1112
Joined: 02 Oct 2013, 19:41
Location: New Zealand

Re: WinMoveZ() : Moves, but confines a window to the work area of target monitor

30 Apr 2023, 17:27

Not Skan, but it is to avoid possible warnings when #Warn is used in the included script. As all variables are defined either under Local or as parameters to the function, there are no assume-global variables.

Hope this helps.
My scripts:-
XRef - Produces Cross Reference lists for scripts
ReClip - A Text Reformatting and Clip Management utility
ScriptGuard - Protects Compiled Scripts from Decompilation
I also maintain Ahk2Exe

Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: No registered users and 78 guests