Jump to content

Snaping Gui's


Recommended Posts

how can you have multple guis, that snap together when in the corner of another one?

Could you just keep checking the positions, and if an edge is closer than some value then move the window to the edge?
Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

that doesnt really help, 'cause, i just want it for the three gui i have, not everything. But i guess ill have to live without it for now. thanks for your help everyone

[font=Microsoft Sans Serif]My Scripts: From Most recent to least.[/font]Countdown GUI | QLOCK TWO | FlipClock | Slot Machine My UDF:_GenerateRandomNoRepeat | _GuiSnap

Link to comment
Share on other sites

that doesnt really help, 'cause, i just want it for the three gui i have, not everything. But i guess ill have to live without it for now. thanks for your help everyone

No way.

Just try some logic with: WinGetPos() and WinMove().

Get the positions, compare and set the position if any window is near to another.

e.g.: If mywin1_posx >= mywin2_posx and ...etc

Of course, you need write that according to your needs. :)

Link to comment
Share on other sites

I've come across no way in autoit to read/manipulate window positions UNTIL they have been dropped. I made a thread about the same thing a little while back, but got no answers ( http://www.autoitscript.com/forum/index.ph...c=47380&hl= ).

If anyone knows how to read a window position WHILE IT IS BEING MOVED, so you can only see the rectangle/outline of the window moving, I would be very grateful, and could help you with this... I know it's possible seeing as allSnap does it, but he would not let me see the source code to it...

Link to comment
Share on other sites

Ok, I went ahead and wrote a function and a small demo for what you wanted. I know it's not perfect, it always moves the first of the GUIs that it tests instead of the most active one, it will snap vertically even if they are nowhere near each other horizontally and visa-versa... But it should be enough to give you a start.

$snapRange = how many pixels it will snap within, IE if one window is @ 345x and another is at 360x, they will snap if $snapRange = 15, but not if it equals 10

$GUI1-10 = hwnd of your GUIs. Just make sure they aren't named $GUI1, $GUI2, etc.

$num = number of GUIs being tested (VERY IMPORTANT TO GET THIS NUMBER RIGHT!)

I used adLibEnable to call my function once a second, but you can just put it in the while loop, or only call it when a window has been moved/resized, whatever you want.

That's about it... Good luck.

#include <GUIConstants.au3>

$1 = GUICreate("Test", 233, 454, 193, 115)
GUISetState(@SW_SHOW)
$2 = GUICreate("Test2", 233, 454, 693, 115, -1, -1, $1)
GUISetState(@SW_SHOW)
AdlibEnable("_call", 1000)

While 1
    $msg = GUIGetMsg()
    If $msg = $GUI_EVENT_CLOSE Then Exit
WEnd

Func _call()
    _alignGUIs(2, 10, $1, $2)
EndFunc

