Jump to content

Gui - snap to grid


Recommended Posts

Try this.

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <SendMessage.au3>

Global Const $SC_DRAGMOVE = 0xF012

Global $ver = "Program Launcher 2.7"
Global $iW = 128
Global $iH = 170
Global $mainpos

Global $hGUI = GUICreate($ver, $iW, $iH, @DesktopWidth - $iW, (@DesktopHeight - $iH) / 2, BitOR($WS_SYSMENU, $WS_POPUP, $WS_BORDER), $WS_EX_TOOLWINDOW)
Global $ListView = GUICtrlCreateListView("col1|col2", 0, 30, $iW + 40, $iH - 40)
GUISetState(@SW_SHOW)

While 1
    Switch GUIGetMsg();check the gui for messages
        Case $GUI_EVENT_CLOSE ; Esc to exit
            Exit
        Case $GUI_EVENT_PRIMARYDOWN;if left mouse is clicked
            _SendMessage($hGUI, $WM_SYSCOMMAND, $SC_DRAGMOVE, 0);move the gui
            $mainpos = WinGetPos($ver)
            WinMove($ver, "", _RoundEx($mainpos[0], 75), _RoundEx($mainpos[1], 75))
    EndSwitch
WEnd


; Round up or down to nearest $x value eg. 4.185 to nearest 0.01 rounds up to 4.19
Func _RoundEx($n, $x = 1)
    If Round(Mod($n, $x), 8) < ($x / 2) Then
        Return Int($n / $x) * $x
    Else
        Return Ceiling($n / $x) * $x
    EndIf
EndFunc   ;==>_RoundEx
Link to comment
Share on other sites

I've been playing around with all these suggestion (just wanted to let you all know) to see if I could get something to work. So far not yet, but lots of interesting ideas.

010101000110100001101001011100110010000001101001011100110010000

001101101011110010010000001110011011010010110011100100001

My Android cat and mouse game
https://play.google.com/store/apps/details?id=com.KaosVisions.WhiskersNSqueek

We're gonna need another Timmy!

Link to comment
Share on other sites

  • 2 months later...

revisiting this thread as I think I've gotten somewhere, maybe

save this file as C:\Allin1move.au3

#include <Misc.au3>
#include <WinAPI.au3>
Opt("TrayIconHide", 1)
$activetitle = WinGetTitle("[active]")
$activewin = WinActive($activetitle)
$size = WinGetPos($activewin)
$winH = $size[3]
$winW = $size[2]
Global $__MonitorList[1][5]
$__MonitorList[0][0] = 0
Global $curres[2]
Global $resmatch = 1
Global $index = 0
;end setting variables
$mainmon = _GetMonitorFromPoint()
If $mainmon = 0 Then $mainmon = 1
$res1 = _GetMonitors()
$resx = $res1[$mainmon][3]
$resy = $res1[$mainmon][4]
$curres[0] = $resx
$curres[1] = $resy
$xgrid = $resx / $winW
$ygrid = ($resy - _GetTaskbarHeight()) / $winH
$xgridx = 0
$ygridy = 0
While _IsPressed(01)
 $size = WinGetPos($activewin)
 $mouse = MouseGetPos()
 $mainmon = _GetMonitorFromPoint($mouse[0], $mouse[1])
 If $mainmon = 0 Then $mainmon = 1
 $res1 = _GetMonitors()
 $resx = $res1[$mainmon][3]
 $resy = $res1[$mainmon][4]
 If (($curres[0] <> $resx And $curres[1] <> $resy) Or ($curres[0] = $resx And $curres[1] = $resy)) And $resmatch = 1 Then
  If $curres[0] <> $resx And $curres[1] <> $resy Then $resmatch = 0
  $xgrid = $resx / $winW
  $ygrid = ($resy - _GetTaskbarHeight()) / $winH
 ElseIf $curres[0] = $resx And $curres[1] = $resy And $resmatch = 0 Then
  $resmatch = 1
 EndIf
 For $gridx = 0 to $xgrid
  If $size[0] >= ($gridx * $winW - 30) And $size[0] <= ($gridx * $winW + 30) Then
   $xgridx = $gridx
   ExitLoop
  EndIf
 Next
    For $gridy = 0 to $ygrid
  If $size[1] >= ($gridy * $winH - 30) And $size[1] <= ($gridy * $winH + 30) Then
   $ygridy = $gridy
   ExitLoop
  EndIf
    Next
 If $xgridx <> $gridx Or $ygridy <> $gridy Then
  ;
 Else
  WinMove($activewin,"",$xgridx * $winW,$ygridy * $winH)
 EndIf
