Advertisement
Guest User

oijkn

a guest
Feb 27th, 2015
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ; <COMPILER: v1.0.48.5>
  2. #SingleInstance, Force
  3.  
  4. #Persistent
  5. #InstallKeybdHook
  6. #UseHook, On
  7. FindClick(ImageFile="", Options="", ByRef FoundX="", ByRef FoundY="")
  8. {
  9.     Static Cache
  10.     , Center, Silent, Delim, Count, CharX, CharY, CharN, Sleep, Stay, Func, dx, d, m, x, y, o, n, k, r, e, a, w, t, f
  11.     , ImageW, ImageH, LastX1, LastY1, ImageFilePath
  12.     , LastOptions, LastImageFile, MonitorInfo, DxInfo
  13.     , GuiHWND, GuiCommand, GuiTitle
  14.     , Error, Message, Buttons, # := "`t", $ := "`r"
  15.     GlobalSettingsLocation = %A_LineNumber%
  16.  
  17.  
  18.     DefaultDirs = %A_AhkPath%\..\Graphics|%A_Desktop%|%A_ScriptDir%|%A_Temp%|C:\Dropbox\AutoHotkey\Graphics
  19.     DefaultExts = png|bmp
  20.     GuiA = 97
  21.     GuiB = 98
  22.     Literal := """"
  23.     UseRGB = %False%
  24.     ForumURL = http://www.autohotkey.com/board/topic/89592-findclick-2nd-edition
  25.     DocumentationURL = https://www.cubby.com/pl/FindClick.pdf/_feba12f92a604faead036f157a95ba6b
  26.     LastUpdate = November 16, 2013
  27.  
  28.     If (ImageFile <> "") and (Asc(ImageFile) <> 62) {
  29.         If (LastImageFile <> ImageFile) or (Options <> LastOptions) {
  30.             If (Asc(Cache) = 62)
  31.                 SpecialLaunch := SubStr(Cache, 2, 1), Cache := SubStr(Cache, 3)
  32.             If (LastImageFile <> "")
  33.                 Cache := LastImageFile A_Tab ImageFilePath A_Tab ImageW "|" ImageH "|" LastX1 "|" LastY1 "`n" Cache, LastImageFile := ""
  34.             If (SpecialLaunch <> 3) {
  35.                 DefaultOptionsLocation := A_LineNumber
  36.  
  37.  
  38.  
  39.  
  40.                 , o := "",                o_user := "*15"
  41.                 , a := "",                a_user := "m100"
  42.                 , r := "",                r_user := "A"
  43.                 , x := 0,                 x_user := "Abs"
  44.                 , y := 0,                 y_user := "Abs"
  45.                 , n := 1,                 n_user := 0
  46.                 , e := "",                e_user := 0.85
  47.                 , w := "",                w_user := "0,100"
  48.                 , dx := "",               dx_user := True
  49.                 , k := "{Click}",         k_user := "{RButton}"
  50.                 , Stay := False,          Stay_user := True
  51.                 , Count := False,         Count_user := True
  52.                 , d := "",                d_user := "MousePos"
  53.                 , m := "Input",           m_user := "ControlClick"
  54.                 , Sleep := 20,            Sleep_user := 0
  55.                 , t := "",                t_user := "10%"
  56.                 , Silent := False,        Silent_user := True
  57.                 , Center := True,         Center_user := False
  58.                 , Delim := "`n",          Delim_user := A_Tab
  59.                 , f := "x,y",             f_user := "x y n"
  60.                 , Func := "",             Func_user := ""
  61.                 , CharX := "x",           CharX_user := "x"
  62.                 , CharY := "y",           CharY_user := "y"
  63.                 , CharN := "n",           CharN_user := "n"
  64.  
  65.  
  66.                 UserConfig_foo = r"Test Window" mControlClick
  67.                 UserConfig_log = dx"SaveTo=%A_Desktop%\FindClickDebug.txt"
  68.  
  69.             }
  70.             @5 := 1, TempOptions := Options, Commands := "Center|Silent|Delim|Count|CharX|CharY|CharN|Sleep|Stay|Func|Err|dx|d|m|x|y|o|n|k|r|e|a|w|t|f"
  71.             If SpecialLaunch and (SpecialLaunch <> 4) {
  72.  
  73.  
  74.                 OptionInfo =
  75.                 (
  76.                 m               SendMode for keystrokes
  77.                 What to give    [Event|Play|Input|Default|ControlClick|First letter of any of these words]
  78.                 Description     The send mode (or first letter thereof) to use for clicks, i.e. Input, Play, or Event. Specify ControlClick (or c) to use a controlclick instead of a simulated keystroke. If m is blank or the letter d (for default), the current SendMode will be used.
  79.                 --------------------------------------------------------------------------------
  80.                 x               X Offset
  81.                 What to give    An integer
  82.                 Description     This many pixels will be incremented to the click coordinates before clicking. A positive x value will click left of the image, a negative value will click to the right. This change will also show up in the string that is returned by the function and the coordinates stored in the ByRef variables.
  83.                 --------------------------------------------------------------------------------
  84.                 y               Y Offset
  85.                 What to give    An integer
  86.                 Description     This many pixels will be incremented to the click coordinates before clicking. A positive y value will click below the image, and a negative value will click above it. This change will also show up in the string that is returned by the function and the coordinates stored in the ByRef variables.
  87.                 --------------------------------------------------------------------------------
  88.                 f               Format of output string
  89.                 What to give    Template string that includes the CharX and/or CharY and/or CharN characters.
  90.                 Description     The given string represents a template into which image x-coordinate, y-coordinate, and instance number will be substituted. Each time an image is found, the CharX, CharY, and CharN characters will be replaced with these values. The final string is returned by the function. See the examples section of the documentation for an example.
  91.                 --------------------------------------------------------------------------------
  92.                 Delim           Delimiter for multiple images
  93.                 What to give    Any character or characters
  94.                 Description     If e is used and multiple images are found then each image's info is separated by this character(s) in the returned string. The format of the image info is determined by f.
  95.                 --------------------------------------------------------------------------------
  96.                 Stay            Do not restore mouse
  97.                 What to give    True or False (1 or 0)
  98.                 Description     Normally after any clicks executed by FindClick the mouse will be immediately returned to its initial location. If Stay is true then the mouse will NOT return to its original position after FindClick finishes.
  99.                 --------------------------------------------------------------------------------
  100.                 o               ImageSearch Options
  101.                 What to give    Comma-delimited string of imagesearch options.
  102.                 Description     The imagesearch options are the Optional parameters for ImageSearch, as shown in documentation. Use a comma to separate options. You may omit the asterisk (*). For example: oTransBlack,20 makes black transparent and allows 20 shades of variation.
  103.                 --------------------------------------------------------------------------------
  104.                 n               Number of clicks
  105.                 What to give    Any number
  106.                 Description     The number of times to click on each image. Indicate 0 (the default) to do no clicking whatsoever and just return the coordinates of the found image(s). In this sense, specifying just n is like saying "no clicking". Without clicks, the m, d, and k options are irrelevant, however, the x and y values will still be added to the output coordinates.
  107.                 --------------------------------------------------------------------------------
  108.                 Sleep           Sleep milliseconds
  109.                 What to give    Any number of milliseconds
  110.                 Description     Number of milliseconds to sleep between each click if n > 1 or e and multiple images found.
  111.                 --------------------------------------------------------------------------------
  112.                 k               Keystroke(s)
  113.                 What to give    Key to send (in the same format as the AutoHotkey Send command)
  114.                 Description     Indicate the keys to press (if any) when each image is found. k can include multiple keypresses and even non-mouse keys, for instance, ^{Space}. If ControlClick is in effect the format is different (see the ControlClick documentation) and a left click will be assumed if an incorrect k is given.
  115.                 --------------------------------------------------------------------------------
  116.                 r               Relative to Window Coords
  117.                 What to give    Window Title criteria, or a window HWND
  118.                 Description     The search area becomes the area of the given window instead of the entire screen area. This is useful when scanning for an element which only appears on a particular window – reducing the search area improves performance. Use of the s option in conjunction with r will apply these offsets to the window coordinates.
  119.                 --------------------------------------------------------------------------------
  120.                 e               Find Every Image
  121.                 What to give    Positive fraction between 0 and 1
  122.                 Description     If this option is nonblank then FindClick will find (and click) EVERY instance found. This means that after any successful imagesearch execution the script will queue up a new call of imagesearch which represents the screen area left unsearched by the first call. (Note that this therefore makes FindClick slower for any use in which you don't expect to find more than one image.)
  123.                                 The value of e signifies the overlap between search areas, in terms of the fraction of the image width and height. Overlap should normally be near 1 except if the image is uniform throughout, e.g. a 10x10 square image containing mostly white pixels. The t, d, and Count options all require the "find every image" ehavior as part of their execution and so using any of these other options implies e, however, you may still specify a custom value for e to change the overlap for these other behaviors.
  124.                 --------------------------------------------------------------------------------
  125.                 a               Search Area Modifications
  126.                 What to give    x[,y,w,h] OR  mn
  127.                 Description     Region within which to search for the image. Indicate either of the following: 1) A comma-delimited list in the format x,y,w,h. List items may be blank or absent to leave that value unchanged. Coordinates are relative to the window if the a option is true. For w and h, use +/- to indicate a change to the normal endpoint (depending on a, either the edge of the screen or active window). For instance, s,,-300 will search the entire screen (or window if a is specified) except for the last 300 pixels of the right side – the width of the search area has been reduced by 300. 2) The letter m and then a number to search a square region centered at the cursor position and with a width and height twice that number.
  128.                 --------------------------------------------------------------------------------
  129.                 w               Wait until image is found
  130.                 What to give    Number of milliseconds [, Number of milliseconds]
  131.                 Description     If the image is not found, the function will wait this many milliseconds for it to appear before returning. You may add a comma and then a second number which indicates the delay in milliseconds between subsequent imagesearches. For example 2000,50 means the function will look for the image every 50ms until either the image is found or 2000ms elapse, for a maximum of 40 imagesearch operations. If omitted, this delay will be the smaller of either the wait time divided by 10 or 100ms.
  132.                 --------------------------------------------------------------------------------
  133.                 t               Image Tracking
  134.                 What to give    A percent OR a number of pixels
  135.                 Description     This option is used to improve performance if an image will be found nearby where its last location. By analogy it's like tracking the course of a thrown ball. The script will first search nearby the last found position and if it is not found there then the rest of the area will be searched. Indicate a percentage to search within that percentage of the search area in each direction – for instance, the string 20`% will first search a box that begins 20`% of the distance between the starting x position and the last found x position, and likewise for all four directions. On the other hand, indicating a number will simply search a box that many pixels from the last found area before searching the rest of the s area. Indicate 0 to search EXACTLY the last found location first. If t is negative (including -0) then it will ONLY search in the region requested, and will not go on to search the rest of the screen if the image is not found there.
  136.                 --------------------------------------------------------------------------------
  137.                 Silent          No Dialogs
  138.                 What to give    True or False
  139.                 Description     Instead of displaying an error dialog when an error prevents the function from executing properly (for instance, if the image file is not found), it will silently return a blank string and set the ErrorLevel to the error message. The errors concerned should not appear during normal execution and so Silent is generally not recommended.
  140.                 --------------------------------------------------------------------------------
  141.                 Count           Return found count
  142.                 What to give    True or False
  143.                 Description     If Count is true then the function will return the number of items found instead of their coordinates. e is assumed if absent.
  144.                 --------------------------------------------------------------------------------
  145.                 dx              Diagnostic Mode
  146.                 What to give    Comma delimited list of diagnostic mode options (see below)
  147.                 Description     Will illustrate where clicks take place with an on-screen display. Currently the comma-separated options aren't really working, sorry about that!
  148.                 --------------------------------------------------------------------------------
  149.                 Center          Start at center of image
  150.                 What to give    True or False (1 or 0)
  151.                 Description     If Center is true then clicks will occur at the center of the image, i.e. its found position plus half its width and half its height. The x and y options treat this as 0, 0 – for instance, by default an x of 2 will click 2 pixels to the right of the image center. Indicate false to instead start at the top left corner of the image.
  152.                 --------------------------------------------------------------------------------
  153.                 Func            Function Callout
  154.                 What to give    The name of a function in the script
  155.                 Description     Each time an image is found, instead of clicking on the image or executing keystrokes the given function will be called. The function must accept at least two parameters: the x-coordinate of the image will be passed in the first parameter, and the y-coordinate will be passed in the second parameter. Note that any thread settings such as CoordMode that are changed within the function will carry over to FindClick when the function is done.
  156.                 --------------------------------------------------------------------------------
  157.                 d               Direction Of Search
  158.                 What to give    Left|Right|Bottom
  159.                 Description     This setting attempts to emulate the mode of pixelsearch where you can search from right to left or top to bottom – for instance, specifying Bottom will find the image closest to the bottom of the search area. However, to accomplish this the script needs to first find every image and then choose the coordinate pair that is furthest in the requested direction, making it a time-consuming process.
  160.                 )
  161.  
  162.                 OptionInfo := RegExReplace(OptionInfo, "(?:`n|^)\K\s+"), OptionInfo := "`r" RegExReplace(OptionInfo, "\s*-{5,}\s*", "`r"), OptionInfo := RegExReplace(OptionInfo, "[ \t]{3,}|\t+", "`t")
  163.                 If (SpecialLaunch <> 3)
  164.                     Loop, Parse, Commands, |
  165.                         OptionInfo := RegExReplace(OptionInfo, "i)`r" A_LoopField "`t[^`n]+", "$0`nDefault`t" %A_ThisFunc%(">Escape<", %A_ThisFunc%(">ShowChars<", %A_LoopField%)) "`nUser Default`t" %A_ThisFunc%(">Escape<", %A_ThisFunc%(">ShowChars<", %A_LoopField%_user)))
  166.                 If SpecialLaunch in 2,3
  167.                     Return OptionInfo
  168.                 DllCall("QueryPerformanceCounter", "Int64*", QPC)
  169.                 , TempCommands := Commands, VarSetCapacity(DxInfo, 2500)
  170.                 , DxInfo := A_TickCount A_Tab QPC "`r1:Initializing function" #
  171.                 . "q:" QPC #
  172.                 . "t:Function called at " A_Hour ":" A_Min ":" A_Sec "." A_MSec "`n`nThe following values were passed as parameters to the function:`n<table>ImageFile;%ImageFile%`nOptions;%Options%</table>`n`nThe following script settings were inherited from the current thread:`n<table>Thread Name;%A_ThisLabel%`nWorking Dir;%A_WorkingDir%`nBatch Lines;%A_BatchLines%`nTitle Match Mode;%A_TitleMatchMode%</table>" #
  173.                 . "c1:ImageFile:" %A_ThisFunc%(">Escape<", ImageFile) #
  174.                 . "c2:Options:" %A_ThisFunc%(">Escape<", Options) #
  175.                 . "c3:A_ThisLabel:" A_ThisLabel #
  176.                 . "c4:A_WorkingDir:" A_WorkingDir #
  177.                 . "c5:A_BatchLines:" A_BatchLines #
  178.                 . "c6:A_TitleMatchMode:" A_TitleMatchMode #
  179.                 . "l:" A_LineNumber - 1 #
  180.             }
  181.             If DxInfo
  182.                 DxInfo .= $ "2:Parsing options" #
  183.                 . "t:The information passed to " A_ThisFunc "() through the options parameter (2nd param) will now be parsed into individual script settings." #
  184.                 . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
  185.                 . "l:" A_LineNumber + 1
  186.             While (@5 := RegExMatch(TempOptions, "i)(?:^|\s)(?:!(\w+)|(\+|-)?(" Commands ")(" Literal "(?:[^" Literal "]|" Literal Literal ")*" Literal "(?= |$)|[^ ]*))", @, @5 + StrLen(@))) {
  187.                 If (@1 <> "") {
  188.                     TempOptions := SubStr(TempOptions, 1, @5 + StrLen(@)) A_Space UserConfig_%@1% SubStr(TempOptions, @5 + StrLen(@))
  189.                     If DxInfo
  190.                         DxInfo .= $ "2:Loading user configuration: !" @1 #
  191.                         . "l:" DefaultOptionsLocation + 1 #
  192.                         . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
  193.                         . "c1:UserConfig:" @1 #
  194.                         . "c2:Options:" %A_ThisFunc%(">Escape<", TempOptions) #
  195.                         . "t:<table>User configuration;!%UserConfig%`nOptions string after modification;%Options%`n`nUser configurations can be found below the script options near the top of the code." #
  196.                 } Else If (@4 <> "") {
  197.                     If (InStr(@4, Literal) = 1) and (@4 <> Literal) and (SubStr(@4, 0, 1) = Literal) and (@4 := SubStr(@4, 2, -1))
  198.                         StringReplace, @4, @4, %Literal%%Literal%, %Literal%, All
  199.                     %@3% := @4
  200.                 } Else
  201.                     %@3% := @2 = "+" ? True : @2 = "-" ? False : %@3%_user
  202.                 If DxInfo {
  203.                     RegExMatch(OptionInfo, "i)`r" @3 "`t\K[^`n]+", @6)
  204.                     DxInfo .= $ "3:" @3 #
  205.                     . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
  206.                     . "t:<table>Option ID;" @3 "`nDescription;" (@5 = "" ? "UNKNOWN!" : @6) "`nNew value;%" @3 "%`nAssign type;" (@4 = "" ? "User default</table>`n`nUser default means that the option was indicated without a value so the value defaulted to this string" : "Custom string</table>`n`nCustom string means the user put a string after the option ID, so it now takes that value.") #
  207.                     . "l:" A_LineNumber - 2 #
  208.                     . "c1:" @3 ":" %A_ThisFunc%(">Escape<", %@3%) #
  209.                     StringReplace, TempCommands, TempCommands, |%@3%|, |
  210.                 }
  211.             }
  212.             If (SpecialLaunch = 4)
  213.                 Return
  214.             If (dx <> "")
  215.                 If DxInfo {
  216.                     @ := "t:The remaining script settings take the following default values:`n`n<table>"
  217.                     , DxInfo .= $ "2:Other script settings" #
  218.                     . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
  219.                     . "l:" DefaultOptionsLocation #
  220.                     Loop, Parse, TempCommands, |
  221.                         If (A_LoopField <> "")
  222.                             DxInfo .= "c" A_Index ":" A_LoopField ":" %A_ThisFunc%(">Escape<", %A_LoopField%) #
  223.                             , @ .= A_LoopField ";%" A_LoopField "%`n"
  224.                     DxInfo .= @ "</table>"
  225.                 } Else {
  226.                     Cache := ">>" Cache
  227.                     Return %A_ThisFunc%(ImageFile, Options)
  228.                 }
  229.             LastOptions := Options, @ := LastImageFile, LastImageFile := ImageFile
  230.             If DxInfo
  231.                 DxInfo .= $ "1:Preparing Image File" #
  232.                 . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
  233.                 . "t:The image file that was specified for use with imagesearch must now be located on the hard drive, and its size must be measured." #
  234.                 . "l:" A_LineNumber + 1
  235.             If !(((ImageFile = @) and FileExist(ImageFilePath)) or %A_ThisFunc%(">ParseCache<", ImageFile)) {
  236.                 NewImage := True, ImageFilePath := ""
  237.                 If RegExMatch(ImageFile, "i)^\*(?:0x)?([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})(?:\D*(\d+)\D*(\d+).*?)?$", @) {
  238.                     ImageW := @4 ? @4 : 1, ImageH := @5 ? @5 : 1, Color := UseRGB ? @1 @2 @3 : @3 @2 @1
  239.                     If DxInfo
  240.                         DxInfo .= $ "2:PixelSearch Set" #
  241.                         . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
  242.                         . "t:The ImageFile parameter was recognized as a pixel color so the function will search for pixels of this color. The mechanism for this search however will remain ImageSearch.`n`n<table>Color;%Color%`nColor is RGB;%UseRGB%`nRegion Width;%ImageW%`nRegion Height;%ImageH%</table>" #
  243.                         . "l:" A_LineNumber - 2 #
  244.                         . "c1:Color:" Color #
  245.                         . "c2:UseRGB:" UseRGB #
  246.                         . "c3:ImageW:" ImageW #
  247.                         . "c4:ImageH:" ImageH #
  248.                     If !FileExist(ImageFilePath := A_Temp "\" A_ThisFunc "_" Color "_" ImageW "x" ImageH ".png") {
  249.                         If DxInfo
  250.                             DxInfo .= $ "2:Building image of color #" Color #
  251.                             . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
  252.                             . "t:A temporary png image will be created of the color specified. This is relatively time-consuming but only need be done once as long as the png file remains in the temporary folder.`n`nWindows Temp Dir: %A_Temp%" #
  253.                             . "c1:A_Temp:" A_Temp #
  254.                             . "l:" A_LineNumber - 2 #
  255.                         VarSetCapacity(Colors, ImageW * ImageH * 7)
  256.                         Loop % ImageW * ImageH
  257.                             Colors .= "|" Color
  258.                         %A_ThisFunc%(">MakeImage<", A_Temp "\" A_ThisFunc "_" Color "_" ImageW "x" ImageH "|png|" ImageW "|" ImageH Colors)
  259.                     }
  260.                 } Else {
  261.                     DefaultDirs := SubStr(RegExReplace(DefaultDirs "|", "\\*(?:\||^)+", Asc(ImageFile) = 92 ? "|" : "\|"), 2, -1), DefaultExts := SubStr(RegExReplace("|" DefaultExts "|", "\|\.*", "|."), 1, -2)
  262.                     If DxInfo
  263.                         DxInfo .= $ "2:ImageFile not seen before" #
  264.                         . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
  265.                         . "t:Image file """ ImageFile """ has not been seen before by the function so it will now look through the default locations to find the full image path." #
  266.                         . "l:" GlobalSettingsLocation #
  267.                         . "d:2"
  268.                     Loop, Parse, DefaultDirs, |
  269.                     {
  270.                         ThisDir := A_LoopField
  271.                         If DxInfo
  272.                             DxInfo .= $ "3:" (A_Index = 1 ? "(Working Dir)" : SubStr(ThisDir, 1, -1)) #
  273.                             . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
  274.                             . "t:Directory #" A_Index " is:`n`n%ThisDir%`n`n(This can be specified at the top of the script in DefaultDirs.)" #
  275.                             . "c1:ThisDir:" %A_ThisFunc%(">Escape<", ThisDir)
  276.                         Loop, Parse, DefaultExts, |
  277.                             If FileExist(ThisDir ImageFile A_LoopField) {
  278.                                 If InStr(FileExist(ImageFilePath := ThisDir ImageFile A_LoopField), "D")
  279.                                     ImageFilePath := ""
  280.                                 Else
  281.                                     Break
  282.                             } Else If DxInfo
  283.                                 DxInfo .= $ "4:" ImageFile A_LoopField #
  284.                                 . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
  285.                                 . "t:Trying file path:`n`n%ImageFilePath%`n`nFile does not exist." #
  286.                                 . "c1:ImageFilePath:" %A_ThisFunc%(">Escape<", ThisDir ImageFile A_LoopField) #
  287.                                 . "d:1" #
  288.                                 . "l:" A_LineNumber - 6
  289.                         If (ImageFilePath <> "")
  290.                             Break
  291.                     }
  292.                     If (ImageFilePath = "") {
  293.                         Error = File Not Found
  294.                         Message = Image file "%ImageFile%" not found.
  295.                         Buttons = &Create Image,&Debug,E&xit,&Help
  296.                         If (%A_ThisFunc%(">Error<") = "Create Image")
  297.                             %A_ThisFunc%(">>" ImageFile, Options)
  298.                         Return
  299.                     } Else If DxInfo
  300.                         DxInfo .= $ "4:Image file found" #
  301.                         . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
  302.                         . "t:Trying file path:`n`n%ImageFilePath%`n`nImage file found!" #
  303.                         . "c1:ImageFilePath:" %A_ThisFunc%(">Escape<", ImageFilePath) #
  304.                         . "l:" A_LineNumber - 10 #
  305.                         . "d:1"
  306.                     If !%A_ThisFunc%(">ParseCache<", ImageFilePath) {
  307.                         If DxInfo
  308.                             DxInfo .= $ "2:Measuring width and height" #
  309.                             . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
  310.                             . "t:The image dimensions will be measured by quickly creating an AutoHotkey GUI containing the image. This is a relatively CPU-intensive step but only need be done once per session - the information is stored in the cache for future calls with the same image.`n`n<table>Image Width;%ImageW%`nImage Height;%ImageH%</table>"
  311.                         Gui, %GuiA%:Add, Picture, Hwnd@, %ImageFilePath%
  312.                         WinGetPos, , , ImageW, ImageH, ahk_id %@%
  313.                         Gui, %GuiA%:Destroy
  314.                         If (ImageW = "") {
  315.                             Error = Image file type unsupported
  316.                             Message = Image file "%ImageFile%" appears to be of an unsupported filetype.
  317.                             Buttons = &View File,&Debug,E&xit,&Help
  318.                             If (%A_ThisFunc%(">Error<") = "View File")
  319.                                 MsgBox, 262160, %A_ScriptName%: Error, Function not yet supported, sorry!
  320.                             Return
  321.                         }
  322.                         If DxInfo
  323.                             DxInfo .= "g:Add,Edit,+ReadOnly -VScroll w" (ImageW > 20 ? ImageW * 15 : 300) "," ImageFilePath ";-E0x20 +Caption +SysMenu;Add,Picture,+Border xp" (ImageW > 20 ? "" : "+" 150 - ImageW * 7.5) " y+10 w" ImageW * 15 " h-1," ImageFilePath ";Show,NA,Preview of image" #
  324.                             . "c1:ImageW:" %A_ThisFunc%(">Escape<", ImageW) #
  325.                             . "c2:ImageH:" %A_ThisFunc%(">Escape<", ImageH) #
  326.                             . "l:" A_LineNumber - 7 #
  327.                             . "d:5"
  328.                     }
  329.                 }
  330.             }
  331.             If (o <> "") {
  332.                 If DxInfo
  333.                     @ := o
  334.                 o := SubStr(RegExReplace(A_Space o, "[^\w-]+", " *"), 2) A_Space
  335.                 If DxInfo and (o <> @ A_Space)
  336.                     DxInfo .= $ "2:Refining imagesearch options" #
  337.                     . "t:The ImageSearch options (""o"" option) have been modified to fit the AutoHotkey ImageSearch command's format.`n`n<table>Given;%o_original%`nNow;%o%</table>" #
  338.                     . "l:" A_LineNumber - 2 #
  339.                     . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
  340.                     . "c1:o:" %A_ThisFunc%(">Escape<", SubStr(o, 1, -1)) #
  341.                     . "c2:o_original:" %A_ThisFunc%(">Escape<", @) #
  342.             }
  343.             If (Func <> "") {
  344.                 StringReplace, Func, Func, ()
  345.                 If !IsFunc(Func)
  346.                     MsgBox, 262160, %A_ScriptName%: Error, Function %Func%() does not exist.
  347.                 Else
  348.                     n := 0
  349.             }
  350.             If (r <> "") and RegExMatch(r, "i)^0x[0-9A-F]{5,8}$") {
  351.                 r := "ahk_id " r
  352.                 If DxInfo
  353.                     DxInfo .= $ "2:Refining WinTitle option" #
  354.                     . "t:The ""r"" option (relative to window) is a hexadecimal number, so it will be interpreted as a window handle and becomes ""%r%""." #
  355.                     . "l:" A_LineNumber - 2 #
  356.                     . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
  357.                     . "c1:r:" %A_ThisFunc%(">Escape<", r) #
  358.             }
  359.             If d
  360.                 If (InStr(d, "t") = 1) or (InStr(d, "u") = 1) {
  361.                     If DxInfo
  362.                         DxInfo .= $ "2:Ignoring d option" #
  363.                         . "t:The ""d"" (directional) option was given as ""%d%"" which will be ignored since the top image is the one that ImageSearch finds by default." #
  364.                         . "c1:d:" d #
  365.                         . "l:" A_LineNumber + 1 #
  366.                         . "q:" DllCall("QueryPerformanceCounter", "Int648", QPC) * QPC #
  367.                     d := ""
  368.                 } Else
  369.                     StringLower, d, d
  370.             If (e = "") {
  371.                 If Count or d
  372.                     e := e_user
  373.                 Else If (t <> "")
  374.                     e := 0.99
  375.                 If DxInfo and (e <> "")
  376.                     DxInfo .= $ "2:Overlap set to " e #
  377.                     . "t:Because an option that requires every image to be found was indicated (either ""t"", ""d"", or ""Count""), and because a custom value of ""e"" was not given, it defaults to %e%." #
  378.                     . "c1:e:" e #
  379.             }
  380.             If (InStr(m, "c") = 1) {
  381.                 If DxInfo
  382.                     @ := k
  383.                 If k Contains RButton
  384.                     k = Right
  385.                 Else If k Not In Left,Right,Middle,L,R,M,X1,X2,WheelUp,WU,WheelDown,WD,WheelLeft,WL,WheelRight,WR
  386.                     k = Left
  387.                 If DxInfo and (@ <> k)
  388.                     DxInfo .= $ "2;Correcting k option" #
  389.                     . "t:The ""k"" (keystrokes) option was given as ""%@%"" but has been corrected to ""%k%"" because ControlClick was indicated for the ""m"" (SendMode) option, and ControlClick has a different format than the Send command." #
  390.                     . "c1:k:" k #
  391.             }
  392.         } Else {
  393.             If dx
  394.                 Cache := ">3" Cache, OptionInfo := %A_ThisFunc%(A_Space), TempCommands := Commands, DxStartMS := A_TickCount, VarSetCapacity(DxInfo, 2500)
  395.                 , DxInfo .= "1:Initializing function" #
  396.                 . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
  397.                 . "t:Called at " A_Now #
  398.                 . "l:" A_LineNumber - 1
  399.                 , DxStartQPC := QPC
  400.             If DxInfo
  401.                 DxInfo .= $ "2:Restoring previous settings" #
  402.                 . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
  403.                 . "t:The passed image file and options string is the same as the last time " A_ThisFunc "() was called. The script options have been preserved as static variables and are therefore not parsed. This helps with performance in the case of multiple consecutive searches for the same image. Reload the script to avoid this behavior."
  404.         }
  405.         If DxInfo
  406.             DxInfo .= $ "1:Preparing other script settings" #
  407.             . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
  408.             . "t:If additional options were specified, " A_ThisFunc "() may need to prepare certain settings relevant to these options before performing the imagesearch." #
  409.             . "l:" A_LineNumber
  410.         SysGet, MonitorCount, MonitorCount
  411.         If (MonitorCount <> SubStr(MonitorInfo, 1, InStr(MonitorInfo, "`n") - 1)) {
  412.             MonitorInfo := MonitorCount
  413.             Loop %MonitorCount% {
  414.                 SysGet, @, Monitor, %A_Index%
  415.                 MonitorInfo .= "`n" @Left "," @Top ";" @Right - 1 "," @Bottom - 1
  416.             }
  417.         }
  418.         CoordMode, Pixel
  419.         CoordMode, Mouse
  420.         If (r <> "") {
  421.             WinGetPos, Search1, Search2, Search3, Search4, %r%
  422.             If (Search1 = "") or (Search3 <= 0) or (Search4 <= 0) {
  423.                 If (Search1 = "") {
  424.                     Error = Window Not Found
  425.                     Message = Window "%r%" was not found.
  426.                 } Else {
  427.                     Error = Window Invisible
  428.                     Message = Window "%r%" reported a negative width and/or height to AutoHotkey, meaning that it is probably not visible on the screen.
  429.                 }
  430.                 Buttons = &Debug,E&xit,&Help
  431.                 %A_ThisFunc%(">Error<")
  432.                 Return
  433.             } Else If DxInfo
  434.                 DxInfo .= $ "2:Window """ r """ found" #
  435.                 . "t:The ""r"" param was given as:`n" r "`n`nThis window was found at the following coordinates:`n<table>X;" Search1 "`nY;" Search2 "`nW;" Search3 "`nH;" Search4 "</table>`n`nThis is the new search area." #
  436.                 . "l:" A_LineNumber - 1 #
  437.                 . "d:2"
  438.             Search3 += Search1, Search4 += Search2
  439.         }
  440.         If (a <> "") and (InStr(a, "m") <> 1) {
  441.             If DxInfo
  442.                 @ := "The ""a"" (Search Area) parameter has been given as """ a """. It will be interpreted as follows:`n`n<table>X;1*`nY;2*`nW;3*`nH;4*</table>"
  443.             If (r = "")
  444.                 If (MonitorCount > 1) {
  445.                     MouseGetPos, MouseX, MouseY
  446.                     Loop, Parse, MonitorInfo, `n
  447.                         If (A_Index > 1) {
  448.                             StringSplit, Search, A_LoopField, `,;
  449.                             If (MouseX >= Search1) and (MouseY >= Search2) and (MouseX <= Search3) and (MouseY <= Search4)
  450.                                 Break
  451.                         }
  452.                 } Else
  453.                     Search1 := 0, Search2 := 0, Search3 := A_ScreenWidth - 1, Search4 := A_ScreenHeight - 1
  454.             Loop, Parse, a, |`,
  455.                 If A_LoopField is Number
  456.                 {
  457.                     Search%A_Index% := (A_LoopField >= 0 ? (A_Index & 1 ? Search1 : Search2) : (A_Index & 1 ? Search3 : Search4)) + A_LoopField
  458.                     If DxInfo
  459.                         StringReplace, @, @, %A_Index%*, % "Now = " Search%A_Index%
  460.                 }
  461.             If DxInfo
  462.                 DxInfo .= $ "2:Modifying search area" #
  463.                 . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
  464.                 . "t:" RegExReplace(@, ";\K\d\*", "Unchanged") #
  465.                 . "l:" A_LineNumber - 6
  466.             If (Search3 <= Search1) or (Search4 <= Search2) {
  467.                 Error = Search area is 0
  468.                 Message = The search area requested using the "a" option resulted in an area of 0 pixels, thus the search will not be conducted.
  469.                 Buttons = &Debug,E&xit,&Help
  470.                 %A_ThisFunc%(">Error<")
  471.                 Return
  472.             }
  473.         }
  474.         Found := 0
  475.         If (InStr(a, "m") <> 1) {
  476.             SubRegions := ((a = "") and (r = "") ? SubStr(MonitorInfo, InStr(MonitorInfo, "`n") + 1) : Search1 "," Search2 ";" Search3 "," Search4) "`n"
  477.             If (w <> "")
  478.                 SubRegionsW := SubRegions
  479.         }
  480.         If (t <> "") and (LastX1 <> "") and SubRegions {
  481.             LastX2 := LastX1 + ImageW - 1, LastY2 := LastY1 + ImageH - 1
  482.             Loop, Parse, SubRegions, `n
  483.                 If (A_LoopField <> "") {
  484.                     StringSplit, @, A_LoopField, `,;
  485.                     If (LastX1 >= @1) and (LastX2 <= @3) and (LastY1 >= @2) and (LastY2 <= @4) {
  486.                         StringReplace, t, t, -, , UseErrorLevel
  487.                         @ := ErrorLevel
  488.                         StringReplace, SubRegions, SubRegions, %A_LoopField%`n
  489.                         If InStr(t, "%")
  490.                             LastX1 += (@1 - LastX1) * SubStr(t, 1, -1) / 100, LastY1 += (@2 - LastY1) * SubStr(t, 1, -1) / 100, LastX2 += (@3 - LastX2) * SubStr(t, 1, -1) / 100, LastY2 += (@4 - LastY2) * SubStr(t, 1, -1) / 100
  491.                         Else If t Is Integer
  492.                             LastX1 -= t, LastY1 -= + t, LastX2 += t, LastY2 += t
  493.                         Else
  494.                             MsgBox, 262160, %A_ScriptName%: Error, Incorrect value of t given
  495.                         SubRegions := LastX1 "," LastY1 ";" LastX2 "," LastY2 ";P`n" . ( @ ? "" : (LastY1 > @2 ? @1 "," @2 ";" @3 "," LastY1 ";Q`n" : "") . (LastX1 > @1 ? @1 "," LastY1 ";" LastX1 "," LastY2 ";R`n" : "") . (@3 > LastX2 ? LastX2 "," LastY1 ";" @3 "," LastY2 ";S`n" : "") . (@4 > LastY2 ? @1 "," LastY2 ";" @3 "," @4 ";T`n" : "") . SubRegions )
  496.                         Break
  497.                     }
  498.                 }
  499.             LastX1 := LastY1 := ""
  500.         }
  501.         If (w <> "") {
  502.             StringSplit, w, w, `,
  503.             If (w2 = "")
  504.                 w2 := !w1 or (w1 > 1000) ? 100 : Floor(w1 / 10)
  505.             If DxInfo
  506.                 DxInfo .= $ "2:Logging start time" #
  507.                 . "t:Since the ""w"" (wait until found) option was specified, the script stores the current time (%A_TickCount%) and will perform an ImageSearch command every %w2% milliseconds until the image is found" (w1 ? " or %w1% milliseconds elapse." : ".") #
  508.                 . "c1:w1:" w1 #
  509.                 . "c2:w2:" w2 #
  510.                 . "c3:A_TickCount:" A_TickCount #
  511.                 . "q:" DllCall("QueryperformanceCounter", "Int64*", QpC) * QPC #
  512.                 . "l:" A_LineNumber + 1 #
  513.             If w1
  514.                 w1 += A_TickCount
  515.         }
  516.         If DxInfo
  517.             DxInfo .= $ "1:Searching for image" #
  518.             . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
  519.             . "t:The actual ImageSearch portion of the script will now begin. This is generally the most CPU-intensive portion of the script." #
  520.             . "l:" A_LineNumber + 1
  521.         Loop {
  522.             If DxInfo
  523.                 @ := "" #
  524.                 . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
  525.                 . "t:yyyy" #
  526.                 . "g:+.*Performing.*" #
  527.                 . "l:" A_LineNumber + 1
  528.             If (SubRegions <> "") {
  529.                 Search := SubStr(SubRegions, 1, InStr(SubRegions, "`n") - 1), SubRegions := SubStr(SubRegions, InStr(SubRegions, "`n") + 1)
  530.                 StringSplit, Search, Search, `,;
  531.                 If Search5 in A,B
  532.                     e1 := Floor(ImageW * e)
  533.                 Else If Search5 = C
  534.                     e1 := SubRegions = "" ? 0 : Floor(ImageW * e)
  535.                 Else If Search5 in P,R
  536.                     e1 := Floor(ImageW * e)
  537.                 Else
  538.                     e1 := 0
  539.                 If Search5 in P,Q,R,S
  540.                     e2 := Floor(ImageH * e)
  541.                 Else
  542.                     e2 := 0
  543.             } Else If (InStr(a, "m") = 1) {
  544.                 MouseGetPos, Search1, Search2
  545.                 If DxInfo
  546.                     @ .= $ "3:Retrieving mouse position" #
  547.                     . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
  548.                     . "t:Since the ""a"" option (search area) was given as ""%a%"", the search area will become a square region " SubStr(a, 2) "*2=" SubStr(a, 2) * 2 " pixels wide around the mouse cursor.`n`nTo find this area, " A_ThisFunc " must now get the mouse position`n`n<table>X-pos;%MouseX%`nY-pos;%MouseY%</table>" #
  549.                     . "l:" A_LineNumber - 2 #
  550.                     . "d:2" #
  551.                     . "u:m" #
  552.                     . "c1:a:" a #
  553.                     . "c2:MouseX:" Search1 #
  554.                     . "c3:MouseY:" Search2 #
  555.                     . "g:Color,Red;Trans,200;Add,Picture,x1 y5 w30 h-1," A_WinDir "\Cursors\larrow.cur;Show,x" Search1 - 20 " y" Search2 - 20 " w40 h40 NA"
  556.                 Search3 := Search1 + SubStr(a, 2), Search4 := Search2 + SubStr(a, 2), Search1 -= SubStr(a, 2), Search2 -= SubStr(a, 2), e1 := 0, e2 := 0
  557.             } Else If (MostX <> "")
  558.                 FoundXOrig := MostX, FoundYOrig := MostY, SubRegions := "`n", ErrorLevel := False
  559.             Else
  560.                 Break
  561.             If (d = "") or (SubRegions <> "`n") {
  562.                 If DxInfo
  563.                     @ .= $ "3:Performing ImageSearch" #
  564.                     . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
  565.                     . "t:The following line of code will execute:`n`n%Code_Orig%`n`nType of region: " (Search5 ? Search5 : "Normal") #
  566.                     . "l:" A_LineNumber + 2 #
  567.                     . "u:http://www.autohotkey.com/docs/imagesearch`no" #
  568.                     . "d:5" #
  569.                     . "c1:Code:ImageSearch, FoundX, FoundY, " Round(Search1) ", " Round(Search2) ", " Round(Search3) " + " e1 ", " Round(Search4) " + " e2 ", " o ImageFilePath #
  570.                     . "g:Color,FF9999,FF9999;Trans,80;Show,NA x" Search1 " y" Search2 " w" Search3 - Search1 + e1 + 1 " h" Search4 - Search2 + e2 + 1
  571.                 ImageSearch, FoundXOrig, FoundYOrig, Search1, Search2, Search3 + e1, Search4 + e2, %o%%ImageFilePath%
  572.             }
  573.             If (ErrorLevel = 2) {
  574.  
  575.                 If NewImage
  576.                     Return %A_ThisFunc%(ImageFile, Options)
  577.                 Error = File Not Found
  578.                 Message = AutoHotkey was unable to use the image "%ImageFile%" for searching.
  579.                 Buttons = &View File,&Debug,E&xit,&Help
  580.                 If (%A_ThisFunc%(">Error<") = "View File")
  581.                     MsgBox, 262160, %A_ScriptName%: Error, Function not yet supported, sorry!
  582.                 Return
  583.             } Else If !ErrorLevel {
  584.                 If DxInfo
  585.                     DxInfo .= $ "2:" (SubRegions = "`n" ? "Selecting " d "-most Image" : "Search #" A_Index " - Success") @
  586.                     . $ "3:Image Found at " FoundXOrig ", " FoundYOrig #
  587.                     . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
  588.                     . "t:The image was found at the coordinates (%FoundX%, %FoundY%). These coordinates are relative to the screen." #
  589.                     . "l:" A_LineNumber - 3 #
  590.                     . "d:5" #
  591.                     . "g:Color,Blue;Trans,80;Add,Progress,-0x20000 cRed x10 y10 w30 h30,100;Add,Progress,-0x20000 cRed x" 40 + ImageW " y10 w30 h30,100;Add,Progress,-0x20000 cRed x10 y" 40 + ImageH " w30 h30,100;Add,Progress,-0x20000 cRed x" 40 + ImageW " y" 40 + ImageH " w30 h30,100;Show,NA x" FoundXOrig - 40 " y" FoundYOrig - 40 " w" 80 + ImageW " h" 80 + ImageH #
  592.                     . "c1:FoundX:" FoundXOrig #
  593.                     . "c2:FoundY:" FoundYOrig
  594.                 If (d = "") or (SubRegions = "`n") {
  595.                     If !Found
  596.                         LastX1 := FoundXOrig, LastY1 := FoundYOrig
  597.                     Found += 1, Results .= Delim f, FoundX := FoundXOrig + Center * (ImageW - 1) // 2 + Floor(x), FoundY := FoundYOrig + Center * (ImageH - 1) // 2 + Floor(y)
  598.                     StringReplace, Results, Results, %CharX%, %FoundX%, All
  599.                     StringReplace, Results, Results, %CharY%, %FoundY%, All
  600.                     StringReplace, Results, Results, %CharN%, %Found%, All
  601.                     If n {
  602.                         If DxInfo
  603.                             DxInfo .= $ "3:Performing Clicks" #
  604.                             . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
  605.                             . "t:yyyy" #
  606.                             . "l:" A_LineNumber - 2 #
  607.                             . "u:m`nn" #
  608.                             . "g:Color,Blue;Trans,80;Add,Progress,-0x20000 cRed x10 y10 w" 29 + (ImageW + 1) // 2 " h" 29 + (ImageH + 1) // 2 ",100;Add,Progress,-0x20000 cRed x+1 yp wp+" Mod(ImageW + 1, 2) " hp,100;Add,Progress,-0x20000 cRed x10 y+1 wp-" Mod(ImageW + 1, 2) " hp+" Mod(ImageH + 1, 2) ",100;Add,Progress,-0x20000 cRed x+1 yp wp+" Mod(ImageW + 1, 2) " hp,100;Show,NA x" FoundX - 39 - (ImageW + 1) // 2 " y" FoundY - 39 - (ImageH + 1) // 2 " w" 80 + ImageW " h" 80 + ImageH
  609.                         If (Found <> 1)
  610.                             Sleep %Sleep%
  611.                         If (InStr(m, "c") = 1) {
  612.                             If (Found = 1) {
  613.                                 ControlDelay := A_ControlDelay
  614.                                 SetControlDelay, -1
  615.                                 DetectHiddenWindows := A_DetectHiddenWindows
  616.                                 DetectHiddenWindows, Off
  617.                             }
  618.                             WinGet, WinList, List
  619.                             Loop %WinList% {
  620.                                 WinGetPos, @1, @2, @3, @4, % "ahk_id " WinList%A_Index%
  621.                                 If (FoundX >= @1) and (FoundY >= @2) and (FoundX <= @1 + @3) and (FoundY <= @2 + @4) {
  622.                                     Window := WinList%A_Index%
  623.                                     WinGetPos, ClickX, ClickY, , , ahk_id %Window%
  624.                                     Break
  625.                                 } Else If (A_Index = WinList) {
  626.                                     Error = ControlClick Error
  627.                                     Message = %A_ThisFunc%() was unable to locate a window to use for a ControlClick keystroke.
  628.                                     Buttons = &Debug,E&xit,&Help
  629.                                     %A_ThisFunc%(">Error<")
  630.                                     Return
  631.                                 }
  632.                             }
  633.                         } Else {
  634.                             If (Found = 1) {
  635.                                 CoordMode, Mouse
  636.                                 MouseDelay := A_MouseDelay
  637.                                 SetMouseDelay, -1
  638.                                 MouseGetPos, MouseX, MouseY
  639.                                 If DxInfo
  640.                                     DxInfo .= $ "4:Saving mouse coordinates" #
  641.                                     . "l:" A_LineNumber - 1 #
  642.                                     . "t:Setting A_MouseDelay temporarily to -1 (fastest speed.) Also storing the current mouse coordinates.`n`n<table>Mouse X-Coordinate;%MouseX%`nMouse Y-Coordinate;%MouseY%</table>" #
  643.                                     . "c1:MouseX:" MouseX #
  644.                                     . "c2:MouseY:" MouseY #
  645.                                     . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
  646.                             }
  647.                             If DxInfo
  648.                                 DxInfo .= $ "4:Moving mouse to " MouseX ", " MouseY #
  649.                                 . "d:1" #
  650.                                 . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
  651.                                 . "l:" A_LineNumber + 1 #
  652.                                 . "t:yyyy"
  653.                             MouseMove, FoundX, FoundY, 0
  654.                         }
  655.                         Loop % n * 2 - 1 {
  656.                             If DxInfo
  657.                                 DxInfo .= $ "4:" (A_Index & 1 ? "Clicking" : "Sleeping") #
  658.                                 . "t:The following line of code will execute:`n`n%Code_Orig%" #
  659.                                 . (A_Index & 1 ? "g:-Performing Clicks" # : "")
  660.                                 . "d:4" #
  661.                                 . "l:" A_LineNumber - 14 #
  662.                                 . "c1:Code:" %A_ThisFunc%(">Escape<", !(A_Index & 1) ? "Sleep, " Sleep : SubStr(m, 1, 1) = "i" ? "SendInput, " k : SubStr(m, 1, 1) = "c" ? "ControlClick, x" FoundX - ClickX " y" FoundY - ClickY ", ahk_id " Window ", , " k ", , NA" : SubStr(m, 1, 1) = "p" ? "SendPlay, " k : SubStr(m, 1, 1) = "e" ? "SendEvent, " k : "Send, " k)
  663.                             If !(A_Index & 1)
  664.                                 Sleep %Sleep%
  665.                             Else If (SubStr(m, 1, 1) = "i")
  666.                                 SendInput %k%
  667.                             Else If (SubStr(m, 1, 1) = "c")
  668.                                 ControlClick, % "x" FoundX - ClickX " y" FoundY - ClickY, ahk_id %Window%, , %k%, , NA
  669.                             Else If (SubStr(m, 1, 1) = "p")
  670.                                 SendPlay %k%
  671.                             Else If (SubStr(m, 1, 1) = "e")
  672.                                 SendEvent %k%
  673.                             Else
  674.                                 Send %k%
  675.                         }
  676.                     } Else If (Func <> "")
  677.                         %Func%(FoundX, FoundY)
  678.                     If d or (t <> "")
  679.                         Break
  680.                 }
  681.                 If (e <> "") {
  682.                     If (FoundXOrig + ImageW < Search3) and (FoundYOrig + ImageH < Search4)
  683.                         SubRegions := FoundXOrig + ImageW "," FoundYOrig ";" Search3 "," Search4 ";" "C`n" SubRegions
  684.                     If (FoundYOrig + ImageH < Search4)
  685.                         SubRegions := FoundXOrig "," FoundYOrig + ImageH ";" FoundXOrig + ImageW - 1 "," Search4 ";" "B`n" SubRegions
  686.                     If (FoundXOrig > Search1) and (FoundYOrig + ImageH < Search4)
  687.                         SubRegions := Search1 "," FoundYOrig + 1 ";" FoundXOrig - 1 "," Search4 ";" "A`n" SubRegions
  688.                     If DxInfo
  689.                         DxInfo .= $ "3:More regions queued" #
  690.                         . "t:Because the ""e"" option was indicated, " A_ThisFunc "() needs to continue searching the screen for other instances of the image.`nThe following regions remain to be searched:`n`n<table>Top Left;Bottom Right;Region Type`n" SubRegions "</table>`n`n(Each time an image is found, the remaining space must be split into up to 3 additional regions.)" #
  691.                         . "l:" A_LineNumber - 7
  692.                     If d
  693.                         If (Asc(d) = 108) {
  694.                             If (MostX = "") or (FoundXOrig < MostX)
  695.                                 MostX := FoundXOrig, MostY := FoundYOrig
  696.                         } Else If (Asc(d) = 114) {
  697.                             If (MostX = "") or (FoundXOrig > MostX)
  698.                                 MostX := FoundXOrig, MostY := FoundYOrig
  699.                         } Else If (Asc(d) = 98) or (Asc(d) = 100) {
  700.                             If (MostX = "") or (FoundYOrig > MostY)
  701.                                 MostX := FoundXOrig, MostY := FoundYOrig
  702.                         } Else {
  703.                             If (Dist1 = "") {
  704.                                 If (Asc(d) = 109)
  705.                                     MouseGetPos, Dist1, Dist2
  706.                                 Else
  707.                                     StringSplit, Dist, d, |`,
  708.                                 Dist1 -= Center * (ImageW - 1) // 2 + Floor(x), Dist2 -= Center * (ImageH - 1) // 2 + Floor(y)
  709.                             }
  710.                             If (MostX = "") or (Sqrt((FoundXOrig - Dist1)**2 + (FoundYOrig - Dist2)**2) < Sqrt((MostX - Dist1)**2 + (MostY - Dist2)**2))
  711.                                 MostX := FoundXOrig, MostY := FoundYOrig
  712.                         }
  713.                 } Else
  714.                     Break
  715.             } Else If (w = "") or SubRegions or (w1 and (A_TickCount > w1)) {
  716.                 If DxInfo
  717.                     DxInfo .= $ "2:Search #" A_Index @
  718.                     . $ "3:Image Not Found" #
  719.                     . "t:The image was not found in the given region.`n`n" (Results ? (SubRegions = "" ? "No more regions remain to be searched (""e"" option) so the script will now finish." : "Moving on to the next region:`n" SubStr(SubRegions, 1, InStr(SubRegions, "`n") - 1)) : w = "" ? "Because the ""w"" option (wait for an image to be found) was not used, the script will now finish." : w1 ? "The ""w"" option was indicated as " w " and " A_ThisFunc "() has continued to search for the image. However the wait time has now expired and the script will finish.") #
  720.                     . "g:Color,Red;Trans,80;Show,NA x" Search1 " y" Search2 " w" Search3 - Search1 + e1 + 1 " h" Search4 - Search2 + e2 + 1 #
  721.                     . "d:3" #
  722.                     . "l:" A_LineNumber - 2
  723.  
  724.  
  725.             } Else If Results {
  726.                 MsgBox, 262144, %A_ScriptName%: Alert, Problem! See line %a_linenumber%
  727.             } Else If w2 {
  728.                 If DxInfo
  729.                     DxInfo .= $ "2:Search #" A_Index @
  730.                     . "`r3:Sleeping" #
  731.                     . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
  732.                     . "t:The ""w"" option (wait for an image to be found) was given as: %w%.`n`n<table>Total wait time;" SubStr(w, 1, InStr(w ",", ",") - 1) "`nSleep interval between searches;" (InStr(w, ",") ? SubStr(w, InStr(w, ",") + 1) "</table>" : "Not given</table>`n`nIf the sleep interval is not given then it will be assumed as either the total wait time divided by 10 or 100 milliseconds, whichever is smaller.") "`n`nSince no image has been found yet, the function now sleeps " w2 " milliseconds." #
  733.                     . "l:" A_LineNumber + 1 #
  734.                     . "c1:w:" w
  735.                 Sleep w2
  736.                 SubRegions := SubRegionsW
  737.             }
  738.         }
  739.         If DxInfo {
  740.  
  741.             DxInfo .= $ "1:Finishing" #
  742.             . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
  743.             . "t:Cache contains:`n------------------------`n%TempCache%" #
  744.             . "c1:TempCache:" %A_ThisFunc%(">Escape<", Cache) #
  745.             . "l:" A_LineNumber
  746.         }
  747.         If Results and n
  748.             If (InStr(m, "c") = 1) {
  749.                 SetControlDelay, %ControlDelay%
  750.                 DetectHiddenWindows, %DetectHiddenWindows%
  751.             } Else {
  752.                 If !Stay
  753.                     MouseMove, MouseX, MouseY, 0
  754.                 SetMouseDelay, %MouseDelay%
  755.                 If DxInfo
  756.                     DxInfo .= $ "2:" (Stay ? "LEAVING mouse" : "Returning mouse") #
  757.                     . "t:yyyy" #
  758.                     . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
  759.                     . "g:Color,Red;Trans,200;Add,Picture,x1 y5 w30 h-1," A_WinDir "\Cursors\larrow.cur;Show,x" MouseX - 20 " y" MouseY - 20 " w40 h40 NA" #
  760.                     . "l:" A_LineNumber - 3
  761.             }
  762.         If DxInfo
  763.             DxInfo .= $ "2:Returned Value" #
  764.             . "t:The function returns the following value:`n`n%Return%" #
  765.             . "c1:Return:" %A_ThisFunc%(">Escape<", Count ? Found : Results ? SubStr(Results, StrLen(Delim) + 1) : False) #
  766.             . "l:" A_LineNumber + 1
  767.             , %A_ThisFunc%(">Debug:", dx)
  768.         ErrorLevel := False
  769.         Return Count ? Found : Results ? SubStr(Results, StrLen(Delim) + 1) : False
  770.     }
  771.     Else If ImageFile = >ParseCache<
  772.     {
  773.         Loop, Parse, Cache, `n
  774.             If InStr(A_Tab A_LoopField, A_Tab Options A_Tab) {
  775.                 StringSplit, @, A_LoopField, |%A_Tab%
  776.                 If FileExist(@2) {
  777.                     StringReplace, Cache, Cache, %A_LoopField%`n
  778.                     ImageFilePath := @2, ImageW := @3, ImageH := @4, LastX1 := @5, LastY1 := @6
  779.                     If DxInfo
  780.                         DxInfo .= $ "2:Image file already used" #
  781.                         . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
  782.                         . "t:This file has been used previously by " A_ThisFunc "() and the following attributes will not have to be measured again" #
  783.                         . "l:" A_LineNumber - 2 #
  784.                         . "d:1"
  785.                         , DxInfo .= $ "3:Image width" #
  786.                         . "t:" ImageW
  787.                         , DxInfo .= $ "3:Image height" #
  788.                         . "t:" ImageH
  789.                     Return True
  790.                 }
  791.             }
  792.     }
  793.     Else If ImageFile = >GuiEvent<
  794.     {
  795.         If (A_GuiControl = "ErrorLevel")
  796.             If (A_GuiEvent = "RightClick")
  797.                 @ := A_GuiEvent ":" A_EventInfo
  798.             Else If A_GuiEvent Not In Normal,*,K
  799.                 Return
  800.         DetectHiddenWindows, Off
  801.         GuiCommand := @ <> "" ? @ : A_GuiControl <> "" ? A_GuiControl : A_ThisLabel = A_ThisFunc "Menu" ? A_ThisMenu : A_GuiEvent ? A_GuiEvent : A_ThisHotkey
  802.         If (A_Gui = GuiB) {
  803.             GuiControlGet, @, %GuiB%:, Edit1
  804.             If !ErrorLevel
  805.                 GuiCommand .= "`n" @
  806.             Gui, %GuiA%:-Disabled
  807.             Gui, %GuiB%:Destroy
  808.         } Else If GuiTitle
  809.             WinSetTitle, ahk_id %GuiHWND%, , % SubStr(GuiTitle, 1, InStr(GuiTitle, ":") - 1)
  810.     }
  811.     Else If ImageFile = >Escape<
  812.     {
  813.         StringReplace, Options, Options, ``, ````, All
  814.         StringReplace, Options, Options, %#%, ``#, All
  815.         StringReplace, Options, Options, %$%, ``$, All
  816.         Return Options
  817.     } Else If (ImageFile = ">UnEscape<") {
  818.         Options := RegExReplace(RegExReplace(Options, "(?<!``)``#", #), "(?<!``)``\$", $)
  819.         StringReplace, Options, Options, ````, ``, All
  820.         Return Options
  821.     }
  822.     Else If ImageFile = >ShowChars<
  823.     {
  824.         If (Options = "")
  825.             Return "[EMPTY STRING]"
  826.         Else If (Options = False)
  827.             Return "[0 : FALSE]"
  828.         Else If (Options = True)
  829.             Return "[1 : TRUE]"
  830.         StringReplace, Options, Options, `r, [CR], All
  831.         StringReplace, Options, Options, `n, [NL], All
  832.         StringReplace, Options, Options, %A_Space%, [_], All
  833.         StringReplace, Options, Options, %A_Tab%, [ » ], All
  834.         Invisible = 0,1,2,3,4,5,6,7,8,11,12,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,127
  835.         Loop, Parse, Invisible, `,
  836.             StringReplace, Options, Options, % Chr(A_LoopField), [Chr%A_LoopField%], All
  837.         Return Options
  838.     }
  839.     Else If ImageFile = >NewGui<
  840.     {
  841.         Loop, Parse, Options, `;
  842.             If (A_Index = 1) {
  843.                 Gui, %A_LoopField%:Destroy
  844.                 Gui, %A_LoopField%:+LastFound
  845.                 ThisNum := A_LoopField, ThisHWND := WinExist()
  846.             } Else {
  847.                 @2 := @3 := @4 := ""
  848.                 StringSplit, @, A_LoopField, `,
  849.                 If @1 in Trans,Region
  850.                     WinSet, %@1%, %@2%, ahk_id %ThisHWND%
  851.                 Else
  852.                     Gui, %ThisNum%:%@1%, %@2%, %@3%, % SubStr(A_LoopField, StrLen(@1 @2 @3) + 4)
  853.             }
  854.         Return ThisHWND
  855.     }
  856.     Else If ImageFile = >Table<
  857.     {
  858.         If RegExMatch(Options, "is)<table>\K.*?(?=</table>)", Table)
  859.             While (3 > Cycle := A_Index)
  860.                 Loop, Parse, Table, `n
  861.                 {
  862.                     StringSplit, @, A_LoopField, `;
  863.                     Loop %@0%
  864.                         If (Cycle = 2)
  865.                             Output .= A_Index = @0 ? @%A_Index% "`n" : SubStr(@%A_Index% "                ", 1, Max%A_Index%) "     "
  866.                         Else If (Max%A_Index% < StrLen(@%A_Index%))
  867.                             Max%A_Index% := StrLen(@%A_Index%)
  868.                 }
  869.         StringReplace, Options, Options, <table>%Table%</table>, % SubStr(Output, 1, -1)
  870.         Return Options
  871.     }
  872.     Else If ImageFile = >MakeImage<
  873.     {
  874.         Loop, Parse, Options, |
  875.             If (A_Index = 5)
  876.                 Break
  877.             Else
  878.                 Param%A_Index% := A_LoopField
  879.         StringTrimLeft, Options, Options, StrLen(Param1 Param2 Param3 Param4) + 4
  880.         FileDelete, %Param1%
  881.         If A_PtrSize
  882.             Ptr := "UPtr", PtrA := "UPtr*", PtrSize := A_PtrSize
  883.         Else
  884.             Ptr := "UInt", PtrA := "UInt*", PtrSize := 4
  885.         If !DllCall("GetModuleHandle", "str", "gdiplus")
  886.             DllCall("LoadLibrary", "str", "gdiplus")
  887.         sOutput := Param1 "." Param2, VarSetCapacity(si, 16, 0), si := Chr(1), DllCall("gdiplus\GdiplusStartup", "uint*", pToken, "uint", &si, "uint", 0), DllCall("gdiplus\GdipCreateBitmapFromScan0", "int", Param3, "int", Param4, "int", 0, "int", 0x26200A, Ptr, 0, PtrA, pBitmap)
  888.         Loop, Parse, Options, |
  889.             DllCall("gdiplus\GdipBitmapSetPixel", Ptr, pBitmap, "int", Mod(A_Index - 1, Param3), "int", (A_Index - 1) // Param3, "int", "0xFF" A_LoopField)
  890.         DllCall("gdiplus\GdipGetImageEncodersSize", "uint*", nCount, "uint*", nSize), VarSetCapacity(ci, nSize), DllCall("gdiplus\GdipGetImageEncoders", "uint", nCount, "uint", nSize, Ptr, &ci)
  891.         Loop, %nCount% {
  892.             If A_PtrSize
  893.                 @ := "StrGet", sString := %@%(NumGet(ci, (idx := (48 + 7 * A_PtrSize) * (A_Index - 1)) + 32 + 3 * A_PtrSize), "UTF-16")
  894.             Else
  895.                 idx := 76 * (A_Index - 1), Address := NumGet(ci, idx + 44), char_count := DllCall("WideCharToMultiByte", "uint", 0, "uint", 0x400, "uint", Address, "int", -1, "uint", 0, "uint", 0, "uint", 0, "uint", 0), VarSetCapacity(sString, char_count), DllCall("WideCharToMultiByte", "uint", 0, "uint", 0x400, "uint", Address, "int", -1, "str", sString, "int", char_count, "uint", 0, "uint", 0)
  896.             If InStr(sString, "*." Param2) {
  897.                 pCodec := &ci + idx
  898.                 Break
  899.             }
  900.         }
  901.         If A_IsUnicode
  902.             DllCall("gdiplus\GdipSaveImageToFile", Ptr, pBitmap, Ptr, &sOutput, Ptr, pCodec, "uint", 0)
  903.         Else
  904.             nSize := DllCall("MultiByteToWideChar", "uint", 0, "uint", 0, Ptr, &sOutput, "int", -1, Ptr, 0, "int", 0), VarSetCapacity(wOutput, nSize * 2), DllCall("MultiByteToWideChar", "uint", 0, "uint", 0, Ptr, &sOutput, "int", -1, Ptr, &wOutput, "int", nSize), VarSetCapacity(wOutput, -1), VarSetCapacity(wOutput), DllCall("gdiplus\GdipSaveImageToFile", Ptr, pBitmap, Ptr, &wOutput, Ptr, pCodec, "uint", 0)
  905.         DllCall("gdiplus\GdipDisposeImage", Ptr, pBitmap), DllCall("gdiplus\GdiplusShutdown", Ptr, pToken)
  906.         If (hModule := DllCall("GetModuleHandle", "str", "gdiplus", Ptr))
  907.             DllCall("FreeLibrary", Ptr, hModule)
  908.         If !FileExist(Param1 "." Param2) {
  909.             MsgBox, 262164, %A_ScriptName% - %A_ThisFunc%(): Trouble building file!,  %A_ThisFunc%() had intended to build an image file using GDI+ to output to the following path:`n%Param1%.%Param2%`n`nThis procedure has failed, possibly for one of the following reasons:`n1) You do not have access to the file location in question.`n2) You are using a version of windows that doesn't support the GDI+ procedures the script needs.`n3) Berban has made a silly mistake (most likely answer).`n`nIf this error recurs, please report it on the AutoHotkey forums.`n`nVisit the forums now?
  910.             IfMsgBox YES
  911.                 Run %ForumURL%
  912.         }
  913.     }
  914.     Else If ImageFile = >Error<
  915.     {
  916.         ErrorLevel = %Error% - %Message%
  917.         If !Silent
  918.             If !DxInfo {
  919.                 Margins = 10
  920.                 MsgBoxWidth = 250
  921.                 ButtonWidth = 90
  922.                 ControlHeight = 24
  923.                 TextSize = 10
  924.                 Loop, Parse, Buttons, CSV
  925.                     ButtonList .= ";Add,Button,g" A_ThisFunc "Close y+" Margins " x" Margins " w" ButtonWidth " h" ControlHeight "," A_LoopField
  926.                 WinWaitClose, % "ahk_id " %A_ThisFunc%(">NewGui<", GuiB . ";+AlwaysOnTop +Label" A_ThisFunc . ";Add,Picture,Icon132 x" Margins " y" Margins ",Shell32.dll" . ButtonList . ";Font,s" TextSize . ";Add,Text,x+" Margins " y" Margins " w" MsgBoxWidth - ButtonWidth - Margins "," Message . ";Show,w" MsgBoxWidth + Margins * 2 ",Error: " Error)
  927.                 GuiCommand := RegExReplace(GuiCommand, "(?<!&)&(?!&)")
  928.                 If GuiCommand = Help
  929.                     Run, %ForumURL%
  930.                 Else If GuiCommand = Debug
  931.                     @ := LastImageFile, LastImageFile := ""
  932.                     , %A_ThisFunc%(@, LastOptions " dx")
  933.                 Return GuiCommand, ErrorLevel := Error " - " Message
  934.             } Else
  935.                 DxInfo .= $ "2:Error - " Error #
  936.                     . "t:" Message #
  937.                     . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
  938.                     . "l:" A_LineNumber - 5
  939.                 , DxInfo .= $ "1:Finishing" #
  940.                     . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
  941.                     . "t:Cache contains:`n------------------------`n" %A_ThisFunc%(">ShowChars<", Cache)
  942.                 , %A_ThisFunc%(">Debug:", dx)
  943.     }
  944.     Else If (InStr(ImageFile, ">Debug:") = 1)
  945.     {
  946.         DetectHiddenWindows := A_DetectHiddenWindows, WinDelay := A_WinDelay
  947.         DetectHiddenWindows, On
  948.         SetWinDelay, -1
  949.  
  950.  
  951.         DebugSettingsLocation = %A_LineNumber%
  952.         TextBoxFontSize = 9
  953.         TextBoxFontFace = Lucida Console
  954.         TreeViewFontSize = 10
  955.         TreeViewFontFace = Segoe UI
  956.         Width = 350
  957.         ControlHeight = 30
  958.         TextBoxHeight = 200
  959.         TreeViewHeight = 250
  960.         PlayingText = Playing
  961.         ButtonWidth = 60
  962.         Margins = 7
  963.         PlaySpeed = .3
  964.         ButtonFontSize = 10
  965.         ButtonFontFace = Segoe UI
  966.         ButtonPlay = &Play
  967.         ButtonPause = &Pause
  968.         ButtonPrev = <
  969.         ButtonNext = >
  970.  
  971.         MenuFile = &%A_ThisFunc%
  972.         MenuFilePrev = &Previous Step
  973.         MenuFileNext = &Next Step
  974.         MenuFileStandard = Script &Menu
  975.         MenuFileEdit = &Go to line
  976.         MenuFileSave = &Save
  977.         MenuFileExit = E&xit
  978.  
  979.         MenuCopy = &Clipboard
  980.         MenuCopyStepName = Copy Step &Name
  981.         MenuCopyStepText = Copy Step &Text
  982.  
  983.         MenuSettings = &Settings
  984.         MenuSettingsCompactView = &Compact View
  985.         MenuSettingsAlwaysOnTop = &Always On Top
  986.         MenuSettingsShowGraphics = Show &Graphics
  987.         MenuSettingsShowChars = Show &Whitespaces
  988.         MenuSettingsWrapText = &Wrap Text
  989.         MenuSettingsEdit = &Edit Debugger Settings
  990.         MenuSettingsSkipSteps = Skip Unimportant Steps
  991.         MenuSettingsAutoClose = Close When Finished
  992.  
  993.         MenuHelp = &Help
  994.         MenuHelpDocs = &%A_ThisFunc% Documentation
  995.         MenuHelpDebugger = &Debugger Help
  996.         MenuHelpWhitespaceView = &Whitespace Viewer Help
  997.         MenuHelpAbout = &About %A_ThisFunc%
  998.  
  999.         EditorPath = %A_AhkPath%\..\SciTE\SciTE.exe
  1000.         EditorCommand = -goto:`%LineNumber`%
  1001.  
  1002.         CompactView = %False%
  1003.         ShowChars = %True%
  1004.         ShowGraphics = %True%
  1005.         AlwaysOnTop = %False%
  1006.         WrapText = %True%
  1007.         PlaySpeed = 3
  1008.         Playing = %False%
  1009.         SkipSteps = %True%
  1010.         StartAt = 1
  1011.         SaveTo =
  1012.         AutoClose = %False%
  1013.  
  1014.         HotkeyPlay = Space
  1015.         HotkeyNext = .
  1016.         HotkeyPrev = ,
  1017.         HotkeyCompactView = ``
  1018.         ShrinkByW = 50
  1019.         ShrinkByH = 100
  1020.         Menus =
  1021.         (
  1022.         Standard
  1023.         File:Prev,Next,Play,,Standard,,Edit,Save,Exit
  1024.         Copy:StepName,StepText,
  1025.         Settings:CompactView,AlwaysOnTop,ShowGraphics,ShowChars,WrapText,SkipSteps,AutoClose,,Edit
  1026.         Help:Docs,Debugger,WhitespaceView,About,
  1027.         Bar:File,Copy,Settings,Help
  1028.         Context:File,Copy,Settings,Help
  1029.         )
  1030.  
  1031.         Loop, Parse, Options, CSV
  1032.             If (A_LoopField = "Reset")
  1033.                 LastImageFile := Cache := ""
  1034.             Else If RegExMatch(A_LoopField, "^([A-Za-z0-9_#$]+)=([\s\S]*)$", @)
  1035.                 %@1% := @2
  1036.             Else If (A_Index <> 1)
  1037.                 MsgBox, 262160, %A_ScriptName% - %A_Thisfunc%(): Error, Poorly formatted Options param for diagnostic mode:`n%A_LoopField%
  1038.         If SaveTo {
  1039.             FileDelete, %SaveTo%
  1040.             StringReplace, DxInfo, DxInfo, `r, `r`n, All
  1041.             FileAppend, %DxInfo%, %SaveTo%
  1042.             Return DxInfo := ""
  1043.         }
  1044.         StringReplace, Menus, Menus, %A_Space%, , All
  1045.         StringReplace, Menus, Menus, %A_Tab%, , All
  1046.         MenuStandard := True, Hotkeys := "Play,Next,Prev,CompactView", Buttons := "Button1,Button2,Button3,Edit2"
  1047.         Menu, %A_ThisFunc%MenuStandard, Standard
  1048.         Loop, Parse, Menus, `n
  1049.             Loop, Parse, A_LoopField, :`,
  1050.                 If (A_Index > 1) {
  1051.                     Menu, %A_ThisFunc%Menu%ThisMenu%, Add, % (A_LoopField = "" ? "" : ThisMenu = "Bar" or ThisMenu = "Context" ? Menu%A_LoopField% : Menu%ThisMenu%%A_LoopField% = "" ? Button%A_LoopField% : Menu%ThisMenu%%A_LoopField%) (Hotkey%A_LoopField% = "" ? "" : A_Tab Hotkey%A_LoopField%), % Menu%A_LoopField% = "" ? A_ThisFunc "Menu" : ":" A_ThisFunc "Menu" A_LoopField
  1052.                     If A_LoopField and %A_LoopField%
  1053.                         Menu, %A_ThisFunc%Menu%ThisMenu%, Check, % Menu%ThisMenu%%A_LoopField% (Hotkey%A_LoopField% = "" ? "" : A_Tab Hotkey%A_LoopField%)
  1054.                 } Else
  1055.                     ThisMenu := A_LoopField
  1056.         GuiHWND := %A_ThisFunc%(">NewGui<", GuiA
  1057.         . ";+Label" A_ThisFunc (AlwaysOnTop ? " +AlwaysOnTop" : "")
  1058.         . ";Font,s" ButtonFontSize "," ButtonFontFace
  1059.         . ";Menu," A_ThisFunc "MenuBar"
  1060.         . ";Add,Button,g" A_ThisFunc "Close x" Margins " y" Margins " w" ButtonWidth " h" ControlHeight "," ButtonPrev
  1061.         . ";Add,Button,g" A_ThisFunc "Close x+" Margins " yp wp hp," ButtonPlay
  1062.         . ";Add,Button,g" A_ThisFunc "Close x+" Margins " yp wp hp +Default," ButtonNext
  1063.         . ";Font,s" TreeViewFontSize "," TreeViewFontFace
  1064.         . ";Add,TreeView,g" A_ThisFunc "Close vErrorLevel +AltSubmit x" Margins " y+" Margins " w" Width " h" TreeViewHeight
  1065.         . ";Font,s" TextBoxFontSize "," TextBoxFontFace
  1066.         . ";Add,Edit,+ReadOnly " (WrapText ? "+Wrap -HScroll" : "-Wrap +HScroll") " x" Margins " y+" Margins " w" Width " h" TextBoxHeight
  1067.         . ";Add,Edit,-VScroll +ReadOnly -Wrap x" ButtonWidth * 3 + Margins * 4 " y" Margins " w" Width - (Margins + ButtonWidth) * 3 " h" ControlHeight
  1068.         . ";Default")
  1069.         If (StrLen(ImageFile) > 7) {
  1070.             StringTrimLeft, ImageFile, ImageFile, 7
  1071.             If !FileExist(ImageFile) {
  1072.                 MsgBox, 262160, %A_ScriptName% - %A_ThisFunc%(): Error, Debug file "%ImageFile%" does not appear to exist.
  1073.                 Return
  1074.             } Else
  1075.                 FileRead, DxInfo, %ImageFile%
  1076.         } Else If (DxInfo = "") {
  1077.             MsgBox, 262160, %A_ScriptName% - %A_ThisFunc%(): Error, Improper use of the Diagnostic mode.
  1078.             Return
  1079.         } Else
  1080.             DxInfo := A_TickCount A_Tab DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC A_Tab DxInfo
  1081.         If StartAt Is Integer
  1082.             CurrentStep := StartAt
  1083.         Else
  1084.             RegExMatch(StartAt, "^(?:(?P<Occurence>\d+):)?(?P<Pattern>[\s\S]*)$", StartAt)
  1085.         Loop, Parse, DxInfo, `r, `n
  1086.             If (A_Index = 1) {
  1087.                 StringSplit, @, A_LoopField, %A_Tab%
  1088.                 QPC_Rate := (@1 - @3) / (@2 - @4), QPC_Final := @2
  1089.             } Else {
  1090.                 Items := A_Index - 1
  1091.                 Loop, Parse, A_LoopField, %A_Tab%
  1092.                     If (A_Index = 1) {
  1093.                         %Items%_Level := @1 := Asc(A_LoopField) = 43 ? @2 + 2 : Asc(A_LoopField) = 45 ? @2 : SubStr(A_LoopField, 1, 1), @2 := @1 - 1, %Items%_ID := TV%@1% := TV_Add(%Items%_Title := SubStr(A_LoopField, 3), TV%@2%)
  1094.                         If !CurrentStep and RegExMatch(%Items%_Title, StartAtPattern) and !(--StartAtOccurence)
  1095.                             CurrentStep := Items
  1096.                     } Else If InStr(A_LoopField, ":") {
  1097.                         @1 := SubStr(A_LoopField, 1, InStr(A_LoopField, ":") - 1), %Items%_%@1% := SubStr(A_LoopField, InStr(A_LoopField, ":") + 1)
  1098.                         If @1 = g
  1099.                             TV_Modify(%Items%_ID, "Bold")
  1100.                     }
  1101.             }
  1102.         @ := Items + 1, %@%_q := QPC_Final, PreviousStep := 0, PlaySpeed := PlaySpeed / 20
  1103.         Gui, %GuiA%:Show, % "w" Width + Margins * 2 " h" TreeViewHeight + TextBoxHeight + ControlHeight + Margins * 4
  1104.         Hotkey, IfWinActive, ahk_id %GuiHWND%
  1105.         Loop, Parse, Hotkeys, `,
  1106.             If (Hotkey%A_LoopField% <> "")
  1107.                 Hotkey, % Hotkey%A_LoopField%, %A_ThisFunc%Close, On
  1108.         Hotkey, IfWinActive
  1109.         If Playing
  1110.             TempGuiCommand := ButtonPlay, Playing := False
  1111.         If !CurrentStep
  1112.             CurrentStep := 1
  1113.         Loop {
  1114.             If (A_Index <> 1)
  1115.                 TempGuiCommand := GuiCommand
  1116.             GuiCommand := RightClick := ""
  1117.             If (TempGuiCommand = ButtonPlay) or (TempGuiCommand = ButtonPause) or (TempGuiCommand = HotkeyPlay) or (Playing and (TempGuiCommand = "ErrorLevel")) {
  1118.                 Playing := !Playing
  1119.                 ControlSetText, Button2, % Playing ? ButtonPause : ButtonPlay, ahk_id %GuiHWND%
  1120.                 Menu, %A_ThisFunc%MenuFile, Rename, % (Playing ? ButtonPlay : ButtonPause) A_Tab HotkeyPlay, % (Playing ? ButtonPause : ButtonPlay) A_Tab HotkeyPlay
  1121.             } Else If (TempGuiCommand = MenuSettingsCompactView) or (TempGuiCommand = HotkeyCompactView) {
  1122.                 If (TempGuiCommand = HotkeyCompactView)
  1123.                     Menu, %A_ThisFunc%MenuSettings, % (CompactView := !CompactView) ? "Check" : "Uncheck", %MenuSettingsCompactView%%A_Tab%%HotkeyCompactView%
  1124.                 Loop % n := 10 {
  1125.                     GuiControl, %GuiA%:Move, ErrorLevel, % "x" Margins " y" Margins + (Margins + ControlHeight) * (n - (@ := CompactView ? A_Index : n - A_Index)) / n " w" Width - ShrinkByW * @ / n " h" TreeViewHeight - ShrinkByH * @ / n
  1126.                     Gui, %GuiA%:Show, % "NA w" Width + Margins * 2 - ShrinkByW * @ / n " h" TreeViewHeight + Margins * 4 + TextBoxHeight + ControlHeight - (ShrinkByH + TextBoxHeight + Margins * 2 + ControlHeight) * @ / n
  1127.                 }
  1128.                 Loop, Parse, Buttons, `,
  1129.                     GuiControl, %GuiA%:Move, %A_LoopField%, % CompactView ? "y-200" : "y" Margins
  1130.             } Else If (TempGuiCommand = ButtonPrev) or (TempGuiCommand = HotkeyPrev) or (TempGuiCommand = MenuFilePrev)
  1131.                 CurrentStep -= CurrentStep = 1 ? 0 : 1
  1132.             Else If (TempGuiCommand = "Normal") or (TempGuiCommand = MenuFileExit) {
  1133.                 Gui, %GuiA%:Destroy
  1134.                 Gui, %GuiB%:Destroy
  1135.                 Hotkey, IfWinActive, ahk_id %GuiHWND%
  1136.                 Loop, Parse, Hotkeys, `,
  1137.                     If (Hotkey%A_LoopField% <> "")
  1138.                         Hotkey, % Hotkey%A_LoopField%, Off
  1139.                 Hotkey, IfWinActive
  1140.                 Loop, Parse, Menus, `n
  1141.                     Menu, % A_ThisFunc "Menu" SubStr(A_LoopField, 1, Instr(A_LoopField ":", ":") - 1), Delete
  1142.                 DetectHiddenWindows, %DetectHiddenWindows%
  1143.                 SetWinDelay, %WinDelay%
  1144.                 Return GuiHWND := DxInfo := ""
  1145.             } Else If (TempGuiCommand = MenuSettingsAlwaysOnTop)
  1146.                 WinSet, AlwaysOnTop, % AlwaysOnTop ? "On" : "Off", ahk_id %GuiHWND%
  1147.             Else If (TempGuiCommand = MenuSettingsWrapText)
  1148.                 GuiControl, % GuiA ":" (WrapText ? "+Wrap" : "-Wrap"), Edit1
  1149.             Else If (TempGuiCommand = MenuFileNext) or (TempGuiCommand = ButtonNext) or (TempGuiCommand = HotkeyNext) or ((TempGuiCommand = "") and Playing) {
  1150.                 While (CurrentStep < Items) {
  1151.                     CurrentStep += 1
  1152.                     If (TempGuiCommand <> "") or !Playing or (%CurrentStep%_d <> "") or !SkipSteps
  1153.                         Break
  1154.                 }
  1155.                 If (CurrentStep = Items) and (TempGuiCommand = "") and Playing
  1156.                     GuiCommand := InStr(Options, ",c,") ? "Normal" : ButtonPause
  1157.             } Else If (InStr(TempGuiCommand, A_ThisFunc "Menu") <> 1) {
  1158.                 If (InStr(TempGuiCommand, "RightClick:") = 1)
  1159.                     RightClick := True, TV_Modify(@ := SubStr(TempGuiCommand, 12))
  1160.                 Else
  1161.                     @ := TV_GetSelection()
  1162.                 Loop %Items%
  1163.                     If (%A_Index%_ID = @) {
  1164.                         CurrentStep := A_Index
  1165.                         Break
  1166.                     }
  1167.             } Else If (TempGuiCommand = A_ThisFunc "MenuCopy")
  1168.                 Clipboard := A_ThisMenuItem = MenuCopyStepText ? CurrentStepText : A_ThisMenuItem = MenuCopyStepName ? CurrentStep " - " %CurrentStep%_Title : %A_ThisMenuItem%_Orig_
  1169.             Else If (A_ThisMenuItem = MenuFileEdit LastLine) or (A_ThisMenuItem = MenuSettingsEdit) {
  1170.                 LineNumber := A_ThisMenuItem = MenuSettingsEdit ? DebugSettingsLocation : %CurrentStep%_l
  1171.                 Transform, @, Deref, %EditorCommand%
  1172.                 Run, "%EditorPath%" "%A_LineFile%" %@%
  1173.             } Else If (A_ThisMenuItem = MenuFileSave) {
  1174.                 Gui, %GuiA%:+OwnDialogs
  1175.                 FileSelectFile, File, S, %A_ThisFunc%-dx-%A_Now%.txt
  1176.                 If !ErrorLevel {
  1177.                     FileDelete, %File%
  1178.                     StringReplace, @, DxInfo, `r, `r`n, All
  1179.                     FileAppend, %@%, %File%
  1180.                     MsgBox, 262144, %A_ScriptName% - %A_ThisFunc%: Alert, Disgnostic file saved successfully.
  1181.                 }
  1182.                 Gui, %GuiA%:-OwnDialogs
  1183.             } Else If (TempGuiCommand = A_ThisFunc "MenuHelp") {
  1184.                 If (A_ThisMenuItem = MenuHelpWhitespaceView)
  1185.                     MsgBox, 262144, Whitespace Viewer Legend, If the "Show Whitespace" option is checked in the Settings menu, the following substitutions will be made for all non-visible characters:`n`n[EMPTY STRING]`ta blank/empty string`n[0 : FALSE]`t`t0 (`%false`%)`n[1 : TRUE]`t`t1 (`%true`%)`n[CR]`t`tcarriage return (``r)`n[NL]`t`tnewline (``n)`n[_]`t`tspace (`%A_Space`%)`n[ » ]`t`ttab (`%A_Tab`%)`n[Chr1], [Chr2], etc`tASCII character #1, #2, etc (these are non-visible characters)`n`nThese substitutions are not made when copying the contents of variables using the Clipboard menu.
  1186.                 Else If (A_ThisMenuItem = MenuHelpAbout)
  1187.                     MsgBox, 262144, About %A_ThisFunc%, FindClick() - ImageSearch utility. Created by berban.`n`nMade with AutoHotkey. Compatible with all versions.`n`nLast updated %LastUpdate%.
  1188.                 Else If (A_ThisMenuItem = MenuHelpDocs)
  1189.                     Run, %ForumURL%
  1190.                 Else
  1191.                     MsgBox, 262160, %A_ScriptName%: Error, This menu item currently doesn't do anything. Sorry about that.
  1192.             } Else {
  1193.                 If (TempGuiCommand = A_ThisFunc "MenuSettings") {
  1194.                     If (Settings = "")
  1195.                         RegExMatch(Menus, "\bSettings:\K\S*", Settings)
  1196.                     Loop, Parse, Settings, `,
  1197.                         If (A_LoopField <> "") and (InStr(A_ThisMenuItem A_Tab, MenuSettings%A_LoopField% A_Tab) = 1) {
  1198.                             Menu, %A_ThisFunc%MenuSettings, % (%A_LoopField% := !%A_LoopField%) ? "Check" : "Uncheck", %A_ThisMenuItem%
  1199.                             Break
  1200.                         }
  1201.                 }
  1202.                 GuiCommand := SubStr(A_ThisMenuItem, 1, InStr(A_ThisMenuItem A_Tab, A_Tab) - 1), PreviousStep := 0
  1203.             }
  1204.             If (CurrentStep <> PreviousStep) {
  1205.                 Loop, Parse, MenuCopyItems, `,
  1206.                     If (A_LoopField <> "") {
  1207.                         %A_LoopField%_ := %A_LoopField%_Orig_ := ""
  1208.                         Menu, %A_ThisFunc%MenuCopy, Delete, %A_LoopField%
  1209.                     }
  1210.                 Loop, Parse, MenuHelpItems, `,
  1211.                     If (A_LoopField <> "")
  1212.                         Menu, %A_ThisFunc%MenuHelp, Delete, %A_LoopField%
  1213.                 MenuCopyItems := MenuHelpItems := ""
  1214.                 While (%CurrentStep%_c%A_Index% <> "") {
  1215.                     @ := SubStr(%CurrentStep%_c%A_Index%, 1, InStr(%CurrentStep%_c%A_Index%, ":") - 1)
  1216.                     , %@%_Orig_ := %A_ThisFunc%(">UnEscape<", SubStr(%CurrentStep%_c%A_Index%, InStr(%CurrentStep%_c%A_Index%, ":") + 1))
  1217.                     , %@%_ := ShowChars ? %A_ThisFunc%(">ShowChars<", %@%_Orig_) : %@%_Orig_
  1218.                     , MenuCopyItems .= @ ","
  1219.                     Menu, %A_ThisFunc%MenuCopy, Add, %@%, %A_ThisFunc%Menu
  1220.                 }
  1221.                 Loop, Parse, %CurrentStep%_u, |
  1222.                     If (A_LoopField <> "") {
  1223.                         Menu, %A_ThisFunc%MenuHelp, Add, %A_LoopField%, %A_ThisFunc%Menu
  1224.                         MenuHelpItems .= A_LoopField ","
  1225.                     }
  1226.                 PreviousStep := CurrentStep, @ := 0, CurrentStepText := %CurrentStep%_t
  1227.                 Transform, CurrentStepText, Deref, % CurrentStepText := RegExReplace(CurrentStepText, "%([A-Za-z0-9_#@$?]+)%", "%$1_%")
  1228.                 While InStr(CurrentStepText, "<table>")
  1229.                     CurrentStepText := %A_ThisFunc%(">Table<", CurrentStepText)
  1230.                 StringReplace, CurrentStepText, CurrentStepText, `n, `r`n, All
  1231.                 GuiControl, %GuiA%:, Edit1, %CurrentStepText%
  1232.                 If %CurrentStep%_q
  1233.                     While (%@%_Level > %CurrentStep%_Level) or !%@%_q
  1234.                         @ := CurrentStep + A_Index
  1235.                 Menu, %A_ThisFunc%MenuFile, Rename, %MenuFileEdit%%LastLine%, ----
  1236.                 Menu, %A_ThisFunc%MenuFile, Rename, ----, % MenuFileEdit LastLine := A_Space %CurrentStep%_l
  1237.                 Menu, %A_ThisFunc%MenuFile, % %CurrentStep%_l ? "Enable" : "Disable", %MenuFileEdit%%LastLine%
  1238.                 ControlSetText, Edit2, % "Time (ms):  " (%CurrentStep%_q ? Round((%@%_q - %CurrentStep%_q) * QPC_Rate, 3) : "") "`r`nLine No.:   " %CurrentStep%_l, ahk_id %GuiHWND%
  1239.                 Gui, %GuiB%:Destroy
  1240.                 If (%CurrentStep%_g <> "") and ShowGraphics {
  1241.                     @ := CurrentStep, @1 := Asc(%CurrentStep%_g) = 43 ? 1 : Asc(%CurrentStep%_g) = 45 ? -1 : 0
  1242.                     If @1
  1243.                         While !RegExMatch(%@%_Title, "is)^" SubStr(%CurrentStep%_g, 2) "$") and @ and (@ <= Items)
  1244.                             @ += @1
  1245.                     If (%@%_g <> "")
  1246.                         %A_ThisFunc%(">NewGui<", GuiB ";+ToolWindow -SysMenu -Caption +AlwaysOnTop +E0x20;" %@%_g)
  1247.                     Else
  1248.                         MsgBox, 262160, %A_ScriptName%: Error, Error with referenced graphics!!!! Fix me ben!
  1249.                 }
  1250.                 TempGuiCommand := GuiCommand, TV_Modify(%CurrentStep%_ID)
  1251.                 If (TempGuiCommand = "") and Playing {
  1252.                     While (GuiCommand = "")
  1253.                         Sleep 1
  1254.                     If (GuiCommand = "ErrorLevel")
  1255.                         GuiCommand := ""
  1256.                 }
  1257.             }
  1258.             If RightClick
  1259.                 Menu, %A_ThisFunc%MenuContext, Show
  1260.             If (GuiCommand = "") {
  1261.                 WinSetTitle, ahk_id %GuiHWND%, , % GuiTitle := A_ThisFunc " Debugger" (Playing ? " - " PlayingText : "") ": " CurrentStep " - " %CurrentStep%_Title
  1262.                 WinWaitClose, %GuiTitle% ahk_id %GuiHWND%, , Playing ? ((%CurrentStep%_d ? %CurrentStep%_d : 1) * PlaySpeed) : ""
  1263.             }
  1264.         }
  1265.     } Else If (GuiHWND = "") {
  1266.         CoordMode, Mouse, Screen
  1267.         CoordMode, Pixel, Screen
  1268.         CoordMode, Menu, Screen
  1269.  
  1270.  
  1271.         TempFile = %A_Temp%\%A_ThisFunc%Temp.png
  1272.         NewFilePlaceHolder = NewFile
  1273.         PauseHotkey = ``
  1274.         SquareSize = 19
  1275.         SquaresWide = 22
  1276.         SquaresHigh = 18
  1277.         SquareSpacing = 2
  1278.         ControlHeight = 20
  1279.         Margins = 10
  1280.         FontSize = 10
  1281.         FontFace = Segoe UI
  1282.         SelectionColor = 0xFF0000
  1283.         CurRegionColor = 0x0000FF
  1284.         CurRegionThickness = 3
  1285.         DoubleTapToSelect = %True%
  1286.         PromptOnOverwrite = %True%
  1287.         RecycleOnOverwrite = %True%
  1288.         AutoJumpToFileName = %True%
  1289.         InputBoxWidth = 300
  1290.         StartPaused = %False%
  1291.         AllowOffset = %False%
  1292.         DiagnosticMode = %True%
  1293.         DiagnosticModeOptions = Playing=0
  1294.         CopyToClipboard = %False%
  1295.  
  1296.  
  1297.         CheckboxOffset = Allow O&ffset
  1298.         ButtonPause = &Pause ( %PauseHotkey% )
  1299.         ButtonUnPause = Un&pause ( %PauseHotkey% )
  1300.         ButtonTest = &Test
  1301.         ButtonSave = &Save
  1302.         ButtonBrowse = &Browse
  1303.         ButtonOther = &Other
  1304.         ButtonCancel = &Cancel
  1305.         ButtonAddOption = &Add option...
  1306.         ButtonJumpToFileName = &I
  1307.         CheckboxCopyToClipboard = Copy code to c&lipboard
  1308.         CheckboxDiagnosticMode = &Use diagnostic mode:
  1309.         ButtonInputBoxAdd = &Add
  1310.         ButtonInputBoxCancel = &Cancel
  1311.         ButtonInputBoxHelp = &Help
  1312.  
  1313.         CenterX := SquaresWide // 2, CenterY := SquaresHigh // 2, OffsetX := 0, OffsetY := 0, Cache := ">2" Cache, OptionInfo := SubStr(%A_ThisFunc%(A_Space), 2), WinDelay := A_WinDelay
  1314.         Loop, Parse, OptionInfo, `r
  1315.         {
  1316.             Loop, Parse, A_LoopField, `n
  1317.             {
  1318.                 StringSplit, @, A_LoopField, %A_Tab%
  1319.                 If (A_Index = 1)
  1320.                     Item := @1, @1 := "Main"
  1321.                 If (@2 <> "")
  1322.                     StringReplace, @, @1, %A_Space%, , All
  1323.                 OptionInfo_%Item%_%@% .= @2 = "" ? "`n`n" @1 : @2, @2 := ""
  1324.             }
  1325.             Menu, %A_ThisFunc%OptionInfo, Add, % Item A_Tab OptionInfo_%Item%_Main, %A_ThisFunc%Menu
  1326.         }
  1327.         OptionInfo := GuiTitle := "", LastPos := "x-300 y-300 w10 h10"
  1328.         Loop {
  1329.             If (FilePaths = "") {
  1330.                 StringReplace, ImageFile, ImageFile, >, , UseErrorLevel
  1331.                 AbsolutePath := (ErrorLevel - 1) * (ImageFile <> "")
  1332.                 SplitPath, ImageFile, , @1, @2, @3, @4
  1333.                 If (@2 <> "")
  1334.                     @2 := "." @2
  1335.                 Else If (DefaultExts <> "")
  1336.                     @2 := "." SubStr(DefaultExts, 1, InStr(DefaultExts, "|") - 1)
  1337.                 If (@3 = "")
  1338.                     @3 := NewFilePlaceHolder
  1339.                 FilePaths := "|" (@4 = "" ? "" : @1 "\" @3 @2 "|")
  1340.                 If !AbsolutePath or (@4 = "")
  1341.                     FilePaths .= RegExReplace(DefaultDirs, "\\?(\||$)", (@4 = "" ? "\" @1 : "") "\" @3 @2 "$1")
  1342.                 While InStr(FilePaths, "\\")
  1343.                     StringReplace, FilePaths, FilePaths, \\, \, All
  1344.                 StringReplace, FilePaths, FilePaths, |\, |\\, All
  1345.                 FilePaths := RegExReplace(FilePaths, "\\\K[^\\|]+\\\.\.\\") "|", Destination := SubStr(FilePaths, 2, InStr(FilePaths,  "|", 0, 2) - 2)
  1346.             }
  1347.             StringReplace, TempFilePaths, FilePaths, |%Destination%|, |, All
  1348.             GuiCommand := A_Index <> 1 or StartPaused ? ButtonPause : ButtonUnpause
  1349.             , LastItem := 1
  1350.             , VarSetCapacity(GuiHWND, 18000)
  1351.             , GuiHWND := GuiA . ";+AlwaysOnTop +Label" A_ThisFunc . ";Add,Progress,-0x20000 " LastPos " c" SelectionColor ",100;"
  1352.             While (SquaresHigh >= @ := A_Index)
  1353.                 Loop % SquaresWide
  1354.                     GuiHWND .= "Add,Progress,-0x20000 c" Color_%A_Index%_%@% " x" Margins + (SquareSize + SquareSpacing) * (A_Index - 1) " y" Margins + (SquareSize + SquareSpacing) * (@ - 1) " w" SquareSize + 1 " h" SquareSize + 1 ",100;"
  1355.             GuiHWND .= "Font,s" FontSize "," FontFace . ";Add,Text,x" Margins " y+" Margins + 4 " w" (@ := Ceil(((SquareSize + SquareSpacing) * SquaresWide - SquareSpacing - Margins * 4) / 5)) " h" ControlHeight ",Dimensions" . ";Add,Edit,+ReadOnly x+" Margins " yp-4 w" @ " hp," SquaresWide "x" SquaresHigh . ";Add,Text,x+" Margins " yp+4 w" @ " hp,Color (" (UseRGB ? "RGB" : "BGR") ")" . ";Add,Edit,+ReadOnly x+" Margins " yp-4 w" @ " hp," CurrentColor . ";Add,Text,x" Margins " y+" Margins + 4 " w" @ " hp,Mouse Pos" . ";Add,Edit,+ReadOnly x+" Margins " yp-4 w" @ " hp" . ";Add,CheckBox," (AllowOffset ? "Checked " : "") "x+" Margins " yp w" @ * 2 + Margins " hp," CheckboxOffset " (+0 +0)" . ";Add,Button,+Center g" A_ThisFunc "Close x" Margins * 5 + @ * 4 " yp-" Margins + ControlHeight " w" @ " h" ControlHeight * 2 + Margins "," ButtonPause . ";Add,GroupBox,x" Margins " y+" Margins " w" (SquareSize + SquareSpacing) * SquaresWide - SquareSpacing " h" ControlHeight * 2 + Margins * 4 "," A_ThisFunc " Options" . ";Add,Edit,xp+" Margins " yp+" Margins * 2 " w" (@ := Ceil(((SquareSize + SquareSpacing) * SquaresWide - SquareSpacing - Margins * 5) / 4)) * 3 + Margins * 2 " h" ControlHeight "," Options . ";Add,Button,g" A_ThisFunc "Close xp y+" Margins " w" @ " hp HwndGuiTitle," ButtonAddOption
  1356.             GuiHWND := %A_ThisFunc%(">NewGui<", GuiHWND . ";Add,Checkbox," (DiagnosticMode ? "+Checked " : "") "g" A_ThisFunc "Close x+" Margins " yp hp," CheckboxDiagnosticMode . ";Add,Edit," (DiagnosticMode ? "" : "+ReadOnly ") "x+" Margins " yp w" @ / 2 " hp," DiagnosticModeOptions . ";Add,Button,g" A_ThisFunc "Close x" Margins * 5 + @ * 3 " yp-" ControlHeight + Margins " w" @ " h" ControlHeight * 2 + Margins "," ButtonTest . ";Add,GroupBox,x" Margins " y+" Margins * 2 " w" (SquareSize + SquareSpacing) * SquaresWide - SquareSpacing " h" ControlHeight * 2 + Margins * 4 ",Output File" . ";Add," (AbsolutePath ? "DropDownList" : "ComboBox") ",g" A_ThisFunc "Close vErrorLevel +AltSubmit xp+" Margins " yp+" Margins * 2 " w" @ * 4 + Margins * 3 - (AbsolutePath ? 0 : Margins + ControlHeight) "," Destination "|" SubStr(TempFilePaths, 1, -1) . (AbsolutePath ? "" : ";Add,Button,g" A_ThisFunc "Close x+" Margins " yp w" ControlHeight " hp," ButtonJumpToFileName) . ";Add,Checkbox," (CopyToClipboard ? "+Checked " : "") "x" Margins * 2 " y+" Margins " hp," CheckboxCopyToClipboard . ";Add,Button,g" A_ThisFunc "Close xp+" @ * 2 + Margins * 2 " yp w" @ " hp" (AbsolutePath > 1 ? " +Disabled" : "") "," (AbsolutePath ? ButtonOther : ButtonBrowse) . ";Add,Button,+Default g" A_ThisFunc "Close x+" Margins " yp w" @ " hp," ButtonSave . ";Show,Hide w" (SquareSize + SquareSpacing) * SquaresWide - SquareSpacing + Margins * 2 " y" (GuiY = "" ? (A_ScreenHeight - Margins * 16 - ControlHeight * 4 - (SquareSize + SquareSpacing) * SquaresHigh + SquareSpacing) // 2 : GuiY " x" GuiX) "," A_ThisFunc " Screenshot Creator"), OptionsHWND := GuiTitle, GuiTitle := A_ThisFunc " Screenshot Creator:"
  1357.             Hotkey, IfWinExist, ahk_id %GuiHWND%
  1358.             Hotkey, ~LButton, %A_ThisFunc%Close, On
  1359.             Hotkey, %PauseHotkey%, %A_ThisFunc%Close, On
  1360.             Hotkey, IfWinExist
  1361.             Loop {
  1362.                 TempGuiCommand := GuiCommand, GuiCommand := ""
  1363.                 If (TempGuiCommand = "ErrorLevel") {
  1364.                     GuiControlGet, @, %GuiA%:FocusV
  1365.                     If (@ = "ErrorLevel") {
  1366.                         ControlGetText, Destination, ComboBox1, ahk_id %GuiHWND%
  1367.                         If AutoJumpToFileName and !AbsolutePath {
  1368.                             GuiControlGet, ThisItem, %GuiA%:, ErrorLevel
  1369.                             If (ThisItem < 100) and (ThisItem <> LastItem)
  1370.                                 GuiCommand := ButtonJumpToFileName, LastItem := ThisItem
  1371.                         }
  1372.                     } Else
  1373.                         GuiControl, %GuiA%:Focus, ErrorLevel
  1374.                 } Else If (TempGuiCommand = PauseHotkey) or (TempGuiCommand = ButtonUnpause) or (TempGuiCommand = ButtonPause) {
  1375.                     If (TempGuiCommand <> ButtonPause) {
  1376.                         Gui, %GuiA%:Show, % "NA h" Margins * 4 + 1 + ControlHeight * 2 + (SquareSize + SquareSpacing) * SquaresHigh - SquareSpacing
  1377.                         ControlSetText, Button2, %ButtonPause%, ahk_id %GuiHWND%
  1378.                         GuiControl, %GuiA%:, Edit2
  1379.                         WinSet, AlwaysOnTop, On, ahk_id %GuiHWND%
  1380.                         If (A_Index <> 1) {
  1381.                             ControlGet, AllowOffset, Checked, , Button1, ahk_id %GuiHWND%
  1382.                             If AllowOffset and (MouseX <> "") {
  1383.                                 MouseGetPos, MouseX2, MouseY2
  1384.                                 OffsetX := MouseX2 - MouseX, OffsetY := MouseY2 - MouseY
  1385.                             } Else
  1386.                                 OffsetX := 0, OffsetY := 0
  1387.                             ControlSetText, Button1, % CheckboxOffset " (" (OffsetX < 0 ? "+" : "") 0 - OffsetX ", " (OffsetY < 0 ? "+" : "") 0 - OffsetY ")", ahk_id %GuiHWND%
  1388.                         }
  1389.                         If !WinExist("ahk_id " BoxHWND)
  1390.                             BoxHWND := %A_ThisFunc%(">NewGui<", GuiB . ";Color," CurRegionColor . ";+ToolWindow -SysMenu -Caption +AlwaysOnTop +E0x20" . ";Show,NA x-100 y-100 w" SquaresWide + CurRegionThickness * 2 " h" SquaresHigh + CurRegionThickness * 2 . ";Trans,200" . ";Region,0-0 " SquaresWide + CurRegionThickness * 2 "-0 " SquaresWide + CurRegionThickness * 2 "-" SquaresHigh + CurRegionThickness * 2 " 0-" SquaresHigh + CurRegionThickness * 2 " 0-0 " CurRegionThickness "-" CurRegionThickness " " CurRegionThickness + SquaresWide "-" CurRegionThickness " " CurRegionThickness + SquaresWide "-" CurRegionThickness + SquaresHigh " " CurRegionThickness "-" CurRegionThickness + SquaresHigh " " CurRegionThickness "-" CurRegionThickness)
  1391.  
  1392.                         If A_PtrSize
  1393.                             Ptr := "UPtr", PtrA := "UPtr*"
  1394.                         Else
  1395.                             Ptr := "UInt", PtrA := "UInt*"
  1396.                         If !DllCall("GetModuleHandle", "str", "gdiplus", Ptr)
  1397.                             DllCall("LoadLibrary", "str", "gdiplus")
  1398.                         VarSetCapacity(si, A_PtrSize = 8 ? 24 : 16, 0), si := Chr(1), DllCall("gdiplus\GdiplusStartup", PtrA, pToken, Ptr, &si, Ptr, 0)
  1399.  
  1400.                         GuiCommand := "~LButton"
  1401.                         While (GuiCommand = "~LButton") {
  1402.                             MouseGetPos, MouseX, MouseY
  1403.                             MouseX -= OffsetX, MouseY -= OffsetY
  1404.                             Gui, %GuiB%:Show, % "NA x" MouseX - CenterX - CurRegionThickness " y" MouseY - CenterY - CurRegionThickness
  1405.  
  1406.                             chdc := DllCall("CreateCompatibleDC", Ptr, False), hdc2 := chdc ? chdc : DllCall("GetDC", Ptr, False), VarSetCapacity(bi, 40, 0), NumPut(SquaresWide, bi, 4, "uint"), NumPut(SquaresHigh, bi, 8, "uint"), NumPut(40, bi, 0, "uint"), NumPut(1, bi, 12, "ushort"), NumPut(0, bi, 16, "uInt"), NumPut(32, bi, 14, "ushort"), hbm := DllCall("CreateDIBSection", Ptr, hdc2, Ptr, &bi, "uint", 0, PtrA, False, Ptr, 0, "uint", 0, Ptr)
  1407.                             If !chdc
  1408.                                 DllCall("ReleaseDC", Ptr, False, Ptr, hdc2)
  1409.                             obm := DllCall("SelectObject", Ptr, chdc, Ptr, hbm), hhdc := DllCall("GetDC", Ptr, False), DllCall("gdi32\BitBlt", Ptr, chdc, "int", 0, "int", 0, "int", SquaresWide, "int", SquaresHigh, Ptr, hhdc, "int", MouseX - CenterX, "int", MouseY - CenterY, "uint", 0x00CC0020), DllCall("ReleaseDC", Ptr, False, Ptr, hhdc), DllCall("gdiplus\GdipCreateBitmapFromHBITMAP", Ptr, hbm, Ptr, False, PtrA, pBitmap), DllCall("SelectObject", Ptr, chdc, Ptr, obm), DllCall("DeleteObject", Ptr, hbm), DllCall("DeleteDC", Ptr, hhdc), DllCall("DeleteDC", Ptr, chdc)
  1410.  
  1411.                             While (SquaresHigh >= @ := A_Index)
  1412.                                 Loop %SquaresWide% {
  1413.                                     SetFormat, Integer, Hex
  1414.                                     DllCall("gdiplus\GdipBitmapGetPixel", Ptr, pBitmap, "int", CenterX + A_Index - Floor(SquaresWide / 2) - 1, "int", CenterY + @ - Floor(SquaresHigh / 2) - 1, "uint*", Color), Color := Color & 0x00ffffff
  1415.                                     SetFormat, Integer, Decimal
  1416.                                     GuiControl, % GuiA ":+c" SubStr(Color_%A_Index%_%@% := Color, 3), % "msctls_progress32" 1 + (@ - 1) * SquaresWide + A_Index
  1417.                                 }
  1418.                             ControlSetText, Edit3, %MouseX% `, %MouseY%, ahk_id %GuiHWND%
  1419.  
  1420.                             DllCall("gdiplus\GdipDisposeImage", Ptr, pBitmap)
  1421.  
  1422.                         }
  1423.                         WinSet, AlwaysOnTop, Off, ahk_id %GuiHWND%
  1424.                         MouseGetPos, OffsetX, OffsetY
  1425.                         OffsetX -= MouseX, OffsetY -= MouseY
  1426.  
  1427.                         DllCall("gdiplus\GdiplusShutdown", Ptr, pToken)
  1428.                         If (hModule := DllCall("GetModuleHandle", "str", "gdiplus", Ptr))
  1429.                             DllCall("FreeLibrary", Ptr, hModule)
  1430.                     }
  1431.  
  1432.                     Gui, %GuiA%:Show, % "h" Margins * 16 + 1 + ControlHeight * 5 + (SquareSize + SquareSpacing) * SquaresHigh - SquareSpacing
  1433.                     ControlSetText, Button2, %ButtonUnpause%, ahk_id %GuiHWND%
  1434.                     GuiCommand := GuiCommand = "Normal" ? "Normal" : !AbsolutePath and AutoJumpToFileName ? ButtonJumpToFileName : "ErrorLevel"
  1435.                 } Else If (TempGuiCommand = ButtonAddOption) {
  1436.                     WinGetPos, @1, @2, , @3, ahk_id %OptionsHWND%
  1437.                     Menu, %A_ThisFunc%OptionInfo, Show, % @1 + 1, % @2 + @3 - 1
  1438.                 } Else If (TempGuiCommand = ButtonJumpToFileName) {
  1439.                     SplitPath, Destination, , @1, , @2
  1440.                     ControlFocus, ComboBox1, ahk_id %GuiHWND%
  1441.                     SendMessage, 0xB1, StrLen(@1) + 1, StrLen(@1 @2) + 1, Edit6, ahk_id %GuiHWND%
  1442.                 } Else If (TempGuiCommand = ButtonBrowse) {
  1443.                     ControlGetText, FilePaths, ComboBox1, ahk_id %GuiHWND%
  1444.                     Gui, %GuiA%:+OwnDialogs
  1445.                     FileSelectFile, Destination, , %FilePaths%, , % "Screenshot Files (" SubStr(RegExReplace(DefaultExts, "(?:\||^)\.?(\w+)", "*.$1;"), 1, -1) ")"
  1446.                     If !ErrorLevel
  1447.                         ControlSetText, Edit6, % Destination .= InStr(Destination, ".", 0, InStr("\" Destination, "\", 0, 0)) ? "" : SubStr(DefaultExts, 1, InStr(DefaultExts, "|") - 1), ahk_id %GuiHWND%
  1448.                     Gui, %GuiA%:-OwnDialogs
  1449.                     GuiCommand := AutoJumpToFileName ? ButtonJumpToFileName : "ErrorLevel"
  1450.                 } Else If (TempGuiCommand = ButtonOther) {
  1451.                     WinGetPos, GuiX, GuiY, , , ahk_id %GuiHWND%
  1452.                     ImageFile := ">" ImageFile, GuiHWND := FilePaths := ""
  1453.                     Break
  1454.                 } Else If (TempGuiCommand = CheckboxDiagnosticMode) {
  1455.                     ControlGet, DiagnosticMode, Checked, , Button5, ahk_id %GuiHWND%
  1456.                     GuiControl, % GuiA ":" (DiagnosticMode ? "-" : "+") "ReadOnly", Edit5
  1457.                 } Else If (TempGuiCommand = A_ThisFunc "OptionInfo") {
  1458.                     @ := SubStr(A_ThisMenuItem, 1, InStr(A_ThisMenuItem, A_Tab) - 1)
  1459.                     Gui, %GuiA%:+Disabled
  1460.                     WinWaitClose, % "ahk_id " %A_ThisFunc%(">NewGui<", GuiB . ";+Label" A_ThisFunc " +Owner" GuiA . ";Add,Text,x" Margins " y" Margins " w" InputBoxWidth "," OptionInfo_%@%_Description "`n`nDefault:`t`t" OptionInfo_%@%_Default "`nUser Default:`t" OptionInfo_%@%_UserDefault . ";Add,Edit,xp y+" Margins " wp h" ControlHeight . ";Add,Button,g" A_ThisFunc "Close xp y+" Margins " w" (InputBoxWidth - Margins * 2) // 3 " hp," ButtonInputBoxHelp . ";Add,Button,g" A_ThisFunc "Close x+" Margins " yp wp hp," ButtonInputBoxCancel . ";Add,Button,g" A_ThisFunc "Close x+" Margins " yp wp hp +Default," ButtonInputBoxAdd . ";Show,w" InputBoxWidth + Margins * 2 ",Add Option: " @ " - " OptionInfo_%@%_Main)
  1461.                     Gui, %GuiA%:-Disabled
  1462.                     TempGuiCommand := GuiCommand, GuiCommand := ""
  1463.                     If (InStr(TempGuiCommand, ButtonInputBoxAdd) = 1) {
  1464.                         NewOption := SubStr(TempGuiCommand, InStr(TempGuiCommand, "`n") + 1)
  1465.                         If InStr(NewOption, A_Space) or InStr(NewOption, Literal) {
  1466.                             StringReplace, NewOption, NewOption, %Literal%, %Literal%%Literal%, All
  1467.                             NewOption := Literal NewOption Literal
  1468.                         }
  1469.                         ControlGetText, Options, Edit4, ahk_id %GuiHWND%
  1470.                         ControlSetText, Edit4, % (Options .= SubStr(A_Space Options, 0) = A_Space ? "" : A_Space) @ NewOption, ahk_id %GuiHWND%
  1471.                         ControlFocus, Edit4, ahk_id %GuiHWND%
  1472.                         SendMessage, 0xB1, @1 := StrLen(Options), @2 := @1 + StrLen(@ NewOption), Edit4, ahk_id %GuiHWND%
  1473.                         Sleep 200
  1474.                         SendMessage, 0xB1, @1 + StrLen(@), @2, Edit4, ahk_id %GuiHWND%
  1475.                     } Else If (InStr(TempGuiCommand, ButtonInputBoxHelp) = 1)
  1476.                         Run, %ForumURL%
  1477.  
  1478.                 } Else If InStr(TempGuiCommand, "LButton") {
  1479.                     MouseGetPos, , , MouseWin, MouseControl1
  1480.                     If (MouseWin = GuiHWND)
  1481.                         If (InStr(MouseControl1, "msctls_progress32") = 1) and (MouseControl1 <> "msctls_progress321") {
  1482.                             GuiControlGet, Con1, %GuiA%:Pos, %MouseControl1%
  1483.                             While (!DoubleTapToSelect and GetKeyState("LButton", "P")) or (DoubleTapToSelect and (GuiCommand = "")) {
  1484.                                 MouseGetPos, , , MouseWin, MouseControl
  1485.                                 If (MouseControl <> MouseControl2) and (InStr(MouseControl, "msctls_progress32") = 1) and (MouseControl <> "msctls_progress321") {
  1486.                                     GuiControlGet, Con2, %GuiA%:Pos, % MouseControl2 := MouseControl
  1487.                                     GuiControl, %GuiA%:MoveDraw, msctls_progress321, % LastPos := "x" (Con1X < Con2X ? Con1X : Con2X) - SquareSpacing - 1 " y" (Con1Y < Con2Y ? Con1Y : Con2Y) - SquareSpacing - 1 " w" Abs(Con2X - Con1X) + SquareSize + SquareSpacing * 2 + 3 " h" Abs(Con2Y - Con1Y) + SquareSize + SquareSpacing * 2 + 3
  1488.                                     GuiControl, %GuiA%:, Edit1, % Round((Abs(Con2X - Con1X) + SquareSize + SquareSpacing) / (SquareSize + SquareSpacing)) "x" Round((Abs(Con2Y - Con1Y) + SquareSize + SquareSpacing) / (SquareSize + SquareSpacing))
  1489.                                     @1 := Round((Con2X + SquareSize - Margins + SquareSpacing) / (SquareSize + SquareSpacing)), @2 := Round((Con2Y + SquareSize - Margins + SquareSpacing) / (SquareSize + SquareSpacing))
  1490.                                     GuiControl, %GuiA%:, Edit2, % CurrentColor := UseRGB ? Color_%@1%_%@2% : "0x" SubStr(Color_%@1%_%@2%, 7) SubStr(Color_%@1%_%@2%, 5, 2) SubStr(Color_%@1%_%@2%, 3, 2)
  1491.                                 }
  1492.                                 Sleep 10
  1493.                             }
  1494.                             Con1Y := Ceil((SubStr(MouseControl1, 18) - 1) / SquaresWide), Con1X := SubStr(MouseControl1, 18) - 1 - SquaresWide * (Con1Y - 1), Con2Y := Ceil((SubStr(MouseControl2, 18) - 1) / SquaresWide), Con2X := SubStr(MouseControl2, 18) - 1 - SquaresWide * (Con2Y - 1), X1 := Con1X < Con2X ? Con1X : Con2X, Y1 := Con1Y < Con2Y ? Con1Y : Con2Y, X2 := Con1X > Con2X ? Con1X : Con2X, Y2 := Con1Y > Con2Y ? Con1Y : Con2Y, GuiCommand := ""
  1495.                         } Else If (MouseControl1 = "") or (MouseControl1 = "Button3") or (MouseControl1 = "Button7") or (InStr(MouseControl1, "Static") = 1) {
  1496.                             WinGetPos, WinX, WinY, , , ahk_id %GuiHWND%
  1497.                             MouseGetPos, MouseX1, MouseY1
  1498.                             While GetKeyState("LButton", "P") {
  1499.                                 MouseGetPos, MouseX2, MouseY2
  1500.                                 WinMove, ahk_id %GuiHWND%, , WinX + MouseX2 - MouseX1, WinY + MouseY2 - MouseY1
  1501.                             }
  1502.                         }
  1503.                 } Else {
  1504.                     If (TempGuiCommand = ButtonSave) or (TempGuiCommand = ButtonTest) {
  1505.                         Gui, %GuiA%:+OwnDialogs
  1506.                         If (TempGuiCommand = ButtonTest) {
  1507.                             OutputFile := TempFile
  1508.                             ControlGet, DiagnosticMode, Checked, , Button5, ahk_id %GuiHWND%
  1509.                             ControlGetText, DiagnosticModeOptions, Edit5, ahk_id %GuiHWND%
  1510.                             WinGetPos, GuiX, GuiY, , , ahk_id %GuiHWND%
  1511.                         } Else
  1512.                             OutputFile := Destination
  1513.                         SplitPath, OutputFile, , , Extension, Name
  1514.                         If (Extension <> "")
  1515.                             StringTrimRight, OutputFile, OutputFile, StrLen(Extension) + 1
  1516.                         If Extension Not In bmp,dib,rle,jpg,jpeg,jpe,jfif,gif,tif,tiff,png
  1517.                         {
  1518.                             MsgBox, 262148, %A_ScriptName%: Input Required, % "You have chosen the following file extension:`n`n" Extension "`n`nThis is not a valid screenshot filetype.`n`nPress YES to use the .png (the recommended filetype for screenshot files.)`n`nPress NO to enter a different file extension. Supported filetypes are bmp, dib, rle, jpg, jpeg, jpe, jfif, gif, tif, tiff, and png." (TempGuiCommand = ButtonTest ? "`n`nTo fix this problem while testing, replace the %TempFile% path declaration in the function code." : "")
  1519.                             IfMsgBox YES
  1520.                                 Extension := "png"
  1521.                             Else
  1522.                                 GuiCommand := "ErrorLevel"
  1523.                         }
  1524.                         If (TempGuiCommand = ButtonSave) {
  1525.                             If InStr(@ := FileExist(OutputFile "." Extension), "D") {
  1526.                                 MsgBox, 262160, %A_ScriptName%: Error, Please enter a file name.
  1527.                                 GuiCommand := "ErrorLevel"
  1528.                             } Else If (@ <> "") {
  1529.                                 If PromptOnOverWrite {
  1530.                                     MsgBox, 262148, %A_ScriptName%: Input Required, File "%OutputFile%.%Extension%" already exists. Overwrite it?
  1531.                                     IfMsgBox No
  1532.                                         GuiCommand := "ErrorLevel"
  1533.                                 }
  1534.                                 If (GuiCommand <> "ErrorLevel")
  1535.                                     If RecycleOnOverWrite
  1536.                                         FileRecycle, %OutputFile%.%Extension%
  1537.                                     Else
  1538.                                         FileDelete, %OutputFile%.%Extension%
  1539.                             }
  1540.                         } Else If (TempGuiCommand = ButtonTest)
  1541.                             FileDelete, %OutputFile%.%Extension%
  1542.                         ControlGetText, Options, Edit4, ahk_id %GuiHWND%
  1543.                         ControlGet, CopyToClipboard, Checked, , Button9, ahk_id %GuiHWND%
  1544.                     }
  1545.                     If (GuiCommand <> "ErrorLevel") {
  1546.                         Gui, %GuiA%:Destroy
  1547.                         Gui, %GuiB%:Destroy
  1548.                         Hotkey, IfWinExist, ahk_id %GuiHWND%
  1549.                         Hotkey, ~LButton, Off
  1550.                         Hotkey, %PauseHotkey%, Off
  1551.                         Hotkey, IfWinExist
  1552.                         SetWinDelay, %WinDelay%
  1553.                     } Else
  1554.                         Gui, %GuiA%:-OwnDialogs
  1555.                     If (TempGuiCommand = ButtonSave) or (TempGuiCommand = ButtonTest) {
  1556.                         If (X1 = "")
  1557.                             X1 := 1, Y1 := 1, X2 := SquaresWide, Y2 := SquaresHigh
  1558.                         VarSetCapacity(Colors, (X2 - X1 + 1) * (Y2 - Y1 + 1) * 7)
  1559.                         While (Y2 >= IndexY := A_Index + Y1 - 1)
  1560.                             While (X2 >= IndexX := A_Index + X1 - 1)
  1561.                                 Colors .= "|" SubStr(Color_%IndexX%_%IndexY%, 3)
  1562.                         %A_ThisFunc%(">MakeImage<", OutputFile "|" Extension "|" X2 - X1 + 1 "|" Y2 - Y1 + 1 Colors)
  1563.                     }
  1564.                     If (TempGuiCommand = ButtonTest) {
  1565.                         %A_ThisFunc%(OutputFile "." Extension, Options (DiagnosticMode ? (SubStr(A_Space Options, 0) = A_Space ? "" : A_Space) "dx" DiagnosticModeOptions : ""))
  1566.                         FileDelete, %OutputFile%.%Extension%
  1567.                         %A_ThisFunc%(">ParseCache<", OutputFile "." Extension), LastImageFile := ""
  1568.                         Break
  1569.                     } Else If (GuiCommand <> "ErrorLevel") {
  1570.                         GuiHWND := ""
  1571.                         If (TempGuiCommand = ButtonSave) {
  1572.                             FileCreateDir, % SubStr(OutputFile, 1, InStr(OutputFile, "\", 0, 0))
  1573.                             Cache := Name A_Tab OutputFile "." Extension A_Tab X2 - X1 + 1 "|" Y2 - Y1 + 1 "||`n" Cache, FoundX := OutputFile "." Extension, FoundY := Options
  1574.                             If CopyToClipboard {
  1575.                                 DefaultDirs := SubStr(RegExReplace(DefaultDirs "|", "\\*(?:\||^)+", "\|"), 3, -1), DefaultExts := SubStr(RegExReplace("|" DefaultExts "|", "\|\.*", "|."), 2, -2), OutputFile := "|" OutputFile "|"
  1576.                                 Loop, Parse, DefaultDirs, |
  1577.                                     StringReplace, OutputFile, OutputFile, |%A_LoopField%
  1578.                                 Loop, Parse, DefaultExts, |
  1579.                                     StringReplace, OutputFile, OutputFile, %A_LoopField%|
  1580.                                 StringReplace, OutputFile, OutputFile, |, , All
  1581.                                 StringReplace, Options, Options, ", "", All
  1582.                                 Clipboard := A_ThisFunc "(""" OutputFile """" (Options = "" ? "" : ", """ Options """") ")"
  1583.                             }
  1584.                             Return True
  1585.                         }
  1586.                         Return False
  1587.                     }
  1588.                 }
  1589.                 If (GuiCommand = "") {
  1590.                     WinSetTitle, ahk_id %GuiHWND%, , % GuiTitle := A_ThisFunc " Screenshot Creator: Paused"
  1591.                     WinWaitClose, %GuiTitle% ahk_id %GuiHWND%
  1592.                 }
  1593.             }
  1594.         }
  1595.     } Else
  1596.         MsgBox, 262160, %A_ScriptName% - %A_ThisFunc%(): Error, The image creator is already running.`n`nPlease finish the current task before continuing.
  1597.     Return
  1598.     FindClickMenu:
  1599.     FindClickClose:
  1600.     FindClickEscape:
  1601.     Return FindClick(">GuiEvent<")
  1602. }
  1603. ; #Include FindClick.ahk
  1604.  
  1605. randstart = 0
  1606. UserConfig_a = o20,TransBlack
  1607. playing = 0
  1608. process,close,HearthRanger.exe
  1609. process,close,Silver.exe
  1610. process,close,Hearthstone.exe
  1611. process,close,Battle.net.exe
  1612. random,randstart,0,360
  1613. sleep randstart
  1614. started = 0
  1615. Run "%A_WorkingDir%/Ranger Recovery/Battle.net.lnk"
  1616.  
  1617.  
  1618.     ;Launch the game
  1619.     FindClick("/Ranger Recovery/play.png","!a w")
  1620.         sleep 500
  1621.     FindClick("/Ranger Recovery/play.png","!a")
  1622.  
  1623. Run "%A_WorkingDir%/ExternBot/silverfish/Silver.exe"
  1624.     Sleep 5000
  1625. Run "HearthRanger.exe"
  1626.     ;   sleep 10000
  1627.     ;FindClick("/Ranger Recovery/update.png","o20 stay1 funcUpdate")
  1628.         Sleep 10000
  1629.     FindClick("/Ranger Recovery/startbot.png","o20 stay1 funcStartbot w")
  1630.         mousemove,0,0
  1631. loop
  1632. {
  1633.     StayOnTop()     ;don't work when game crash !!
  1634.         sleep 10000
  1635.     FindClick("/Ranger Recovery/blueHR.png","funcRestart !a")
  1636.     FindClick("/Ranger Recovery/blueHR.png","funcBotstopped !a")
  1637. }
  1638.  
  1639. Update()
  1640. {
  1641.     FindClick("/Ranger Recovery/update.png","!a w5000,2000")
  1642. }
  1643.  
  1644. Startbot()
  1645. {
  1646.         global
  1647.         loop
  1648. {
  1649.     process,close,Battle.net.exe  ;don't work
  1650.     FindClick("/Ranger Recovery/started.png","!a funcStarted")
  1651.     FindClick("/Ranger Recovery/startbot.png","o20 stay1")
  1652.         if started = 1
  1653. {
  1654.         break
  1655. }
  1656. }
  1657. }
  1658.  
  1659. Botstopped()
  1660. {
  1661.     FindClick("/Ranger Recovery/botfinished0.png","!a funcClosedown")
  1662.         sleep 500
  1663.     FindClick("/Ranger Recovery/botstopped.png","!a funcRestart")
  1664. }
  1665.  
  1666. Closedown()
  1667. {
  1668. process,close,HearthRanger.exe
  1669. process,close,Silver.exe
  1670. process,close,Hearthstone.exe
  1671. process,close,Battle.net.exe
  1672. exitapp
  1673. }
  1674.  
  1675. Restart()
  1676. {
  1677. process,close,HearthRanger.exe
  1678. process,close,Silver.exe
  1679. process,close,Hearthstone.exe
  1680. process,close,Battle.net.exe
  1681. reload
  1682. }
  1683.  
  1684.  
  1685. Started()
  1686. {
  1687. global
  1688. Started = 1
  1689. }
  1690.  
  1691. StayOnTop()
  1692. {
  1693.     FindClick("/Ranger Recovery/ontopf.png","!a")
  1694. }
  1695.  
  1696. ; Don't used
  1697. Playgame()
  1698. {
  1699.         global
  1700.     FindClick("/Ranger Recovery/play.png","!a")
  1701.     playing = 1
  1702. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement