ViciousXUSMC

Help turning a script into a proper UDF

9 posts in this topic

#1 ·  Posted (edited)

So one area I am lacking is "standardization" how the proper way to code, things like how to state variables etc. 

Yesterday I came up with what I thought was a neat little script that should be easy to turn into a UDF, and I think the process of learning how to make a UDF will make me better at everything else as I am sure to learn some best practices.

This code here is by no means a UDF its like a hybrid of my original code and the half way process that I am at in trying to convert it over.

Would anybody be willing to help guide me in the changes and proper ways to get this to where it could be posted and shared?

Also dos anybody know what .au3 files the original PixelSearch() is located in, looking that over may be a good self study reference.

Regards,

;This is an enhancement to the PiexelSearch function built into AutoIT in where when the function is called instead of searching the entire screen for your pixel color it searches the specified $range in pixels.
;If the color is found the x & y cordinate values are returned if the color is not found the search is expanded by the $expandrate in pixels and performed again up to the number of times specified in $expandcount.


Func PixelSearchRange($searchcolor, $range=50, $expandrate=200, $expandcount=50)
    Local $aPOS = MouseGetPos()
    Local $lb = $aPOS[0] - $range
    Local $tb = $aPOS[1] - $range
    Local $rb = $aPOS[0] + $range
    Local $bb = $aPOS[1] + $range



    $aPix = PixelSearch($lb, $tb, $rb, $bb, $searchcolor)
    If Not @Error Then
    ;Took out $x & $y just using the array directly probably need a "return" for the function.
    ;$x = $aPix[0]
    ;$y = $aPix[1]

    ;MouseMove is testing/debug actual UDF will return the array for array with x/y cordinates for user to decide what to do with.
    MouseMove($aPix[0], $aPix[1], 10)
    Else
    $Expand = 1
    Do
    $tb -=$expandrate
    $lb -=$expandrate
    $rb +=$expandrate
    $bb +=$expandrate
    $expand +=1
    $aPix = PixelSearch($lb, $tb, $rb, $bb, $searchcolor)
    If Not @Error Then $Expand = $expandcount
    Until $Expand = $expandcount
    EndIf
    ;Took out $x & $y just using the array directly probably need a "return" for the function.
    ;$x = $aPix[0]
    ;$y = $aPix[1]

    ;MouseMove is testing/debug actual UDF will return the array for array with x/y cordinates for user to decide what to do with.
    MouseMove($aPix[0], $aPix[1], 10)
EndFunc


;call function for testing
PixelSearchRange(000000)
Edited by ViciousXUSMC

Share this post


Link to post
Share on other sites



ViciousXUSMC,

To begin with, I suggest you read this Wiki article and check if your code follows it recommendations. :)

Then I suggest you look at how other UDFs have been written. The standard includes are probably a good place to start - and my own libraries are pretty "standard" in their coding style, at least in my opinion. ;)

And PixelSearch is a native AutoIt command, not a UDF function (most of which usually have a leading underscore), so do not spend any time looking for it. ;)

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

Ok I'll do as much research as I can on my own and come back when I get stuck.

Share this post


Link to post
Share on other sites

So here is my progress.  I figured out how to use Return and get the Array that the user can plug into their own script, now I just need to figure out how to return @Error and then clean up the naming convention and a few other minor things.

; #INDEX# =======================================================================================================================
; Title .........: _PixelSearchRange
; AutoIt Version : 3.3.12.0
; Language ......: English
; Author(s) .....: ViciousXUSMC
; Modifiers .....:
; Forum link ....:
; Description ...: An enhanced PixelSearch() that uses the mouses current position as the source for the search source.
; ===============================================================================================================================

; #CURRENT# =====================================================================================================================
;_PixelSearchRange
; ===============================================================================================================================

; #STRUCTURE# ===================================================================================================================
; Name...........: $tagMYSTRUCT
; Description ...: An example of a structure.
; Fields ........: hFoo       - A handle to foo that does something.
;                  iBar       - An integer that does something.
; Author ........: Matt Diesel (Mat)
; Remarks .......:
; Related .......: _MyUDF_Function
; ===============================================================================================================================