WEnd
;Thank you wakillon for this
Func _GetTaskbarHeight()
 Local Const $SPI_GETWORKAREA = 48
 Local $WorkArea, $stRect = DllStructCreate("long left;long top;long right;long bottom")
 Local $iResult = _WinAPI_SystemParametersInfo($SPI_GETWORKAREA, 0, DllStructGetPtr($stRect), 0)
 If $iResult = True Then
  $WorkArea = DllStructGetData($stRect, "bottom") - DllStructGetData($stRect, "top")
  If Not @error Then Return @DesktopHeight - $WorkArea
 EndIf
EndFunc   ;==>_GetTaskbarHeight
#Region thanks to xrxca for these functions
Func _GetMonitorFromPoint($XorPoint = 0, $y = 0)
 Local $MousePos, $myX, $myY
 If @NumParams = 0 Then
  $MousePos = MouseGetPos()
  $myX = $MousePos[0]
  $myY = $MousePos[1]
 ElseIf (@NumParams = 1) And IsArray($XorPoint) Then
  $myX = $XorPoint[0]
  $myY = $XorPoint[1]
 Else
  $myX = $XorPoint
  $myY = $y
 EndIf
 If $__MonitorList[0][0] == 0 Then
  _GetMonitors()
 EndIf
 Local $i = 0
 Local $Monitor = 0
 For $i = 1 To $__MonitorList[0][0]
  If ($myX >= $__MonitorList[$i][1]) _
    And ($myX < $__MonitorList[$i][3]) _
    And ($myY >= $__MonitorList[$i][2]) _
    And ($myY < $__MonitorList[$i][4]) Then $Monitor = $i
 Next
 Return $Monitor
EndFunc   ;==>_GetMonitorFromPoint
Func _GetMonitors()
 $__MonitorList[0][0] = 0 ;  Added so that the global array is reset if this is called multiple times
 Local $handle = DllCallbackRegister("_MonitorEnumProc", "int", "hwnd;hwnd;ptr;lparam")
 DllCall("user32.dll", "int", "EnumDisplayMonitors", "hwnd", 0, "ptr", 0, "ptr", DllCallbackGetPtr($handle), "lparam", 0)
 DllCallbackFree($handle)
 Local $i = 0
 For $i = 1 To $__MonitorList[0][0]
  If $__MonitorList[$i][1] < $__MonitorList[0][1] Then $__MonitorList[0][1] = $__MonitorList[$i][1]
  If $__MonitorList[$i][2] < $__MonitorList[0][2] Then $__MonitorList[0][2] = $__MonitorList[$i][2]
  If $__MonitorList[$i][3] > $__MonitorList[0][3] Then $__MonitorList[0][3] = $__MonitorList[$i][3]
  If $__MonitorList[$i][4] > $__MonitorList[0][4] Then $__MonitorList[0][4] = $__MonitorList[$i][4]
 Next
 Return $__MonitorList
EndFunc   ;==>_GetMonitors
Func _MonitorEnumProc($hMonitor, $hDC, $lRect, $lParam)
 Local $Rect = DllStructCreate("int left;int top;int right;int bottom", $lRect)
 $__MonitorList[0][0] += 1
 ReDim $__MonitorList[$__MonitorList[0][0] + 1][5]
 If $hDC = $hDC Then
 EndIf
 If $lParam = $lParam Then
 EndIf
 $__MonitorList[$__MonitorList[0][0]][0] = $hMonitor
 $__MonitorList[$__MonitorList[0][0]][1] = DllStructGetData($Rect, "left")
 $__MonitorList[$__MonitorList[0][0]][2] = DllStructGetData($Rect, "top")
 $__MonitorList[$__MonitorList[0][0]][3] = DllStructGetData($Rect, "right")
 $__MonitorList[$__MonitorList[0][0]][4] = DllStructGetData($Rect, "bottom")
 Return 1 ; Return 1 to continue enumeration
