Jump to content

Screen calipers


WideBoyDixon
 Share

Recommended Posts

I was looking at this and was wondering whether I'd be able to re-create using AutoIt. Below is what I managed to create. I've lifted quite a bit of code from a couple of other scripts which can be found here and here so thanks to those coders (you know who you are :P)

Basic instructions:

Use the mouse to drag the two triangles so that the points are on the pixels you want to measure between. When the mouse is held down you can use the arrow keys to fine tune the selection. The zoom window shows the region around the triangles (when they are being moved) or around the current mouse location (when not). You can use PageUp and PageDown to change the zoom factor for the zoom window. Exit the tool by closing the zoom window.

Have fun.

WBD

#include <Constants.au3>
#include <GUIConstants.au3>
#include <GUIConstantsEx.au3>
#include <Misc.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>

Opt("MustDeclareVars", 1)

Global $hwndMove = 0, $mouseStart, $winStart
Global Const $WM_LBUTTONDOWN = 0x201
Global Const $WM_LBUTTONDBCLICK = 0x203

Global $SIZEX = 256
Global $SIZEY = 256
Local $GUIZoom = GUICreate("Zoom", $SIZEX, $SIZEY, 0, 0, BitOR($WS_SYSMENU, $WS_BORDER, $WS_CAPTION), $WS_EX_TOPMOST)
GUISetBkColor(0xEEEEEE)
GUISetState()
Global $GUI1 = GUICreate("", 24, 24, -1, -1, $WS_POPUP, $WS_EX_TOOLWINDOW + $WS_EX_TOPMOST)
GUISetBkColor(0x00ff00)
Local $rgn = CreateTriangleRgn(0, 0, 0, 24, 24, 0)
SetWindowRgn($GUI1, $rgn)
GUISetState()
Global $GUI2 = GUICreate("", 24, 24, -1, -1, $WS_POPUP, $WS_EX_TOOLWINDOW + $WS_EX_TOPMOST)
GUISetBkColor(0x0000ff)
$rgn = CreateTriangleRgn(24, 0, 0, 24, 24, 24)
SetWindowRgn($GUI2, $rgn)
GUISetState()

Global $z1 = 4
Global $zoomX = Int($SIZEX / $z1)
Global $zoomY = Int($SIZEY / $z1)
Global $DeskDC = _WinAPI_GetDC(0)
Global $MyDC = _WinAPI_GetDC($GUIZoom)
_WinAPI_SetBkMode($MyDC, 1)

GUIRegisterMsg($WM_LBUTTONDBCLICK, "_GuiMessageHandler")
GUIRegisterMsg($WM_LBUTTONDOWN, "_GuiMessageHandler")
GUIRegisterMsg($WM_LBUTTONUP, "_GuiMessageHandler")
GUIRegisterMsg($WM_MOUSEMOVE, "_GuiMessageHandler")

Global $UserDLL = DllOpen("user32.dll")

Global $bContinue = True, $mousePos, $pos2, $pos3

_SetZoom()
While $bContinue
    If GUIGetMsg() = $GUI_EVENT_CLOSE Then $bContinue = False
    If _IsPressed("25", $UserDLL) Then _MoveWindow($hwndMove, -1, 0)
    If _IsPressed("27", $UserDLL) Then _MoveWindow($hwndMove, 1, 0)
    If _IsPressed("26", $UserDLL) Then _MoveWindow($hwndMove, 0, -1)
    If _IsPressed("28", $UserDLL) Then _MoveWindow($hwndMove, 0, 1)
    $mousePos = MouseGetPos()
    If _IsPressed("21", $UserDLL) And $z1 < 32 Then
        $z1 *= 2
        _SetZoom()
        Do
            Sleep(10)
        Until Not _IsPressed("21", $UserDLL)
        $pos2 = -1
    EndIf
    If _IsPressed("22", $UserDLL) And $z1 > 1 Then
        $z1 /= 2
        _SetZoom()
        Do
            Sleep(10)
        Until Not _IsPressed("22", $UserDLL)
        $pos2 = -1
    EndIf
    If IsHWnd($hwndMove) Then
        Local $r1 = WinGetPos($hwndMove)
        If $hwndMove = $GUI1 Then
            $mousePos[0] = $r1[0]
            $mousePos[1] = $r1[1]
        Else
            $mousePos[0] = $r1[0] + $r1[2] - 1
            $mousePos[1] = $r1[1] + $r1[3] - 1
        EndIf
    EndIf
    If ($mousePos[0] <> $pos2) Or ($mousePos[1] <> $pos3) Then
        $pos2 = $mousePos[0]
        $pos3 = $mousePos[1]
        _WinAPI_StretchBlt($MyDC, 0, 0, $SIZEX, $SIZEY, $DeskDC, $pos2 - ($zoomX / 2), $pos3 - ($zoomY / 2), $zoomX, $zoomY, $SRCCOPY)
    EndIf
    Sleep(50)