; #FUNCTION# ====================================================================================================================
; Name...........: _PixelSearchRange
; Description ...: An enhanced PixelSearch() that uses the mouses current position as the source for the search source.
; Syntax.........: _PixelSearchRange(ByRef $searchcolor{, $range = 50[, $expandrate = 200[, $expandcount = 50]]])
; Parameters ....: $searchcolor       - [byref] The Decimal RGB Value for the color you want to search for.
;                  $range             - [optional] How large the initial search vector is, default is 50 pixels.
;                  $expandrate        - [optional] If search fails to match within $range this is how many pixels the search is
;                                       expanded by on each additonal pass default is 200 pixels.
;                  $expandcount     - [optional] This is the number of times the search will be expanded before the function ends if a match is not found.
; Return values .: Success          - An Array where Array[0] is the X Cordinate of your patch and Array[1] is the Y Cordinate.
;                  Failure          - Returns zero and sets the @error flag:
;                                   |1 - The $avAnArray is invalid.
; Author ........: ViciousXUSMC
; Modified.......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......: _PixelSearchRange(000000, 50, 200, 50) ;Search for an all black pixel within a 100 pixel box around your current mouse position,
;    If no match is found try again expanding the search box by 200 pixels each direction.  Try to expand the search and try again up to 50 times.
; ===============================================================================================================================


Func _PixelSearchRange($searchcolor, $range=50, $expandrate=200, $expandcount=50)
    Local $aPOS = MouseGetPos()
    Local $lb = $aPOS[0] - $range
    Local $tb = $aPOS[1] - $range
    Local $rb = $aPOS[0] + $range
    Local $bb = $aPOS[1] + $range
    $aPix = PixelSearch($lb, $tb, $rb, $bb, $searchcolor)
    If Not @Error Then
    Return $aPix
    Else
    $Expand = 1
    Do
    $tb -=$expandrate
    $lb -=$expandrate
    $rb +=$expandrate
    $bb +=$expandrate
    $expand +=1
    $aPix = PixelSearch($lb, $tb, $rb, $bb, $searchcolor)
    If Not @Error Then $Expand = $expandcount
    Until $Expand = $expandcount
    EndIf
    Return $aPix
EndFunc


;call function for testing
$returntest = _PixelSearchRange(000000)
MsgBox(0, "", $returntest[1])

Share this post


Link to post
Share on other sites

Here is my code so far.

; #INDEX# =======================================================================================================================
; Title .........: _PixelSearchRange
; AutoIt Version : 3.3.12.0
; Language ......: English
; Author(s) .....: ViciousXUSMC
; Modifiers .....:
; Forum link ....:
; Description ...: An enhanced PixelSearch() that uses the mouses current position as the source for the search source.
; ===============================================================================================================================

; #CURRENT# =====================================================================================================================
;_PixelSearchRange
; ===============================================================================================================================

; #STRUCTURE# ===================================================================================================================
; Name...........: $tagMYSTRUCT
; Description ...: An example of a structure.
; Fields ........: hFoo       - A handle to foo that does something.
;                  iBar       - An integer that does something.
; Author ........: Matt Diesel (Mat)
; Remarks .......:
; Related .......: _MyUDF_Function
; ===============================================================================================================================

; #FUNCTION# ====================================================================================================================
; Name...........: _PixelSearchRange
; Description ...: An enhanced PixelSearch() that uses the mouses current position as the source for the search source.
; Syntax.........: _PixelSearchRange(ByRef $searchcolor{, $range = 50[, $expandrate = 200[, $expandcount = 10]]])
; Parameters ....: $searchcolor       - [byref] The Decimal RGB Value for the color you want to search for.
;                  $range             - [optional] How large the initial search vector is, default is 50 pixels.
;                  $expandrate        - [optional] If search fails to match within $range this is how many pixels the search is
;                                       expanded by on each additonal pass default is 200 pixels.
;                  $expandcount     - [optional] This is the number of times the search will be expanded before the function ends if a match is not found
;                                       default is 10 times.
; Return values .: Success          - An Array where Array[0] is the X Cordinate of your patch and Array[1] is the Y Cordinate.
;                  Failure          - An Array with current mouse cordinates Sets @Error Flag @Error 1 = Cound not get Mouse Position, @Error 2 = Could Not Find Pixel Color Where
;                                      @Extended 1 = Initial Search and @Extended 2 = Extended Search after Extend Counter Expires.
;
; Author ........: ViciousXUSMC
; Modified.......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......: _PixelSearchRange(000000, 50, 200, 10) ;Search for an all black pixel within a 100 pixel box around your current mouse position,
;    If no match is found try again expanding the search box by 200 pixels each direction.  Try to expand the search and try again up to 50 times.
; ===============================================================================================================================