EndFunc   ;==>_MonitorEnumProc
#EndRegion thanks to xrxca for these functions

Run this program and when you click and drag, it will run the above code

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>
#include <Misc.au3>
#include <SendMessage.au3>
HotKeySet("{ESC}", "Terminate")
Global $ver = "Program Launcher 2.7"
$iW = 128
$iH = 170
$t = TimerInit();starts the timer in 't'
$q = 0
Global $__MonitorList[1][5]
$__MonitorList[0][0] = 0
Global $curres[2]
Global $resmatch = 1
Global Const $SC_DRAGMOVE = 0xF012
;end setting variables
$mainmon = _GetMonitorFromPoint()
If $mainmon = 0 Then $mainmon = 1
$res1 = _GetMonitors()
$resx = $res1[$mainmon][3]
$resy = $res1[$mainmon][4]
$curres[0] = $resx
$curres[1] = $resy
$hGUI = GUICreate($ver, $iW, $iH, @DesktopWidth - $iW, (@DesktopHeight - $iH) / 2, BitOR($WS_SYSMENU, $WS_POPUP, $WS_BORDER), $WS_EX_TOOLWINDOW)
$ListView = GUICtrlCreateListView("col1|col2", 0, 30, $iW + 40, $iH - 40)
GUISetState(@SW_SHOW)
While 1;start infinate loop
    Sleep(10);pause for 10 milliseconds
    $mainpos = WinGetPos($ver)
    $mainmon = _GetMonitorFromPoint($mainpos, $mainpos[1])
    If $mainmon = 0 Then $mainmon = 1
    $res1 = _GetMonitors()
    $resx = $res1[$mainmon][3]
    $resy = $res1[$mainmon][4]
    If $mainpos[0]+$mainpos[2] > $resx Then
            WinMove($ver,"",$resx-$mainpos[2],$mainpos[1])
        EndIf
        If $mainpos[0] < 0 Then
            WinMove($ver,"",0,$mainpos[1])
        EndIf
        If $mainpos[1]+$mainpos[3] > $resy - _GetTaskbarHeight() Then
            WinMove($ver,"",$mainpos[0],$resy-$mainpos[3] - _GetTaskbarHeight())
        EndIf
        If $mainpos[1] < 0 Then
            WinMove($ver,"",$mainpos[0],0)
        EndIf
    Switch GUIGetMsg();check the gui for messages
        Case $GUI_EVENT_PRIMARYDOWN;if left mouse is clicked
            $xgrid = $resx / $mainpos[2]
            $ygrid = ($resy - _GetTaskbarHeight()) / $mainpos[3]
            $wincol = WinList()
            $extrax = 2
            $extray = 2
            $wpos = WinGetPos($ver);get the position of the main gui
            $mpos = MouseGetPos();get the mouse position
            $ipos = ControlGetPos($ver, "", $ListView);get the list area
            If $mpos[0] > $wpos[0] + $ipos[0] + $extrax And $mpos[1] > $wpos[1] + $ipos[1] + $extray And $mpos[0] < $wpos[0] + $ipos[0] + $extrax + $ipos[2] And $mpos[1] < $wpos[1] + $ipos[1] + $extray + $ipos[3] Then
                If TimerDiff($t) <= 500 And $q = 1 Then;if left click is in the list area
                    MsgBox(0, "", "Double Clicked", 2)
                Else
                    $t = TimerInit();reset the timer
                    $q = 1
                EndIf
            ElseIf $mpos[0] > $wpos[0] + $extrax And $mpos[1] > $wpos[1] + $extray And $mpos[0] < $wpos[0] + $ipos[0] + $extrax + $ipos[2] And $mpos[1] < $wpos[1] + $ipos[1] + $extray + $ipos[3] Then
                ;if the click is not in the list but in the main gui
                While _IsPressed("01");while the left button is held
     ShellExecute("C:\Allin1move.au3")
                    _SendMessage($hGUI, $WM_SYSCOMMAND, $SC_DRAGMOVE, 0);move the gui
                WEnd
            EndIf
    EndSwitch