WEnd

GUISetState(@SW_HIDE, $GUI1)
GUISetState(@SW_HIDE, $GUI2)
GUISetState(@SW_HIDE, $GUIZoom)
GUIDelete($GUI1)
GUIDelete($GUI2)
GUIDelete($GUIZoom)

Exit

Func OnAutoItExit()
    _WinAPI_ReleaseDC(0, $DeskDC)
    _WinAPI_ReleaseDC($GUIZoom, $MyDC)
EndFunc   ;==>OnAutoItExit

Func _GuiMessageHandler($hWnd, $iMsg, $wParam, $lParam)
    Switch $iMsg
        Case $WM_LBUTTONDOWN
            $hwndMove = $hWnd
            $mouseStart = MouseGetPos()
            $winStart = WinGetPos($hwndMove)
            _WinAPI_SetCapture($hWnd)
        Case $WM_LBUTTONUP, $WM_LBUTTONDBCLICK
            $hwndMove = 0
            _WinAPI_ReleaseCapture()
            If $iMsg = $WM_LBUTTONDBCLICK Then $bContinue = False
        Case $WM_MOUSEMOVE
            If IsHWnd($hwndMove) Then
                Local $mouseNow = MouseGetPos()
                Local $winNow = $winStart
                $winNow[0] += $mouseNow[0] - $mouseStart[0]
                $winNow[1] += $mouseNow[1] - $mouseStart[1]
                WinMove($hwndMove, "", $winNow[0], $winNow[1])
                _ShowTooltip()
            EndIf
    EndSwitch
EndFunc   ;==>_GuiMessageHandler

Func _ShowTooltip()
    Local $r1 = WinGetPos($GUI1)
    Local $r2 = WinGetPos($GUI2)
    Local $x1 = $r1[0]
    Local $y1 = $r1[1]
    Local $x2 = $r2[0] + $r2[2] - 1
    Local $y2 = $r2[1] + $r2[3] - 1
    Local $x3 = $x2 - $x1
    Local $y3 = $y2 - $y1
    ToolTip("[" & $x1 & "," & $y1 & "] to [" & $x2 & "," & $y2 & "] = [" & $x3 & "," & $y3 & "] --- " & Round(Sqrt($x3 ^ 2 + $y3 ^ 2)) & " pixels")
EndFunc   ;==>_ShowTooltip

Func _MoveWindow($hWnd, $ox, $oy)
    If Not IsHWnd($hWnd) Then Return
    Local $r1 = WinGetPos($hwndMove)
    Local $p1 = MouseGetPos()
    $r1[0] += $ox
    $r1[1] += $oy
    $p1[0] += $ox
    $p1[1] += $oy
    WinMove($hwndMove, "", $r1[0], $r1[1])
    MouseMove($p1[0], $p1[1], 0)
    _ShowTooltip()
EndFunc   ;==>_MoveWindow

Func _SetZoom()
    _WinAPI_SetWindowText($GUIZoom, "Calipers- x" & $z1)
    $zoomX = Int($SIZEX / $z1)
    $zoomY = Int($SIZEY / $z1)
EndFunc   ;==>_SetZoom

;Author(s) : Prog@ndy, after _WinAPI_BitBlt
Func _WinAPI_StretchBlt($hDestDC, $iXDest, $iYDest, $iWidth, $iHeight, $hSrcDC, $iXSrc, $iYSrc, $iWidthSrc, $iHeightSrc, $iROP)
    Local $aResult

    $aResult = DllCall("GDI32.dll", "int", "StretchBlt", "hwnd", $hDestDC, "int", $iXDest, "int", $iYDest, "int", $iWidth, "int", $iHeight, _
            "hwnd", $hSrcDC, "int", $iXSrc, "int", $iYSrc, "int", $iWidthSrc, "int", $iHeightSrc, "int", $iROP)
    If @error Then Return SetError(@error, 0, False)
    Return $aResult[0] <> 0
EndFunc   ;==>_WinAPI_StretchBlt

;===============================================================================
;
; Function Name:   SetWindowRgn()
; Description::    Applies a generated region to a window handle returned by GUICreate
; Parameter(s):    $h_win - window handle, $rgn - The region returned by any Create..Rgn function
; Requirement(s):  AutoIt Beta
; Return Value(s): None
; Author(s):       Larry
;
;===============================================================================
;
Func SetWindowRgn($h_win, $rgn)
    DllCall("user32.dll", "long", "SetWindowRgn", "hwnd", $h_win, "long", $rgn, "int", 1)