Func _alignGUIs($num, $snapRange, $GUI1, $GUI2, $GUI3 = 0, $GUI4 = 0, $GUI5 = 0, $GUI6 = 0, $GUI7 = 0, $GUI8 = 0, $GUI9 = 0, $GUI10 = 0)
    Dim $GUIs[$num]
    If $GUI1 <> 0 Then $GUIs[0] = $GUI1
    If $GUI2 <> 0 Then $GUIs[1] = $GUI2
    If $GUI3 <> 0 Then $GUIs[2] = $GUI3
    If $GUI4 <> 0 Then $GUIs[3] = $GUI4
    If $GUI5 <> 0 Then $GUIs[4] = $GUI5
    If $GUI6 <> 0 Then $GUIs[5] = $GUI6
    If $GUI7 <> 0 Then $GUIs[6] = $GUI7
    If $GUI8 <> 0 Then $GUIs[7] = $GUI8
    If $GUI9 <> 0 Then $GUIs[8] = $GUI9
    If $GUI10 <> 0 Then $GUIs[9] = $GUI10   
    For $i = 0 to $num - 1
        For $j = 0 to $num - 1
            If $i <> $j Then
                $pos1 = WinGetPos($GUIs[$i])
                $pos2 = WinGetPos($GUIs[$j])
                    If Abs($pos1[0] - $pos2[0]) <= $snapRange and Abs($pos1[0] - $pos2[0]) <> 0 Then ; Horizontal in left snapping
                        If $pos1[0] < $pos2[0] Then WinMove($GUIs[$i], "", $pos1[0] + Abs($pos1[0] - $pos2[0]), Default)
                        If $pos1[0] > $pos2[0] Then WinMove($GUIs[$i], "", $pos1[0] - Abs($pos1[0] - $pos2[0]), Default)
                    EndIf
                    If Abs($pos1[1] - $pos2[1]) <= $snapRange and Abs($pos1[1] - $pos2[1]) <> 0 Then ; Vertical in top snapping
                        If $pos1[1] < $pos2[1] Then WinMove($GUIs[$i], "", Default, $pos1[1] + Abs($pos1[1] - $pos2[1]))
                        If $pos1[1] > $pos2[1] Then WinMove($GUIs[$i], "", Default, $pos1[1] - Abs($pos1[1] - $pos2[1]))
                    EndIf
                    If Abs($pos1[0] + $pos1[2] - $pos2[0]) <= $snapRange and Abs($pos1[0] + $pos1[2] - $pos2[0]) <> 0 Then ; Horizontal out right snapping
                        If $pos1[0] + $pos1[2] < $pos2[0] Then WinMove($GUIs[$i], "", $pos1[0] + Abs($pos1[0] + $pos1[2] - $pos2[0]), Default)
                        If $pos1[0] + $pos1[2] > $pos2[0] Then WinMove($GUIs[$i], "", $pos1[0] - Abs($pos1[0] + $pos1[2] - $pos2[0]), Default)
                    EndIf
                    If Abs($pos1[0] - $pos2[0] + $pos2[2]) <= $snapRange and Abs($pos1[0] - $pos2[0] + $pos2[2]) <> 0 Then ; Horizontal out left snapping
                        If $pos1[0] < $pos2[0] + $pos2[2] Then WinMove($GUIs[$i], "", $pos1[0] + Abs($pos1[0] - $pos2[0] + $pos2[2]), Default)
                        If $pos1[0] > $pos2[0] + $pos2[2] Then WinMove($GUIs[$i], "", $pos1[0] - Abs($pos1[0] - $pos2[0] + $pos2[2]), Default)
                    EndIf
                    If Abs($pos1[1] + $pos1[3] - $pos2[1]) <= $snapRange and Abs($pos1[1] + $pos1[3] - $pos2[1]) <> 0 Then ; Vertical out bottom snapping
                        If $pos1[1] + $pos1[3] < $pos2[1] Then WinMove($GUIs[$i], "", Default, $pos1[1] + Abs($pos1[1] + $pos1[3] - $pos2[1]))
                        If $pos1[1] + $pos1[3] > $pos2[1] Then WinMove($GUIs[$i], "", Default, $pos1[1] - Abs($pos1[1] + $pos1[3] - $pos2[1]))
                    EndIf
                    If Abs($pos1[1] - $pos2[1] + $pos2[3]) <= $snapRange and Abs($pos1[1] - $pos2[1] + $pos2[3]) <> 0 Then ; Vertical out top snapping
                        If $pos1[1] < $pos2[1] + $pos2[3] Then WinMove($GUIs[$i], "", Default, $pos1[1] + Abs($pos1[1] - $pos2[1] + $pos2[3]))
                        If $pos1[1] > $pos2[1] + $pos2[3] Then WinMove($GUIs[$i], "", Default, $pos1[1] - Abs($pos1[1] - $pos2[1] + $pos2[3]))
                    EndIf   
            EndIf
        Next
    Next
EndFunc

Oh! And this is NOT Vista compatible (with Aero theme) you will have to modify the code slightly, seeing as windows don't line up perfectly, due to the drop shadow or some other effect...

Edited by magician13134
Link to comment
Share on other sites

How about using old good WM_WINDOWPOSCHANGING message?

#include <GUIConstants.au3>

Global Const $WM_WINDOWPOSCHANGING = 0x0046 

Global $nGap = 20

Global $ahGUI[3] 

$ahGUI[0] = GUICreate("Snapped window 1", 300, 200, 100, 100)
GUISetState()

$ahGUI[1] = GUICreate("Snapped window 2", 300, 400, 300, 400)
GUISetState()

$ahGUI[2] = GUICreate("Snapped window 3", 150, 300, 500, 100)
GUISetState()


GUIRegisterMsg($WM_WINDOWPOSCHANGING, "MY_WM_WINDOWPOSCHANGING")

While 1
    $GUIMsg = GUIGetMsg()
    
    Switch $GUIMsg
        Case $GUI_EVENT_CLOSE
            ExitLoop
    EndSwitch
WEnd


Func MY_WM_WINDOWPOSCHANGING($hWnd, $Msg, $wParam, $lParam)
    Local $stWinPos = DllStructCreate("uint;uint;int;int;int;int;uint", $lParam)

    Local $nLeft   = DllStructGetData($stWinPos, 3)
    Local $nTop    = DllStructGetData($stWinPos, 4)

    $pos_cur = WinGetPos($hWnd)

    For $i = 0 To UBound($ahGUI) - 1
        If $hWnd = $ahGUI[$i] Then ContinueLoop
        $pos_win = WinGetPos($ahGUI[$i])

        If Abs(($pos_win[0] + $pos_win[2]) - $nLeft) <= $nGap Then DllStructSetData($stWinPos, 3, $pos_win[0] + $pos_win[2])
        If Abs($nLeft + $pos_cur[2] - $pos_win[0]) <= $nGap Then DllStructSetData($stWinPos, 3, $pos_win[0] - $pos_cur[2])

        If Abs(($pos_win[1] + $pos_win[3]) - $nTop) <= $nGap Then DllStructSetData($stWinPos, 4, $pos_win[1] + $pos_win[3])
        If Abs($nTop + $pos_cur[3] - $pos_win[1]) <= $nGap Then DllStructSetData($stWinPos, 4, $pos_win[1] - $pos_cur[3])
    Next
    
    Return 0
EndFunc

Of course, it's a bit messy and sloppy too, but you can add additional checks to make this more fine.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...