WEnd
Func _GetTaskbarHeight()
    Local Const $SPI_GETWORKAREA = 48
    Local $WorkArea, $stRect = DllStructCreate("long left;long top;long right;long bottom")
    Local $iResult = _WinAPI_SystemParametersInfo($SPI_GETWORKAREA, 0, DllStructGetPtr($stRect), 0)
    If $iResult = True Then
        $WorkArea = DllStructGetData($stRect, "bottom") - DllStructGetData($stRect, "top")
        If Not @error Then Return @DesktopHeight - $WorkArea
    EndIf
EndFunc   ;==>_GetTaskbarHeight
#Region thanks to xrxca for these functions
Func _GetMonitorFromPoint($XorPoint = 0, $y = 0)
    Local $MousePos, $myX, $myY
    If @NumParams = 0 Then
        $MousePos = MouseGetPos()
        $myX = $MousePos[0]
        $myY = $MousePos[1]
    ElseIf (@NumParams = 1) And IsArray($XorPoint) Then
        $myX = $XorPoint[0]
        $myY = $XorPoint[1]
    Else
        $myX = $XorPoint
        $myY = $y
    EndIf
    If $__MonitorList[0][0] == 0 Then
        _GetMonitors()
    EndIf
    Local $i = 0
    Local $Monitor = 0
    For $i = 1 To $__MonitorList[0][0]
        If ($myX >= $__MonitorList[$i][1]) _
                And ($myX < $__MonitorList[$i][3]) _
                And ($myY >= $__MonitorList[$i][2]) _
                And ($myY < $__MonitorList[$i][4]) Then $Monitor = $i
    Next
    Return $Monitor
EndFunc   ;==>_GetMonitorFromPoint
Func _GetMonitors()
    $__MonitorList[0][0] = 0 ;  Added so that the global array is reset if this is called multiple times
    Local $handle = DllCallbackRegister("_MonitorEnumProc", "int", "hwnd;hwnd;ptr;lparam")
    DllCall("user32.dll", "int", "EnumDisplayMonitors", "hwnd", 0, "ptr", 0, "ptr", DllCallbackGetPtr($handle), "lparam", 0)
    DllCallbackFree($handle)
    Local $i = 0
    For $i = 1 To $__MonitorList[0][0]
        If $__MonitorList[$i][1] < $__MonitorList[0][1] Then $__MonitorList[0][1] = $__MonitorList[$i][1]
        If $__MonitorList[$i][2] < $__MonitorList[0][2] Then $__MonitorList[0][2] = $__MonitorList[$i][2]
        If $__MonitorList[$i][3] > $__MonitorList[0][3] Then $__MonitorList[0][3] = $__MonitorList[$i][3]
        If $__MonitorList[$i][4] > $__MonitorList[0][4] Then $__MonitorList[0][4] = $__MonitorList[$i][4]
    Next
    Return $__MonitorList
EndFunc   ;==>_GetMonitors
Func _MonitorEnumProc($hMonitor, $hDC, $lRect, $lParam)
    Local $Rect = DllStructCreate("int left;int top;int right;int bottom", $lRect)
    $__MonitorList[0][0] += 1
    ReDim $__MonitorList[$__MonitorList[0][0] + 1][5]
    If $hDC = $hDC Then
    EndIf
    If $lParam = $lParam Then
    EndIf
    $__MonitorList[$__MonitorList[0][0]][0] = $hMonitor
    $__MonitorList[$__MonitorList[0][0]][1] = DllStructGetData($Rect, "left")
    $__MonitorList[$__MonitorList[0][0]][2] = DllStructGetData($Rect, "top")
    $__MonitorList[$__MonitorList[0][0]][3] = DllStructGetData($Rect, "right")
    $__MonitorList[$__MonitorList[0][0]][4] = DllStructGetData($Rect, "bottom")
    Return 1 ; Return 1 to continue enumeration
EndFunc   ;==>_MonitorEnumProc
#EndRegion thanks to xrxca for these functions
Func Terminate()
    Exit 0
EndFunc   ;==>Terminate

basically it's mostly working (I realized I would probably need a second script to monitor the window position since _sendmessage is a blocking function)

I would just like to see if there is a way I can clean up to top script to keep the gui from flickering when it gets close to a "grid-line"

010101000110100001101001011100110010000001101001011100110010000

001101101011110010010000001110011011010010110011100100001

My Android cat and mouse game
https://play.google.com/store/apps/details?id=com.KaosVisions.WhiskersNSqueek

We're gonna need another Timmy!

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...