Code: Select all
SysGet, VirtualWidth, 78
SysGet, VirtualHeight, 79
loop
{
winGetPos,x,y,,,A
tooltip % VirtualWidth . " " . VirtualHeight . "`n" . x . " " . y ;want x and y to always be positive no matter layout or main monitor setting
sleep 50
}
Code: Select all
SysGet, VirtualWidth, 78
SysGet, VirtualHeight, 79
loop
{
winGetPos,x,y,,,A
tooltip % VirtualWidth . " " . VirtualHeight . "`n" . x . " " . y ;want x and y to always be positive no matter layout or main monitor setting
sleep 50
}
Code: Select all
SysGet, VirtualWidth, 78
SysGet, VirtualHeight, 79
loop
{
Pos := WinGetRelativePos("A")
ToolTip, % VirtualWidth . " " . VirtualHeight . "`n" . Pos.x . " " . Pos.y
Sleep, 50
}
return
WinGetRelativePos(winTitle) {
SysGet, monNum, MonitorPrimary
SysGet, mon, Monitor, % monNum
WinGetPos, x, y,,, % winTitle
return {x: x - monLeft, y: y - monTop}
}
Code: Select all
WinGetRelativePos(winTitle) {
SysGet, mon, Monitor, 2
WinGetPos, x, y,,, % winTitle
return {x: x - monLeft, y: y - monTop}
}
Code: Select all
SysGet, VirtualWidth, 78
SysGet, VirtualHeight, 79
loop
{
Pos := WinGetRelativePos("A")
ToolTip, % VirtualWidth . " " . VirtualHeight . "`n" . Pos.x . " " . Pos.y
Sleep, 50
}
return
WinGetRelativePos(winTitle="A") {
WinGetPos, x, y,,, % winTitle
PosIsOnMonitor(x, y, monLeft, monTop)
return {x: x - monLeft, y: y - monTop}
}
PosIsOnMonitor(Mx, My, ByRef MonLeft, ByRef MonTop) {
; Get the dimensions of all monitors.
SysGet, MonCount, MonitorCount
Loop, % MonCount
{
SysGet, Mon, Monitor, % A_Index
LastMon := A_Index
; Check if the position is on this monitor.
If IsBetween(Mx, MonLeft, MonRight, "Lower") AND IsBetween(My, MonTop, MonBottom, "Lower") {
Break ; Leave MonLeft, MonRight, MonTop and MonBottom as is and continue.
}
}
Return LastMon
}
IsBetween(Value, LowerLimit, UpperLimit, IncludingLimit:="0") {
If (IncludingLimit = "0") {
If (Value > LowerLimit) AND (Value < UpperLimit) {
Return True
} Else {
Return False
}
} Else If (IncludingLimit = "Lower") {
If (Value >= LowerLimit) AND (Value < UpperLimit) {
Return True
} Else {
Return False
}
} Else If (IncludingLimit = "Upper") {
If (Value > LowerLimit) AND (Value <= UpperLimit) {
Return True
} Else {
Return False
}
} Else If (IncludingLimit = "1") {
If (Value >= LowerLimit) AND (Value <= UpperLimit) {
Return True
} Else {
Return False
}
}
}
Code: Select all
#singleinstance Force
#persistent
setBatchLines -1
coordMode,Mouse,screen
polyBorder := new boxExplodeObj(type := "SCREEN")
xoffset := polyBorder.minX
yoffset := polyBorder.minY
setTimer showMouse,20
return
showMouse:
mouseGetPos,x,y
mx := x - xoffset
my := y - yoffset
winGetPos,wx,wy,,,A
tooltip % "corrected mouse coords : " mx . "," . my . "`nraw window coords : " . wx . "," . wy . "`ncorrected window coords : " . wx - xoffset . "," . wy - yoffset . "`npoint on screen : " . polyBorder.pointInPoly(new ptObj(wx,wy)) . "`nwindow on screen : " . polyBorder.windowInPoly("A")
return
class ptObj
{
__new(x,y)
{
this.x := x
this.y := y
}
}
class boxExplodeObj
{
__new(type := "")
{
this.ptArr := {}
this._maxX := ""
this._maxY := ""
this._minX := ""
this._minY := ""
this._border := []
if(type == "SCREEN") ;if type is empty then source points will need to be manually added by user
{
SysGet, numMons, MonitorCount
loop % numMons
{
SysGet, mon, Monitor, % A_index
ul := new ptObj(monLeft,monTop)
ur := new ptObj(monRight,monTop)
lr := new ptObj(monRight,monBottom)
ll := new ptObj(monLeft,monBottom)
;add corner points to scatter buffer
this.add(ul)
this.add(ur)
this.add(lr)
this.add(ll)
}
}
}
maxX[]
{
get
{
if(!this._maxX)
{
init := this.border
}
return this._maxX
}
}
maxY[]
{
get
{
if(!this._maxY)
{
init := this.border
}
return this._maxY
}
}
minX[]
{
get
{
if(!this._minX)
{
init := this.border
}
return this._minX
}
}
minY[]
{
get
{
if(!this._minY)
{
init := this.border
}
return this._minY
}
}
border[]
{
get
{
if(!this._border._maxIndex())
{
this._border := this.collapse()
;set extents
minX := 10000000000000
minY := 10000000000000
maxX := -10000000000000
maxY := -10000000000000
for index,pt in this._border
{
if(pt.x<minX)
{
minX := pt.x
}
if(pt.x>maxX)
{
maxX := pt.x
}
if(pt.y > maxY)
{
maxY := pt.y
}
if(pt.y < minY)
{
minY := pt.y
}
}
this._minX := minX
this._maxX := maxX
this._minY := minY
this._maxY := maxY
}
return this._border
}
}
pointInPoly(pt) ;raycast point check : https://stackoverflow.com/questions/11716268/point-in-polygon-algorithm
{
inPoly := false
b := this.border
loop % b._maxIndex() - 1
{
p1 := b[A_index]
p2 := b[A_index +1]
if((p1.y <= pt.y) && (p2.y > pt.y) || (p2.y <= pt.y) && (p1.y > pt.y))
{
cross := (p2.x - p1.x)*(pt.y - p1.y)/(p2.y - p1.y) + p1.x
if(cross < pt.x)
{
inPoly := !inPoly
}
}
}
return inPoly
}
windowInPoly(winName)
{
WinGet, mm, MinMax , %winName%
if(mm)
{
return true
}
winGetPos,x,y,w,h,%winName%
r := 0
r += this.pointInPoly(new ptObj(x,y),this.border)
r += this.pointInPoly(new ptObj(x,y+h),this.border)
r += this.pointInPoly(new ptObj(x+w,y+h),this.border)
r += this.pointInPoly(new ptObj(x+w,y),this.border)
if(r == 4)
{
return true
}
return false
}
add(pt)
{
ptKey := pt.x . "," . pt.y
if(this.ptArr.hasKey(ptKey))
{
this.ptArr.Delete(ptKey)
}
else
{
this.ptArr[ptKey] := pt
}
}
toBasicArray(arr) ;converts associative array to basic
{
result := []
for ptKey,pt in arr
{
result.push(pt)
}
return result
}
sortXtY() ;sorts points by x then by y
{
tempArr := this.toBasicArray(this.ptArr)
sorted :=[]
loop % this.ptArr.count()
{
minVal := 10000000000000
minIndex := 0
for index,pt in tempArr
{
if(pt.x<minVal)
{
minPt := pt
minIndex := index
minVal := pt.x
}
}
offset := 0
loop
{
checkPt := sorted[sorted._maxIndex()-offset]
if(checkPt.x == minPt.x)
{
if(minPt.y>checkPt.y) ;valid position so add
{
sorted.insertAt(sorted._maxIndex()-offset+1,minPt)
break
}
}
else
{
if(offset) ;offset involved where change in x found but min on y
{
sorted.insertAt(sorted._maxIndex()-offset+1,minPt)
}
else ;new x value on end of stack
{
sorted.push(minPt)
}
break
}
offset++
}
tempArr.RemoveAt(minIndex)
}
return sorted
}
sortYtX() ;sorts points by y then by x
{
tempArr := this.toBasicArray(this.ptArr)
sorted :=[]
loop % this.ptArr.count()
{
minVal := 10000000000000
minIndex := 0
for index,pt in tempArr
{
if(pt.y<minVal)
{
minPt := pt
minIndex := index
minVal := pt.y
}
}
offset := 0
loop
{
checkPt := sorted[sorted._maxIndex()-offset]
if(checkPt.y == minPt.y)
{
if(minPt.x>checkPt.x) ;valid position so add
{
sorted.insertAt(sorted._maxIndex()-offset+1,minPt)
break
}
}
else
{
if(offset) ;offset involved where change in x found but min on y
{
sorted.insertAt(sorted._maxIndex()-offset+1,minPt)
}
else ;new x value on end of stack
{
sorted.push(minPt)
}
break
}
offset++
}
tempArr.RemoveAt(minIndex)
}
return sorted
}
collapse() ;https://stackoverflow.com/questions/13746284/merging-multiple-adjacent-rectangles-into-one-polygon
{
;breaks multiple touching rectangles into a minimum edge simplified polygon
;algorithm on website will detect nested polygons. we only need exterior poly so it can be simplified
if(!this.ptArr.count())
{
msgbox ,,Error,Need to add border points to object before operating on it
reload
}
sortX := this.sortXtY()
sortY := this.sortYtX()
edgesH := {}
i := 1
while(i < this.ptArr.count()) ;link horizontal segments
{
currY := sortY[i].y
while(i < this.ptArr.count() && sortY[i].y == currY)
{
edgesH[sortY[i]] := sortY[i+1]
edgesH[sortY[i+1]] := sortY[i]
i += 2
}
}
edgesV := {}
i := 1
while(i < this.ptArr.count()) ;link vertical segments
{
currX := sortY[i].x
while(i < this.ptArr.count() && sortY[i].x == currX)
{
edgesV[sortX[i]] := sortX[i+1]
edgesV[sortX[i+1]] := sortX[i]
i += 2
}
}
while(edgesH.count()>1)
{
for startPt ,matchPt in edgesH
{
break
}
poly := []
poly.push(startPt)
poly.push(0)
edgesH.Delete(startPt)
loop
{
lastPt := poly[poly._maxIndex()-1]
flag := poly[poly._maxIndex()]
if(flag)
{
nextPt := edgesH[lastPt]
edgesH.Delete(lastPt)
poly.pop() ;remove last flag
poly.push(nextPt)
poly.push(0) ;next flag
}
else
{
nextPt := edgesV[lastPt]
edgesV.Delete(lastPt)
poly.pop() ;remove last flag
poly.push(nextPt)
poly.push(1) ;next flag
}
if(poly[1] == nextPt) ;chain is closed
{
poly.pop() ;remove last flag
poly.pop() ;remove duplicate end point chain is complete
return poly
}
}
}
}
}
Users browsing this forum: Descolada and 95 guests