EndFunc   ;==>SetWindowRgn

;===============================================================================
;
; Function Name:   CreateTriangleRgn()
; Description::    Creates a triangular region
; Parameter(s):    left, top, width, height
; Requirement(s):  AutoIt Beta
; Return Value(s): Region Handle
; Author(s):       RazerM
;
;===============================================================================
;
Func CreateTriangleRgn($x1, $y1, $x2, $y2, $x3, $y3)
    Return CreatePolyRgn("0,0," & $x1 & "," & $y1 & "," & $x2 & "," & $y2 & "," & $x3 & "," & $y3 & "," & $x1 & "," & $y1 & ",0,0")
EndFunc   ;==>CreateTriangleRgn

;===============================================================================
;
; Function Name:   CreatePolyRgn()
; Description::    Create a polygon region
; Parameter(s):    $pt - co-ordinates separated by a comma
; Syntax:          Set of co-ordinates for certain points(must end with the starting point)
; Requirement(s):  AutoIt Beta
; Return Value(s): Region handle
; Author(s):       Larry, Improved by RazerM
;
;===============================================================================
;
Func CreatePolyRgn($pt)
    $pt = "0,0," & $pt & ",0,0"
    Local $ALTERNATE = 1
    Local $buffer = ""

    $pt = StringSplit($pt, ",")
    For $i = 1 To $pt[0]
        $buffer = $buffer & "int;"
    Next
    $buffer = StringTrimRight($buffer, 1)
    Local $lppt = DllStructCreate($buffer)
    For $i = 1 To $pt[0]
        DllStructSetData($lppt, $i, $pt[$i])
    Next
    Local $ret = DllCall("gdi32.dll", "long", "CreatePolygonRgn", _
            "ptr", DllStructGetPtr($lppt), "int", Int($pt[0] / 2), _
            "int", $ALTERNATE)
    $lppt = 0
    Return $ret[0]
EndFunc   ;==>CreatePolyRgn
Link to comment
Share on other sites

@WideBoyDixon

Local $last_pos[2], $lastdistance

While 1
    $current_pos = MouseGetPos()
    $distance = Sqrt(($current_pos[0] - $last_pos[0]) ^ 2 + ($current_pos[1] - $last_pos[1]) ^ 2)
    $mousedist = $distance + $lastdistance
    $lastdistance = $mousedist
    $last_pos = $current_pos
    $mousesplit = StringSplit($mousedist, ".")

    If Not @error Then
        $distance = $mousesplit[1]
        TrayTip('Mouse distance', $distance & " pixels", 0)
    Else
        $distance = $mousedist
        TrayTip('Mouse distance', $distance & " pixels", 0)
    EndIf
WEnd

I dont know what your topic is about but maybe this is a way...

Cheers, FireFox.

Edited by FireFox
Link to comment
Share on other sites

@WideBoyDixon,

Very nice; you're producing some very good code!

I've long been a fan of Meazure from http://www.cthing.com/

I like the way you can switch between a single line to a bounding frame so you can easily get horizontal and vertical measurements in one go.

Maybe some ideas to incorporate in yours? hint, hint. :P

Link to comment
Share on other sites

Excellent work WideBoyDixon :P

UEZ

Agreed!

Maybe you could use a cross wire so that you could measure for anywhere to anywhere insted of from top left to bottom right only.

Also, needs a bit of work to allow the pointers to be positioned near the screen edges.

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

Very nice; you're producing some very good code!

Praise from Caesar! Well, someone who looks a bit like Caesar anyway :D

Maybe some ideas to incorporate in yours? hint, hint. :P

I looked at this application; it's probably more than I would ever want but I'll keep it in mind if I revisit this script. I'm currently working on another script.

I did also notice that I accidentally allowed moving the zoom window by clicking and dragging anywhere in the window (not just the title bar). I guess someone might find that useful for other applications :unsure:

WBD

Edited by WideBoyDixon
Link to comment
Share on other sites

Praise from Caesar! Well, someone who looks a bit like Caesar anyway :unsure:

I looked at this application; it's probably more than I would ever want but I'll keep it in mind if I revisit this script. I'm currently working on another script.

I did also notice that I accidentally allowed moving the zoom window by clicking and dragging anywhere in the window (not just the title bar). I guess someone might find that useful for other applications :P

WBD

makes me wana know what your working on now

wat are you working on?

0x616e2069646561206973206c696b652061206d616e20776974686f7574206120626f64792c20746f206669676874206f6e6520697320746f206e657665722077696e2e2e2e2e

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