Func _PixelSearchRange($searchcolor, $range=50, $expandrate=200, $expandcount=10)
    Local $aPOS = MouseGetPos()
    If @Error Then SetError(1)
    Local $lb = $aPOS[0] - $range
    Local $tb = $aPOS[1] - $range
    Local $rb = $aPOS[0] + $range
    Local $bb = $aPOS[1] + $range
    $aPix = PixelSearch($lb, $tb, $rb, $bb, $searchcolor)
    If @Error Then SetError(2,1)
    If Not @Error Then
    Return $aPix
    Else
    $Expand = 1
    Do
    $tb -=$expandrate
    $lb -=$expandrate
    $rb +=$expandrate
    $bb +=$expandrate
    $expand +=1
    $aPix = PixelSearch($lb, $tb, $rb, $bb, $searchcolor)
    If @Error Then SetError(2,2)
    If Not @Error Then $Expand = $expandcount
    Until $Expand = $expandcount
    EndIf
    If @Error Then
    Return $aPOS
    Else
    Return $aPix
    EndIf
EndFunc

The good - I think all the @Error stuff is working the way I want with the exception of failure to get mouse cords because I cant create that issue to see what happens :)

Return values seem to be working including if the search fails instead of crashing the script it returns current mouse cords and sets the @Error to 2 and @Extended to 1 or 2 depending on what search failed.

Testing this and it works well, even on my 3 monitor setup.

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

ViciousXUSMC,

 

I think all the @Error stuff is working

Sorry, but I think you have some serious logic flow problems there - not least because @error does not behave quite as you think it does. For example, in this section @error is already set, so why are you setting it again?

$aPix = PixelSearch($lb, $tb, $rb, $bb, $searchcolor)
If @Error Then SetError(2,1)
If Not @Error Then
if you would permit me, something along these lines might be a little more elegant:

Func _PixelSearchRange($iSearchColor, $iRange = 50, $iExpandRate = 200, $iExpandCountMax = 10)
    
    Local $aPix

    ; Get mouse position
    Local $aPOS = MouseGetPos()
    If @error Then Return SetError(1, 0, "") ; Return empty string - there will be no array to return
    ; Determine initial search area
    Local $iLeft = $aPOS[0] - $iRange
    Local $iTop = $aPOS[1] - $iRange
    Local $iRight = $aPOS[0] + $iRange
    Local $iBottom = $aPOS[1] + $iRange
    ; Set expansion counter
    Local $iExpandCount = 0
    ; Start looping
    While 1
        ; Search for colour
        $aPix = PixelSearch($iLeft, $iTop, $iRight, $iBottom, $iSearchColor)
        ; Check for error
        If @error Then
            ; Colour not found so...
            ; Increase counter
            $iExpandCount += 1
            ; Return error if counter maximum reached
            If $iExpandCount > $iExpandCountMax Then Return SetError(2, 0, "") ; Or you could return $aPOS
            ; Increase search area
            $iTop -= $iExpandRate
            $iLeft -= $iExpandRate
            $iRight += $iExpandRate
            $iBottom += $iExpandRate
        Else
            ; Colour found so return coords
            Return $aPix
        EndIf
        ; Only get here if we need another expansion, so loop and search again
    WEnd
    
EndFunc
Please ask if you have any questions on the code - or why I have chosen this logic flow. :)

M23

Edit: My original comment and the code snippet did not match - copy/paste error from an earlier draft. :blush:

Edited by Melba23

Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

Thanks M23 I'll tear it down and compare.

Few good things I learned.

Return exits the function right away, I did not know this so I did not have one for MouseGetPos() and that is also the reason I used Do/Until instead of While 1/Wend

I also did not know you can use Return SetError together.

Being that this is my first time making a function with returns this was a good learning block for me and your example made great sense. 

Edited by ViciousXUSMC

Share this post


Link to post
Share on other sites

ViciousXUSMC,

Glad you found it interesting. :)

There is a school of thought that you should only even have one exit point from a function and preset all the necessary content as you proceed through the code. Personally I have always believed that trying to do that makes for very cumbersome code and, particularly for error cases, you might as well exit as soon as the error is discovered. The exception is where you need to do some tidying up before returning - take a look at my StringSize UDF - you will see that there is a separate "error" function called on an error exit which closes those resources that have already been created as the code progresses. ;)

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
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