· 6 years ago · Nov 26, 2019, 07:34 PM
1FindClick(ImageFile="", Options="", ByRef FoundX="", ByRef FoundY="") ; updated February 17, 2017 ... https://autohotkey.com/boards/viewtopic.php?f=6&t=18719
2{
3 Static Cache
4 , Center, Silent, Delim, Count, CharX, CharY, CharN, Sleep, Stay, Func, dx, d, m, x, y, o, n, k, r, e, a, w, t, f
5 , ImageW, ImageH, LastX1, LastY1, ImageFilePath ; (xxx Does LastX/Y use the static ability?)
6 , LastOptions, LastImageFile, MonitorInfo, DxInfo
7 , GuiHWND, GuiCommand, GuiTitle
8 , Error, Message, Buttons, # := "`t", $ := "`r"
9 GlobalSettingsLocation = %A_LineNumber%
10 ;||||||||||||||||||||||||||||||||||| Misc. Global Script Settings |||||||||||||||||||||||||||||||||||
11 ;----------------------------------------------------------------------------------------------------
12 DefaultDirs = %A_Desktop%|%A_ScriptDir%|%A_Temp% ; Pipe (|) delimited list of default directories to search if file not found in working directory
13 DefaultExts = png|bmp ; Pipe (|) delimited list of file extensions to try appending to %ImageFile% if it is still not found in %DefaultDirs%
14 GuiA = 97 ; Gui numbers to use for gui elements
15 GuiB = 98 ; (Two guis are needed)
16 Literal := """" ; Character that is used to surround a string with spaces in the options parameter
17 UseRGB = %False% ; All colors will be RGB if true and BGR if false. (BGR is what is used by window spy).
18 ForumURL = https://autohotkey.com/boards/viewtopic.php?f=6&t=18719 ; Url of forum
19 LastUpdate = February 17, 2017 ; Date of last update
20 ;||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
21 If (ImageFile <> "") and (Asc(ImageFile) <> 62) {
22 If (LastImageFile <> ImageFile) or (Options <> LastOptions) {
23 If (Asc(Cache) = 62)
24 SpecialLaunch := SubStr(Cache, 2, 1), Cache := SubStr(Cache, 3)
25 If (LastImageFile <> "")
26 Cache := LastImageFile A_Tab ImageFilePath A_Tab ImageW "|" ImageH "|" LastX1 "|" LastY1 "`n" Cache, LastImageFile := ""
27 If (SpecialLaunch <> 3) {
28 DefaultOptionsLocation := A_LineNumber
29 ;||||||||||||||||||||||||||||||||||||||||| Default Options ||||||||||||||||||||||||||||||||||||||||||
30 ; Each letter or letters is a flag that corresponds to one of the settings of the function. By default, each setting takes the value assigned in the first column below. You may change settings by including that flag in the Options parameter of the function. In this case the passed option will take the value assigned in the 2nd column below. Indicate any other value with a string immediately following the corresponding flag. Separate each flag and string pairing with a space.
31 ;----------------------------------------------------------------------------------------------------
32 ; DEFAULT USER DEFAULT NAME OF OPTION
33 , o := "", o_user := "*15" ; ImageSearch Options
34 , a := "", a_user := "m100" ; Search Area Modifications
35 , r := "", r_user := "A" ; Relative to Window Coords
36 , x := 0, x_user := "Abs" ; X Offset
37 , y := 0, y_user := "Abs" ; Y Offset
38 , n := 1, n_user := 0 ; Number of Clicks (No Click)
39 , e := "", e_user := 0.85 ; Find Every Image
40 , w := "", w_user := "0,100" ; Wait Until Image Is Found
41 , dx := "", dx_user := "StartAt=#" ; Diagnostic Mode
42 , k := "{Click}", k_user := "{RButton}" ; Keystroke(s)
43 , Stay := False, Stay_user := True ; Do Not Restore Mouse
44 , Count := False, Count_user := True ; Return Found Count
45 , d := "", d_user := "MousePos" ; Direction of Search
46 , m := "Input", m_user := "ControlClick" ; SendMode
47 , Sleep := 20, Sleep_user := 0 ; Sleep Between Clicks
48 , t := "", t_user := "10%" ; Image Tracking
49 , Silent := False, Silent_user := True ; No Dialogs
50 , Center := True, Center_user := False ; Start at Center of Image
51 , Delim := "`n", Delim_user := A_Tab ; Delimiter for Multiple Images
52 , f := "x,y", f_user := "x y n" ; Format of Output String
53 , Func := "", Func_user := "" ; Function Callout
54 , CharX := "x", CharX_user := "x" ; Character Spaceholder for X-Coord
55 , CharY := "y", CharY_user := "y" ; Character Spaceholder for Y-Coord
56 , CharN := "n", CharN_user := "n" ; Character Spaceholder for Image Instance Number
57 ;----------------------------------------------------------------------------------------------------
58 ; Change or add user configuration variables as you see fit. Call these with !, e.g. !foo
59 UserConfig_foo = r"Test Window" mControlClick
60 UserConfig_log = dx"SaveTo=%A_Desktop%\FindClickDebug.txt"
61 ;||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
62 }
63 @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"
64 If SpecialLaunch and (SpecialLaunch <> 4) {
65 ;|||||||||||||||||||||||||||||||||||||| Description of Options ||||||||||||||||||||||||||||||||||||||
66 ;----------------------------------------------------------------------------------------------------
67 OptionInfo =
68 (
69 m SendMode for keystrokes
70 What to give [Event|Play|Input|Default|ControlClick|First letter of any of these words]
71 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.
72 --------------------------------------------------------------------------------
73 x X Offset
74 What to give An integer
75 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.
76 --------------------------------------------------------------------------------
77 y Y Offset
78 What to give An integer
79 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.
80 --------------------------------------------------------------------------------
81 f Format of output string
82 What to give Template string that includes the CharX and/or CharY and/or CharN characters.
83 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.
84 --------------------------------------------------------------------------------
85 Delim Delimiter for multiple images
86 What to give Any character or characters
87 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.
88 --------------------------------------------------------------------------------
89 Stay Do not restore mouse
90 What to give True or False (1 or 0)
91 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.
92 --------------------------------------------------------------------------------
93 o ImageSearch Options
94 What to give Comma-delimited string of imagesearch options.
95 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.
96 --------------------------------------------------------------------------------
97 n Number of clicks
98 What to give Any number
99 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.
100 --------------------------------------------------------------------------------
101 Sleep Sleep milliseconds
102 What to give Any number of milliseconds
103 Description Number of milliseconds to sleep between each click if n > 1 or e and multiple images found.
104 --------------------------------------------------------------------------------
105 k Keystroke(s)
106 What to give Key to send (in the same format as the AutoHotkey Send command)
107 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.
108 --------------------------------------------------------------------------------
109 r Relative to Window Coords
110 What to give Window Title criteria, or a window HWND
111 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.
112 --------------------------------------------------------------------------------
113 e Find Every Image
114 What to give Positive fraction between 0 and 1
115 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.)
116 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.
117 --------------------------------------------------------------------------------
118 a Search Area Modifications
119 What to give x[,y,w,h] OR mn
120 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.
121 --------------------------------------------------------------------------------
122 w Wait until image is found
123 What to give Number of milliseconds [, Number of milliseconds]
124 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.
125 --------------------------------------------------------------------------------
126 t Image Tracking
127 What to give A percent OR a number of pixels
128 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.
129 --------------------------------------------------------------------------------
130 Silent No Dialogs
131 What to give True or False
132 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.
133 --------------------------------------------------------------------------------
134 Count Return found count
135 What to give True or False
136 Description If Count is true then the function will return the number of items found instead of their coordinates. e is assumed if absent.
137 --------------------------------------------------------------------------------
138 dx Diagnostic Mode
139 What to give Comma delimited list of diagnostic mode options (see below)
140 Description Will illustrate where clicks take place with an on-screen display. Currently the comma-separated options aren't really working, sorry about that!
141 --------------------------------------------------------------------------------
142 Center Start at center of image
143 What to give True or False (1 or 0)
144 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.
145 --------------------------------------------------------------------------------
146 Func Function Callout
147 What to give The name of a function in the script
148 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.
149 --------------------------------------------------------------------------------
150 d Direction Of Search
151 What to give Left|Right|Bottom
152 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.
153 )
154 ;||||||||||||||||||||||||||||||||||||||||||| End Settings |||||||||||||||||||||||||||||||||||||||||||
155 OptionInfo := RegExReplace(OptionInfo, "(?:`n|^)\K\s+"), OptionInfo := "`r" RegExReplace(OptionInfo, "\s*-{5,}\s*", "`r"), OptionInfo := RegExReplace(OptionInfo, "[ \t]{3,}|\t+", "`t")
156 If (SpecialLaunch <> 3)
157 Loop, Parse, Commands, |
158 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)))
159 If SpecialLaunch in 2,3
160 Return OptionInfo
161 DllCall("QueryPerformanceCounter", "Int64*", QPC)
162 , TempCommands := Commands, VarSetCapacity(DxInfo, 2500) ; xxx update size
163 , DxInfo := A_TickCount A_Tab QPC "`r1:Initializing function" #
164 . "q:" QPC #
165 . "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>" #
166 . "c1:ImageFile:" %A_ThisFunc%(">Escape<", ImageFile) #
167 . "c2:Options:" %A_ThisFunc%(">Escape<", Options) #
168 . "c3:A_ThisLabel:" A_ThisLabel #
169 . "c4:A_WorkingDir:" A_WorkingDir #
170 . "c5:A_BatchLines:" A_BatchLines #
171 . "c6:A_TitleMatchMode:" A_TitleMatchMode #
172 . "l:" A_LineNumber - 1 #
173 }
174 If DxInfo
175 DxInfo .= $ "2:Parsing options" #
176 . "t:The information passed to " A_ThisFunc "() through the options parameter (2nd param) will now be parsed into individual script settings." #
177 . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
178 . "l:" A_LineNumber + 1
179 While (@5 := RegExMatch(TempOptions, "i)(?:^|\s)(?:!(\w+)|(\+|-)?(" Commands ")(" Literal "(?:[^" Literal "]|" Literal Literal ")*" Literal "(?= |$)|[^ ]*))", @, @5 + StrLen(@))) {
180 If (@1 <> "") {
181 TempOptions := SubStr(TempOptions, 1, @5 + StrLen(@)) A_Space UserConfig_%@1% SubStr(TempOptions, @5 + StrLen(@))
182 If DxInfo
183 DxInfo .= $ "2:Loading user configuration: !" @1 #
184 . "l:" DefaultOptionsLocation + 1 #
185 . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
186 . "c1:UserConfig:" @1 #
187 . "c2:Options:" %A_ThisFunc%(">Escape<", TempOptions) #
188 . "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." #
189 } Else If (@4 <> "") {
190 If (InStr(@4, Literal) = 1) and (@4 <> Literal) and (SubStr(@4, 0, 1) = Literal) and (@4 := SubStr(@4, 2, -1))
191 StringReplace, @4, @4, %Literal%%Literal%, %Literal%, All
192 %@3% := @4
193 } Else
194 %@3% := @2 = "+" ? True : @2 = "-" ? False : %@3%_user
195 If DxInfo {
196 RegExMatch(OptionInfo, "i)`r" @3 "`t\K[^`n]+", @6)
197 DxInfo .= $ "3:" @3 #
198 . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
199 . "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.") #
200 . "l:" A_LineNumber - 2 #
201 . "c1:" @3 ":" %A_ThisFunc%(">Escape<", %@3%) #
202 StringReplace, TempCommands, TempCommands, |%@3%|, |
203 }
204 }
205 If (SpecialLaunch = 4)
206 Return
207 If (dx <> "")
208 If DxInfo {
209 @ := "t:The remaining script settings take the following default values:`n`n<table>"
210 , DxInfo .= $ "2:Other script settings" #
211 . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
212 . "l:" DefaultOptionsLocation + 1 #
213 Loop, Parse, TempCommands, |
214 If (A_LoopField <> "")
215 DxInfo .= "c" A_Index ":" A_LoopField ":" %A_ThisFunc%(">Escape<", %A_LoopField%) #
216 , @ .= A_LoopField ";%" A_LoopField "%`n"
217 DxInfo .= @ "</table>"
218 } Else {
219 Cache := ">>" Cache
220 Return %A_ThisFunc%(ImageFile, Options)
221 }
222 LastOptions := Options, @ := LastImageFile, LastImageFile := ImageFile
223 If DxInfo
224 DxInfo .= $ "1:Preparing Image File" #
225 . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
226 . "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." #
227 . "l:" A_LineNumber + 1
228 If !(((ImageFile = @) and FileExist(ImageFilePath)) or %A_ThisFunc%(">ParseCache<", ImageFile)) {
229 NewImage := True, ImageFilePath := ""
230 If RegExMatch(ImageFile, "i)^\*(?:0x)?([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})(?:\D*(\d+)\D*(\d+).*?)?$", @) {
231 ImageW := @4 ? @4 : 1, ImageH := @5 ? @5 : 1, Color := UseRGB ? @1 @2 @3 : @3 @2 @1
232 If DxInfo
233 DxInfo .= $ "2:PixelSearch Set" #
234 . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
235 . "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>" #
236 . "l:" A_LineNumber - 2 #
237 . "c1:Color:" Color #
238 . "c2:UseRGB:" UseRGB #
239 . "c3:ImageW:" ImageW #
240 . "c4:ImageH:" ImageH
241 If !FileExist(ImageFilePath := A_Temp "\" A_ThisFunc "_" Color "_" ImageW "x" ImageH ".png") {
242 If DxInfo
243 DxInfo .= $ "2:Building image of color #" Color #
244 . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
245 . "c1:A_Temp:" A_Temp #
246 . "l:" A_LineNumber - 2 #
247 . "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%"
248 VarSetCapacity(Colors, ImageW * ImageH * 7)
249 Loop % ImageW * ImageH
250 Colors .= "|" Color
251 @6 := %A_ThisFunc%(">MakeImage<", "" A_Temp "\" A_ThisFunc "_" Color "_" ImageW "x" ImageH "|png|" ImageW "|" ImageH Colors)
252 If DxInfo and (@6 > 1)
253 DxInfo .= "`n`nProcess required " @6 " tries to succeed (due to a bug in either the GDI+ code or my code.)"
254 }
255 } Else {
256 DefaultDirs := SubStr(RegExReplace(DefaultDirs "|", "\\*(?:\||^)+", Asc(ImageFile) = 92 ? "|" : "\|"), 2, -1), DefaultExts := SubStr(RegExReplace("|" DefaultExts "|", "\|\.*", "|."), 1, -2)
257 If DxInfo
258 DxInfo .= $ "2:ImageFile not seen before" #
259 . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
260 . "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." #
261 . "l:" GlobalSettingsLocation + 1 #
262 . "d:2"
263 Loop, Parse, DefaultDirs, |
264 {
265 ThisDir := A_LoopField
266 If DxInfo
267 DxInfo .= $ "3:" (A_Index = 1 ? "(Working Dir)" : SubStr(ThisDir, 1, -1)) #
268 . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
269 . "t:Directory #" A_Index " is:`n`n%ThisDir%`n`n(This can be specified at the top of the script in DefaultDirs.)" #
270 . "c1:ThisDir:" %A_ThisFunc%(">Escape<", ThisDir)
271 Loop, Parse, DefaultExts, |
272 If FileExist(ThisDir ImageFile A_LoopField) {
273 If InStr(FileExist(ImageFilePath := ThisDir ImageFile A_LoopField), "D")
274 ImageFilePath := ""
275 Else
276 Break
277 } Else If DxInfo
278 DxInfo .= $ "4:" ImageFile A_LoopField #
279 . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
280 . "t:Trying file path:`n`n%ImageFilePath%`n`nFile does not exist." #
281 . "c1:ImageFilePath:" %A_ThisFunc%(">Escape<", ThisDir ImageFile A_LoopField) #
282 . "d:1" #
283 . "l:" A_LineNumber - 6
284 If (ImageFilePath <> "")
285 Break
286 }
287 If (ImageFilePath = "") {
288 Error = File Not Found
289 Message = Image file "%ImageFile%" not found.
290 Buttons = &Create Image,&Debug,E&xit,&Help
291 If (%A_ThisFunc%(">Error<") = "Create Image")
292 %A_ThisFunc%(">>" ImageFile, Options)
293 Return
294 } Else If DxInfo
295 DxInfo .= $ "4:Image file found" #
296 . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
297 . "t:Trying file path:`n`n%ImageFilePath%`n`nImage file found!" #
298 . "c1:ImageFilePath:" %A_ThisFunc%(">Escape<", ImageFilePath) #
299 . "l:" A_LineNumber - 10 #
300 . "d:1"
301 If !%A_ThisFunc%(">ParseCache<", ImageFilePath) {
302 If DxInfo
303 DxInfo .= $ "2:Image Preview - Measuring width and height" #
304 . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
305 . "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>" #
306 Gui, %GuiA%:Add, Picture, Hwnd@, %ImageFilePath%
307 WinGetPos, , , ImageW, ImageH, ahk_id %@%
308 Gui, %GuiA%:Destroy
309 If (ImageW = "") {
310 Error = Image file type unsupported
311 Message = Image file "%ImageFile%" appears to be of an unsupported filetype.
312 Buttons = &View File,&Debug,E&xit,&Help
313 If (%A_ThisFunc%(">Error<") = "View File")
314 MsgBox, 262160, %A_ScriptName%: Error, Function not yet supported, sorry! ; xxx
315 Return
316 }
317 If DxInfo
318 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" #
319 . "c1:ImageW:" %A_ThisFunc%(">Escape<", ImageW) #
320 . "c2:ImageH:" %A_ThisFunc%(">Escape<", ImageH) #
321 . "l:" A_LineNumber - 7 #
322 . "d:5"
323 }
324 }
325 }
326 If (o <> "") {
327 If DxInfo
328 @ := o
329 o := SubStr(RegExReplace(A_Space o, "[^\w-]+", " *"), 2) A_Space
330 If DxInfo and (o <> @ A_Space)
331 DxInfo .= $ "2:Refining imagesearch options" #
332 . "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>" #
333 . "l:" A_LineNumber - 2 #
334 . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
335 . "c1:o:" %A_ThisFunc%(">Escape<", SubStr(o, 1, -1)) #
336 . "c2:o_original:" %A_ThisFunc%(">Escape<", @) #
337 }
338 If (Func <> "") {
339 StringReplace, Func, Func, ()
340 If !IsFunc(Func)
341 MsgBox, 262160, %A_ScriptName%: Error, Function %Func%() does not exist. ;xxx
342 Else
343 n := 0
344 }
345 If (r <> "") and RegExMatch(r, "i)^0x[0-9A-F]{5,8}$") {
346 r := "ahk_id " r
347 If DxInfo
348 DxInfo .= $ "2:Refining WinTitle option" #
349 . "t:The ""r"" option (relative to window) is a hexadecimal number, so it will be interpreted as a window handle and becomes ""%r%""." #
350 . "l:" A_LineNumber - 2 #
351 . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
352 . "c1:r:" %A_ThisFunc%(">Escape<", r) #
353 }
354 If d
355 If (InStr(d, "t") = 1) or (InStr(d, "u") = 1) {
356 If DxInfo
357 DxInfo .= $ "2:Ignoring d option" #
358 . "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." #
359 . "c1:d:" d #
360 . "l:" A_LineNumber + 1 #
361 . "q:" DllCall("QueryPerformanceCounter", "Int648", QPC) * QPC #
362 d := ""
363 } Else
364 StringLower, d, d
365 If (e = "") {
366 If Count or d
367 e := e_user
368 Else If (t <> "")
369 e := 0.99
370 If DxInfo and (e <> "")
371 DxInfo .= $ "2:Overlap set to " e #
372 . "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%." #
373 . "c1:e:" e #
374 }
375 If (InStr(m, "c") = 1) {
376 If DxInfo
377 @ := k
378 If k Contains RButton
379 k = Right
380 Else If k Not In Left,Right,Middle,L,R,M,X1,X2,WheelUp,WU,WheelDown,WD,WheelLeft,WL,WheelRight,WR
381 k = Left
382 If DxInfo and (@ <> k)
383 DxInfo .= $ "2;Correcting k option" #
384 . "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." #
385 . "c1:k:" k #
386 }
387 } Else { ; xxx fix this part
388 If dx
389 Cache := ">3" Cache, OptionInfo := %A_ThisFunc%(A_Space), TempCommands := Commands, DxStartMS := A_TickCount, VarSetCapacity(DxInfo, 2500)
390 , DxInfo .= "1:Initializing function" #
391 . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
392 . "t:Called at " A_Now #
393 . "l:" A_LineNumber - 1
394 , DxStartQPC := QPC
395 If DxInfo
396 DxInfo .= $ "2:Restoring previous settings" #
397 . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
398 . "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."
399 }
400 If DxInfo
401 DxInfo .= $ "1:Preparing other script settings" #
402 . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
403 . "t:If additional options were specified, " A_ThisFunc "() may need to prepare certain settings relevant to these options before performing the imagesearch." #
404 . "l:" A_LineNumber
405 SysGet, MonitorCount, MonitorCount
406 If (MonitorCount <> SubStr(MonitorInfo, 1, InStr(MonitorInfo, "`n") - 1)) {
407 MonitorInfo := MonitorCount
408 Loop %MonitorCount% {
409 SysGet, @, Monitor, %A_Index%
410 MonitorInfo .= "`n" @Left "," @Top ";" @Right - 1 "," @Bottom - 1
411 }
412 }
413 CoordMode, Pixel
414 CoordMode, Mouse
415 If (r <> "") {
416 WinGetPos, Search1, Search2, Search3, Search4, %r%
417 If (Search1 = "") or (Search3 <= 0) or (Search4 <= 0) {
418 If (Search1 = "") {
419 Error = Window Not Found
420 Message = Window "%r%" was not found. ; xxx
421 } Else {
422 Error = Window Invisible
423 Message = Window "%r%" reported a negative width and/or height to AutoHotkey, meaning that it is probably not visible on the screen.
424 }
425 Buttons = &Debug,E&xit,&Help
426 %A_ThisFunc%(">Error<")
427 Return
428 } Else If DxInfo
429 DxInfo .= $ "2:Window """ r """ found" #
430 . "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." #
431 . "l:" A_LineNumber - 1 #
432 . "d:2"
433 Search3 += Search1 - 1, Search4 += Search2 - 1
434 }
435 If (a <> "") and (InStr(a, "m") <> 1) {
436 If DxInfo
437 @ := "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>"
438 If (r = "")
439 If (MonitorCount > 1) {
440 MouseGetPos, MouseX, MouseY
441 Loop, Parse, MonitorInfo, `n
442 If (A_Index > 1) {
443 StringSplit, Search, A_LoopField, `,;
444 If (MouseX >= Search1) and (MouseY >= Search2) and (MouseX <= Search3) and (MouseY <= Search4)
445 Break
446 }
447 } Else
448 Search1 := 0, Search2 := 0, Search3 := A_ScreenWidth - 1, Search4 := A_ScreenHeight - 1
449 Loop, Parse, a, |`,
450 If A_LoopField is Number
451 {
452 Search%A_Index% := (A_LoopField >= 0 ? (A_Index & 1 ? Search1 : Search2) - (A_Index >= 3) : (A_Index & 1 ? Search3 : Search4)) + A_LoopField
453 If DxInfo
454 StringReplace, @, @, %A_Index%*, % "Now = " Search%A_Index%
455 }
456 If DxInfo
457 DxInfo .= $ "2:Modifying search area" #
458 . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
459 . "t:" RegExReplace(@, ";\K\d\*", "Unchanged") #
460 . "l:" A_LineNumber - 6
461 If (Search3 < Search1) or (Search4 < Search2) {
462 Error = Search area is 0
463 Message = The search area requested using the "a" option resulted in an area of 0 pixels, thus the search will not be conducted.
464 Buttons = &Debug,E&xit,&Help
465 %A_ThisFunc%(">Error<")
466 Return
467 }
468 }
469 Found := 0
470 If (InStr(a, "m") <> 1) {
471 SubRegions := ((a = "") and (r = "") ? SubStr(MonitorInfo, InStr(MonitorInfo, "`n") + 1) : Search1 "," Search2 ";" Search3 "," Search4) "`n"
472 If (w <> "")
473 SubRegionsW := SubRegions
474 }
475 If (t <> "") and (LastX1 <> "") and SubRegions {
476 LastX2 := LastX1 + ImageW - 1, LastY2 := LastY1 + ImageH - 1
477 Loop, Parse, SubRegions, `n
478 If (A_LoopField <> "") {
479 StringSplit, @, A_LoopField, `,;
480 If (LastX1 >= @1) and (LastX2 <= @3) and (LastY1 >= @2) and (LastY2 <= @4) {
481 StringReplace, t, t, -, , UseErrorLevel
482 @ := ErrorLevel
483 StringReplace, SubRegions, SubRegions, %A_LoopField%`n
484 If InStr(t, "%")
485 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
486 Else If t Is Integer
487 LastX1 -= t, LastY1 -= + t, LastX2 += t, LastY2 += t
488 Else
489 MsgBox, 262160, %A_ScriptName%: Error, Incorrect value of t given ; xxx
490 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 )
491 Break
492 }
493 }
494 LastX1 := LastY1 := ""
495 }
496 If (w <> "") {
497 StringSplit, w, w, `,|-
498 If (w2 = "")
499 w2 := !w1 or (w1 > 1000) ? 100 : Floor(w1 / 10)
500 If DxInfo
501 DxInfo .= $ "2:Logging start time" #
502 . "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." : ".") #
503 . "c1:w1:" w1 #
504 . "c2:w2:" w2 #
505 . "c3:A_TickCount:" A_TickCount #
506 . "q:" DllCall("QueryperformanceCounter", "Int64*", QpC) * QPC #
507 . "l:" A_LineNumber + 1 #
508 If w1
509 w1 += A_TickCount
510 }
511 If DxInfo
512 DxInfo .= $ "1:Searching for image" #
513 . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
514 . "t:The actual ImageSearch portion of the script will now begin. This is generally the most CPU-intensive portion of the script." #
515 . "l:" A_LineNumber + 1
516 Loop {
517 If DxInfo
518 @ := "" #
519 . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
520 . "t:Searching and clicking, if applicable." #
521 . "g:+.*(Performing|Found).*" #
522 . "l:" A_LineNumber + 1
523 If (SubRegions <> "") {
524 Search := SubStr(SubRegions, 1, InStr(SubRegions, "`n") - 1), SubRegions := SubStr(SubRegions, InStr(SubRegions, "`n") + 1)
525 StringSplit, Search, Search, `,;
526 If Search5 in A,B
527 e1 := Floor(ImageW * e)
528 Else If Search5 = C
529 e1 := SubRegions = "" ? 0 : Floor(ImageW * e)
530 Else If Search5 in P,R
531 e1 := Floor(ImageW * e)
532 Else
533 e1 := 0
534 If Search5 in P,Q,R,S
535 e2 := Floor(ImageH * e)
536 Else
537 e2 := 0
538 } Else If (MostX <> "") { ; triggers directional search ("d" option)
539 FoundXOrig := MostX, FoundYOrig := MostY, SubRegions := "`n", ErrorLevel := False
540 } Else If (InStr(a, "m") = 1) and !Results {
541 MouseGetPos, Search1, Search2
542 If DxInfo
543 @ .= $ "3:Retrieving mouse position" #
544 . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
545 . "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>" #
546 . "l:" A_LineNumber - 2 #
547 . "d:2" #
548 . "u:m" #
549 . "c1:a:" a #
550 . "c2:MouseX:" Search1 #
551 . "c3:MouseY:" Search2 #
552 . "g:Color,Red;Trans,200;Add,Picture,x10 y10 w30 h-1," A_WinDir "\Cursors\larrow.cur;Trans,150;Show,x" Search1 - 10 " y" Search2 - 10 " w37 h51 NA"
553 Search3 := Search1 + SubStr(a, 2), Search4 := Search2 + SubStr(a, 2), Search1 -= SubStr(a, 2), Search2 -= SubStr(a, 2), e1 := 0, e2 := 0
554 } Else
555 Break ; XXX
556 If (d = "") or (SubRegions <> "`n") { ; SubRegions = `n means d was selected and search is done, it's a dry run to click on the d-most option
557 If DxInfo
558 @5 := (Search3 - Search1 < 80 or Search4 - Search2 < 80) * 100
559 , @ .= $ "3:Performing ImageSearch" #
560 . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
561 . "t:The following line of code will execute:`n`n%Code_Orig%`n`nType of region: " (Search5 ? Search5 : "Normal") (@5 ? "`n`n(Red region is searched, blue region is for ease of visibility.)" : "") #
562 . "l:" A_LineNumber + 2 #
563 . "u:http://www.autohotkey.com/docs/imagesearch`no" #
564 . "d:5" #
565 . "c1:Code:ImageSearch, FoundX, FoundY, " Round(Search1) ", " Round(Search2) ", " Round(Search3) " + " e1 ", " Round(Search4) " + " e2 ", " o ImageFilePath #
566 . "g:Color,44AADD,0000FF;Trans,80;Add,Progress,x" @5 " y" @5 " w" Search3 - Search1 + 1 " h" Search4 - Search2 + 1 " cFF9999 BackgroundFF9999,100;Show,NA x" Search1 - @5 " y" Search2 - @5 " w" Search3 - Search1 + e1 + @5 * 2 + 1 " h" Search4 - Search2 + e2 + @5 * 2 + 1
567 ImageSearch, FoundXOrig, FoundYOrig, Search1, Search2, Search3 + e1, Search4 + e2, %o%%ImageFilePath%
568 }
569 If (ErrorLevel = 2) {
570 ; xxx put the variable %@% before dxinfo
571 If NewImage
572 Return %A_ThisFunc%(ImageFile, Options)
573 Error = File Not Found
574 Message = AutoHotkey was unable to use the image "%ImageFile%" for searching.
575 Buttons = &View File,&Debug,E&xit,&Help
576 If (%A_ThisFunc%(">Error<") = "View File")
577 MsgBox, 262160, %A_ScriptName%: Error, Function not yet supported, sorry! ; xxx
578 Return
579 } Else If !ErrorLevel {
580 If (w2 <> "")
581 w2 := ""
582 If DxInfo
583 DxInfo .= $ "2:" (SubRegions = "`n" ? "Selecting " d "-most Image" : "Search #" A_Index " - Success") @
584 . $ "3:Image Found at " FoundXOrig ", " FoundYOrig #
585 . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
586 . "t:The image was found at the coordinates (%FoundX%, %FoundY%). These coordinates are relative to the screen." #
587 . "l:" A_LineNumber - 3 #
588 . "d:5" #
589 . "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 #
590 . "c1:FoundX:" FoundXOrig #
591 . "c2:FoundY:" FoundYOrig
592 If (d = "") or (SubRegions = "`n") {
593 If !Found
594 LastX1 := FoundXOrig, LastY1 := FoundYOrig
595 Found += 1, Results .= Delim f, FoundX := FoundXOrig + Center * (ImageW - 1) // 2 + Floor(x), FoundY := FoundYOrig + Center * (ImageH - 1) // 2 + Floor(y)
596 StringReplace, Results, Results, %CharX%, %FoundX%, All
597 StringReplace, Results, Results, %CharY%, %FoundY%, All
598 StringReplace, Results, Results, %CharN%, %Found%, All
599 If n {
600 If DxInfo
601 DxInfo .= $ "3:Performing Clicks" #
602 . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
603 . "t:The ""n"" (number of clicks/no clicks) was not set to 0 so the script will now perform clicks on the image." #
604 . "l:" A_LineNumber - 2 #
605 . "u:m`nn" #
606 . "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
607 If (Found <> 1)
608 Sleep %Sleep%
609 If (InStr(m, "c") = 1) {
610 If (Found = 1) {
611 ControlDelay := A_ControlDelay
612 SetControlDelay, -1
613 DetectHiddenWindows := A_DetectHiddenWindows
614 DetectHiddenWindows, Off
615 }
616 WinGet, WinList, List
617 Loop %WinList% {
618 WinGetPos, @1, @2, @3, @4, % "ahk_id " WinList%A_Index%
619 If (FoundX >= @1) and (FoundY >= @2) and (FoundX <= @1 + @3) and (FoundY <= @2 + @4) {
620 Window := WinList%A_Index%
621 WinGetPos, ClickX, ClickY, , , ahk_id %Window%
622 Break
623 } Else If (A_Index = WinList) {
624 Error = ControlClick Error
625 Message = %A_ThisFunc%() was unable to locate a window to use for a ControlClick keystroke.
626 Buttons = &Debug,E&xit,&Help
627 %A_ThisFunc%(">Error<")
628 Return
629 }
630 }
631 } Else {
632 If (Found = 1) {
633 CoordMode, Mouse
634 MouseDelay := A_MouseDelay
635 SetMouseDelay, -1
636 MouseGetPos, MouseX, MouseY
637 If DxInfo
638 DxInfo .= $ "4:Saving mouse coordinates" #
639 . "l:" A_LineNumber - 1 #
640 . "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>" #
641 . "c1:MouseX:" MouseX #
642 . "c2:MouseY:" MouseY #
643 . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
644 . "g:Color,Red;Trans,200;Add,Picture,x10 y10 w30 h-1," A_WinDir "\Cursors\larrow.cur;Trans,150;Show,x" MouseX - 10 " y" MouseY - 10 " w37 h51 NA"
645 }
646 If DxInfo
647 DxInfo .= $ "4:Moving mouse to " MouseX ", " MouseY #
648 . "d:2" #
649 . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
650 . "l:" A_LineNumber + 1 #
651 . "c1:FoundX:" MouseX #
652 . "c2:FoundY:" MouseY #
653 . "t:Moving mouse to coordinates (%FoundX%, %FoundY%). Coordinates are relative to the screen." #
654 . "g:Color,Green;Trans,200;Add,Picture,x10 y10 w30 h-1," A_WinDir "\Cursors\larrow.cur;Trans,150;Show,x" FoundX - 10 " y" FoundY - 10 " w37 h51 NA"
655 MouseMove, FoundX, FoundY, 0
656 }
657 Loop % n * 2 - 1 {
658 If DxInfo
659 DxInfo .= $ "4:" (A_Index & 1 ? "Clicking" : "Sleeping") #
660 . "t:The following line of code will execute:`n`n%Code_Orig%" #
661 . (A_Index & 1 ? "g:-Performing Clicks" # : "")
662 . "d:4" #
663 . "l:" A_LineNumber - 14 #
664 . "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)
665 If !(A_Index & 1)
666 Sleep %Sleep%
667 Else If (SubStr(m, 1, 1) = "i")
668 SendInput %k%
669 Else If (SubStr(m, 1, 1) = "c")
670 ControlClick, % "x" FoundX - ClickX " y" FoundY - ClickY, ahk_id %Window%, , %k%, , NA
671 Else If (SubStr(m, 1, 1) = "p")
672 SendPlay %k%
673 Else If (SubStr(m, 1, 1) = "e")
674 SendEvent %k%
675 Else
676 Send %k%
677 }
678 } Else If (Func <> "")
679 %Func%(FoundX, FoundY)
680 If d or (t <> "")
681 Break
682 }
683 If (e <> "") {
684 If (FoundXOrig + ImageW < Search3) and (FoundYOrig + ImageH < Search4)
685 SubRegions := FoundXOrig + ImageW "," FoundYOrig ";" Search3 "," Search4 ";" "C`n" SubRegions
686 If (FoundYOrig + ImageH < Search4)
687 SubRegions := FoundXOrig "," FoundYOrig + ImageH ";" FoundXOrig + ImageW - 1 "," Search4 ";" "B`n" SubRegions
688 If (FoundXOrig > Search1) and (FoundYOrig + ImageH < Search4)
689 SubRegions := Search1 "," FoundYOrig + 1 ";" FoundXOrig - 1 "," Search4 ";" "A`n" SubRegions
690 If DxInfo
691 DxInfo .= $ "3:More regions queued" #
692 . "t:Because the ""e"" or ""d"" 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.)" #
693 . "l:" A_LineNumber - 7
694 If d
695 If (Asc(d) = 108) { ; l (Left)
696 If (MostX = "") or (FoundXOrig < MostX)
697 MostX := FoundXOrig, MostY := FoundYOrig
698 } Else If (Asc(d) = 114) { ; r (Right)
699 If (MostX = "") or (FoundXOrig > MostX)
700 MostX := FoundXOrig, MostY := FoundYOrig
701 } Else If (Asc(d) = 98) or (Asc(d) = 100) { ; b (Bottom) / d (Down)
702 If (MostX = "") or (FoundYOrig > MostY)
703 MostX := FoundXOrig, MostY := FoundYOrig
704 } Else { ; Distance from coords
705 If (Dist1 = "") {
706 If (Asc(d) = 109) ; m (MousePos)
707 MouseGetPos, Dist1, Dist2
708 Else
709 StringSplit, Dist, d, |`,
710 Dist1 -= Center * (ImageW - 1) // 2 + Floor(x), Dist2 -= Center * (ImageH - 1) // 2 + Floor(y)
711 }
712 If (MostX = "") or (Sqrt((FoundXOrig - Dist1)**2 + (FoundYOrig - Dist2)**2) < Sqrt((MostX - Dist1)**2 + (MostY - Dist2)**2))
713 MostX := FoundXOrig, MostY := FoundYOrig
714 }
715 } Else
716 Break
717 } Else If (w2 = "") or SubRegions or (w1 and (A_TickCount > w1)) {
718 If DxInfo
719 DxInfo .= $ "2:Search #" A_Index @
720 . $ "3:Image Not Found" #
721 . "t:The image was not found in the given region.`n`n" ((Results and e) or (d and MostX != "") ? SubRegions = "" ? "No more regions remain to be searched (""e"" or ""d"" 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." : "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.")) #
722 . "g:Color,44AADD,0000FF;Trans,80;Add,Progress,x" @5 " y" @5 " w" Search3 - Search1 + 1 " h" Search4 - Search2 + 1 " cRed BackgroundRed,100;Show,NA x" Search1 - @5 " y" Search2 - @5 " w" Search3 - Search1 + e1 + @5 * 2 + 1 " h" Search4 - Search2 + e2 + @5 * 2 + 1 #
723 . "d:3" #
724 . "l:" A_LineNumber - 2
725 If (w != "") and (Subregions = "")
726 Break
727 } Else If (w2 <> "") and (Results = "") {
728 If DxInfo
729 DxInfo .= $ "2:Search #" A_Index @
730 . "`r3:Image not found, sleeping" #
731 . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
732 . "t:The image was not found in the search region.`n`nThe ""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 ; show all locations found xxx
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:Returning mouse to coordinates (" MouseX ", " MouseY "). Coordinates are relative to the screen." #
758 . "q:" DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC #
759 . "g:Color,Red;Trans,200;Add,Picture,x10 y10 w30 h-1," A_WinDir "\Cursors\larrow.cur;Trans,150;Show,x" MouseX - 10 " y" MouseY - 10 " w37 h51 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< ;--------------------------------------------------Checks if an image file has already been used--------------------------------------------------
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< ;--------------------------------------------------Gui event handler--------------------------------------------------
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) ;% A_ThisFunc A_Space (A_Gui = GuiA ? "Debugger" : "Screenshot Creator")
810 }
811 Else If ImageFile = >Escape< ;--------------------------------------------------Escapes characters for diagnostic mode storage--------------------------------------------------
812 {
813 StringReplace, Options, Options, ``, ````, All
814 StringReplace, Options, Options, %#%, ``#, All
815 StringReplace, Options, Options, %$%, ``$, All
816 Return Options
817 } Else If (ImageFile = ">UnEscape<") { ;--------------------------------------------------Un-escapes characters for diagnostic mode display--------------------------------------------------
818 Options := RegExReplace(RegExReplace(Options, "(?<!``)``#", #), "(?<!``)``\$", $)
819 StringReplace, Options, Options, ````, ``, All
820 Return Options
821 }
822 Else If ImageFile = >ShowChars< ;--------------------------------------------------Replaces non-visible characters for diagnostic mode--------------------------------------------------
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< ;--------------------------------------------------Assembles gui elements--------------------------------------------------
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< ;--------------------------------------------------Forms data into a table for diagnostic mode--------------------------------------------------
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< ;--------------------------------------------------Builds an image file using GDI+--------------------------------------------------
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%.%Param2%
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, A_PtrSize = 8 ? 24 : 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" SubStr("000000" A_LoopField, -5))
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< ;--------------------------------------------------Displays & handles error dialogs--------------------------------------------------
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) ;--------------------------------------------------Debugging--------------------------------------------------
945 {
946 DetectHiddenWindows := A_DetectHiddenWindows, WinDelay := A_WinDelay
947 DetectHiddenWindows, On
948 SetWinDelay, -1
949 ;|||||||||||||||||||||||||||||||||||||| Debugging Gui Settings ||||||||||||||||||||||||||||||||||||||
950 ;----------------------------------------------------------------------------------------------------
951 DebugSettingsLocation = %A_LineNumber% ; Line number placeholder (do not edit)
952 EditorPath = C:\Program Files (x86)\Notepad++\Notepad++.exe ; Path to editor utilized when you select "Go To Line" command
953 EditorCommand = -n`%LineNumber`% ; Format of command-line parameter to open above editor to the desired line. `%LineNumber`% is substituted by the line number. Use -goto:`%LineNumber`% for SciTE and -n`%LineNumber`% for Notepad++
954 HotkeyPlay = Space ; Hotkeys
955 HotkeyNext = .
956 HotkeyPrev = ,
957 HotkeyCompactView = ``
958 ShrinkByW = 50 ; Amount to shrink when in "compact view"
959 ShrinkByH = 100
960 TextBoxFontSize = 9 ; Misc GUI element tweaks
961 TextBoxFontFace = Lucida Console
962 TreeViewFontSize = 10
963 TreeViewFontFace = Segoe UI
964 Width = 350
965 ControlHeight = 30
966 TextBoxHeight = 200
967 TreeViewHeight = 250
968 PlayingText = Playing
969 ButtonWidth = 60
970 Margins = 7
971 PlaySpeed = .3
972 ButtonFontSize = 10
973 ButtonFontFace = Segoe UI
974 TextBoxFontSize = 9 ; Default values for certain checkbox settings
975 ShowChars = %True%
976 ShowGraphics = %True%
977 AlwaysOnTop = %False%
978 PlaySpeed = 3
979 Playing = %False%
980 SkipSteps = %True%
981 StartAt = 1
982 SaveTo =
983 WrapText = %True% ; needs work
984 CompactView = %False% ; needs work
985 AutoClose = %False% ; needs work
986 ;----------------------------------------- Gui Text Elements ----------------------------------------
987 ; Edit the variables below to change the text of the buttons and other elements in the debugger GUI. This can be done to change the language of the interface, or to change the accelerator keys (using the "&" symbol).
988 ButtonPlay = &Play
989 ButtonPause = &Pause
990 ButtonPrev = <
991 ButtonNext = >
992 MenuFile = &%A_ThisFunc%
993 MenuFilePrev = &Previous Step
994 MenuFileNext = &Next Step
995 MenuFileStandard = Script &Menu
996 MenuFileEdit = &Go to line
997 MenuFileSave = &Save
998 MenuFileExit = E&xit
999 MenuCopy = &Clipboard
1000 MenuCopyStepName = Copy Step &Name
1001 MenuCopyStepText = Copy Step &Text
1002 MenuSettings = &Settings
1003 MenuSettingsCompactView = &Compact View
1004 MenuSettingsAlwaysOnTop = &Always On Top
1005 MenuSettingsShowGraphics = Show &Graphics
1006 MenuSettingsShowChars = Show &Whitespaces
1007 MenuSettingsWrapText = &Wrap Text
1008 MenuSettingsEdit = &Edit Debugger Settings
1009 MenuSettingsSkipSteps = Skip Unimportant Steps
1010 MenuSettingsAutoClose = Close When Finished ; needs work
1011 MenuHelp = &Help
1012 MenuHelpDocs = &%A_ThisFunc% Documentation
1013 MenuHelpDebugger = &Debugger Help
1014 MenuHelpWhitespaceView = &Whitespace Viewer Help
1015 MenuHelpAbout = &About %A_ThisFunc%
1016 ;||||||||||||||||||||||||||||||||||||||||||| End Settings |||||||||||||||||||||||||||||||||||||||||||
1017 Menus =
1018 (
1019 Standard
1020 File:Prev,Next,Play,,Standard,,Edit,Save,Exit
1021 Copy:StepName,StepText,
1022 Settings:CompactView,AlwaysOnTop,ShowGraphics,ShowChars,WrapText,SkipSteps,AutoClose,,Edit
1023 Help:Docs,Debugger,WhitespaceView,About,
1024 Bar:File,Copy,Settings,Help
1025 Context:File,Copy,Settings,Help
1026 )
1027 Loop, Parse, Options, CSV
1028 If (A_LoopField = "Reset")
1029 LastImageFile := Cache := "" ;xxx
1030 Else If RegExMatch(A_LoopField, "^([A-Za-z0-9_#$]+)=([\s\S]*)$", @)
1031 %@1% := @2
1032 Else If (A_Index <> 1)
1033 MsgBox, 262160, %A_ScriptName% - %A_Thisfunc%(): Error, Poorly formatted Options param for diagnostic mode:`n%A_LoopField%
1034 If SaveTo {
1035 FileDelete, %SaveTo%
1036 StringReplace, DxInfo, DxInfo, `r, `r`n, All
1037 FileAppend, %DxInfo%, %SaveTo%
1038 Return DxInfo := ""
1039 }
1040 StringReplace, Menus, Menus, %A_Space%, , All
1041 StringReplace, Menus, Menus, %A_Tab%, , All
1042 MenuStandard := True, Hotkeys := "Play,Next,Prev,CompactView", Buttons := "Button1,Button2,Button3,Edit2"
1043 Menu, %A_ThisFunc%MenuStandard, Standard
1044 Loop, Parse, Menus, `n
1045 Loop, Parse, A_LoopField, :`,
1046 If (A_Index > 1) {
1047 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
1048 If A_LoopField and %A_LoopField%
1049 Menu, %A_ThisFunc%Menu%ThisMenu%, Check, % Menu%ThisMenu%%A_LoopField% (Hotkey%A_LoopField% = "" ? "" : A_Tab Hotkey%A_LoopField%)
1050 } Else
1051 ThisMenu := A_LoopField
1052 GuiHWND := %A_ThisFunc%(">NewGui<", GuiA
1053 . ";+Label" A_ThisFunc (AlwaysOnTop ? " +AlwaysOnTop" : "")
1054 . ";Font,s" ButtonFontSize "," ButtonFontFace
1055 . ";Menu," A_ThisFunc "MenuBar"
1056 . ";Add,Button,g" A_ThisFunc "Close x" Margins " y" Margins " w" ButtonWidth " h" ControlHeight "," ButtonPrev
1057 . ";Add,Button,g" A_ThisFunc "Close x+" Margins " yp wp hp," ButtonPlay
1058 . ";Add,Button,g" A_ThisFunc "Close x+" Margins " yp wp hp +Default," ButtonNext
1059 . ";Font,s" TreeViewFontSize "," TreeViewFontFace
1060 . ";Add,TreeView,g" A_ThisFunc "Close vErrorLevel +AltSubmit x" Margins " y+" Margins " w" Width " h" TreeViewHeight
1061 . ";Font,s" TextBoxFontSize "," TextBoxFontFace
1062 . ";Add,Edit,+ReadOnly " (WrapText ? "+Wrap -HScroll" : "-Wrap +HScroll") " x" Margins " y+" Margins " w" Width " h" TextBoxHeight
1063 . ";Add,Edit,-VScroll +ReadOnly -Wrap x" ButtonWidth * 3 + Margins * 4 " y" Margins " w" Width - (Margins + ButtonWidth) * 3 " h" ControlHeight
1064 . ";Default")
1065 If (StrLen(ImageFile) > 7) {
1066 StringTrimLeft, ImageFile, ImageFile, 7
1067 If !FileExist(ImageFile) {
1068 MsgBox, 262160, %A_ScriptName% - %A_ThisFunc%(): Error, Debug file "%ImageFile%" does not appear to exist.
1069 Return
1070 } Else
1071 FileRead, DxInfo, %ImageFile%
1072 } Else If (DxInfo = "") {
1073 MsgBox, 262160, %A_ScriptName% - %A_ThisFunc%(): Error, Improper use of the Diagnostic mode.
1074 Return
1075 } Else
1076 DxInfo := A_TickCount A_Tab DllCall("QueryPerformanceCounter", "Int64*", QPC) * QPC A_Tab DxInfo
1077 If StartAt Is Integer
1078 CurrentStep := StartAt
1079 Else
1080 RegExMatch(StartAt, "^(?:(?P<Occurence>\d+):)?(?P<Pattern>[\s\S]*)$", StartAt)
1081 Loop, Parse, DxInfo, `r, `n
1082 If (A_Index = 1) {
1083 StringSplit, @, A_LoopField, %A_Tab%
1084 QPC_Rate := (@1 - @3) / (@2 - @4), QPC_Final := @2
1085 } Else {
1086 Items := A_Index - 1
1087 Loop, Parse, A_LoopField, %A_Tab%
1088 If (A_Index = 1) {
1089 %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%)
1090 If !CurrentStep and RegExMatch(%Items%_Title, StartAtPattern) and !(--StartAtOccurence)
1091 CurrentStep := Items
1092 } Else If InStr(A_LoopField, ":") {
1093 @1 := SubStr(A_LoopField, 1, InStr(A_LoopField, ":") - 1), %Items%_%@1% := SubStr(A_LoopField, InStr(A_LoopField, ":") + 1)
1094 If @1 = g
1095 TV_Modify(%Items%_ID, "Bold")
1096 }
1097 }
1098 @ := Items + 1, %@%_q := QPC_Final, PreviousStep := 0, PlaySpeed := PlaySpeed / 20
1099 Gui, %GuiA%:Show, % "w" Width + Margins * 2 " h" TreeViewHeight + TextBoxHeight + ControlHeight + Margins * 4 ; move north
1100 Hotkey, IfWinActive, ahk_id %GuiHWND%
1101 Loop, Parse, Hotkeys, `,
1102 If (Hotkey%A_LoopField% <> "")
1103 Hotkey, % Hotkey%A_LoopField%, %A_ThisFunc%Close, On
1104 Hotkey, IfWinActive
1105 If Playing
1106 TempGuiCommand := ButtonPlay, Playing := False
1107 If !CurrentStep
1108 CurrentStep := 1
1109 Loop {
1110 If (A_Index <> 1)
1111 TempGuiCommand := GuiCommand
1112 GuiCommand := RightClick := ""
1113 If (TempGuiCommand = ButtonPlay) or (TempGuiCommand = ButtonPause) or (TempGuiCommand = HotkeyPlay) or (Playing and (TempGuiCommand = "ErrorLevel")) {
1114 Playing := !Playing
1115 ControlSetText, Button2, % Playing ? ButtonPause : ButtonPlay, ahk_id %GuiHWND%
1116 Menu, %A_ThisFunc%MenuFile, Rename, % (Playing ? ButtonPlay : ButtonPause) A_Tab HotkeyPlay, % (Playing ? ButtonPause : ButtonPlay) A_Tab HotkeyPlay
1117 } Else If (TempGuiCommand = MenuSettingsCompactView) or (TempGuiCommand = HotkeyCompactView) {
1118 If (TempGuiCommand = HotkeyCompactView)
1119 Menu, %A_ThisFunc%MenuSettings, % (CompactView := !CompactView) ? "Check" : "Uncheck", %MenuSettingsCompactView%%A_Tab%%HotkeyCompactView%
1120 Loop % n := 10 {
1121 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
1122 Gui, %GuiA%:Show, % "NA w" Width + Margins * 2 - ShrinkByW * @ / n " h" TreeViewHeight + Margins * 4 + TextBoxHeight + ControlHeight - (ShrinkByH + TextBoxHeight + Margins * 2 + ControlHeight) * @ / n
1123 }
1124 Loop, Parse, Buttons, `,
1125 GuiControl, %GuiA%:Move, %A_LoopField%, % CompactView ? "y-200" : "y" Margins
1126 } Else If (TempGuiCommand = ButtonPrev) or (TempGuiCommand = HotkeyPrev) or (TempGuiCommand = MenuFilePrev)
1127 CurrentStep -= CurrentStep = 1 ? 0 : 1
1128 Else If (TempGuiCommand = "Normal") or (TempGuiCommand = MenuFileExit) {
1129 Gui, %GuiA%:Destroy
1130 Gui, %GuiB%:Destroy
1131 Hotkey, IfWinActive, ahk_id %GuiHWND%
1132 Loop, Parse, Hotkeys, `,
1133 If (Hotkey%A_LoopField% <> "")
1134 Hotkey, % Hotkey%A_LoopField%, Off
1135 Hotkey, IfWinActive
1136 Loop, Parse, Menus, `n
1137 Menu, % A_ThisFunc "Menu" SubStr(A_LoopField, 1, Instr(A_LoopField ":", ":") - 1), Delete
1138 DetectHiddenWindows, %DetectHiddenWindows%
1139 SetWinDelay, %WinDelay%
1140 Return GuiHWND := DxInfo := ""
1141 } Else If (TempGuiCommand = MenuSettingsAlwaysOnTop)
1142 WinSet, AlwaysOnTop, % AlwaysOnTop ? "On" : "Off", ahk_id %GuiHWND%
1143 Else If (TempGuiCommand = MenuSettingsWrapText)
1144 GuiControl, % GuiA ":" (WrapText ? "+Wrap" : "-Wrap"), Edit1 ; xxx doesn't work!!
1145 Else If (TempGuiCommand = MenuFileNext) or (TempGuiCommand = ButtonNext) or (TempGuiCommand = HotkeyNext) or ((TempGuiCommand = "") and Playing) {
1146 While (CurrentStep < Items) {
1147 CurrentStep += 1
1148 If (TempGuiCommand <> "") or !Playing or (%CurrentStep%_d <> "") or !SkipSteps
1149 Break
1150 }
1151 If (CurrentStep = Items) and (TempGuiCommand = "") and Playing
1152 GuiCommand := InStr(Options, ",c,") ? "Normal" : ButtonPause
1153 } Else If (InStr(TempGuiCommand, A_ThisFunc "Menu") <> 1) {
1154 If (InStr(TempGuiCommand, "RightClick:") = 1)
1155 RightClick := True, TV_Modify(@ := SubStr(TempGuiCommand, 12))
1156 Else
1157 @ := TV_GetSelection()
1158 Loop %Items%
1159 If (%A_Index%_ID = @) {
1160 CurrentStep := A_Index
1161 Break
1162 }
1163 } Else If (TempGuiCommand = A_ThisFunc "MenuCopy")
1164 Clipboard := A_ThisMenuItem = MenuCopyStepText ? CurrentStepText : A_ThisMenuItem = MenuCopyStepName ? CurrentStep " - " %CurrentStep%_Title : %A_ThisMenuItem%_Orig_
1165 Else If (A_ThisMenuItem = MenuFileEdit LastLine) or (A_ThisMenuItem = MenuSettingsEdit) {
1166 LineNumber := A_ThisMenuItem = MenuSettingsEdit ? DebugSettingsLocation : %CurrentStep%_l
1167 Transform, @, Deref, %EditorCommand%
1168 Run, "%EditorPath%" "%A_LineFile%" %@%, , UseErrorLevel
1169 If ErrorLevel
1170 MsgBox, 262144, %A_ScriptName% - %A_ThisFunc%: Alert, Check file`n`t%A_LineFile%`nline`n`t%LineNumber%`nto find this setting.`n`n`n(Note: To have this open your editor instead of showing a message box, check line %DebugSettingsLocation% and change the variables `%EditorPath`% and `%EditorCommand`%.)
1171 } Else If (A_ThisMenuItem = MenuFileSave) {
1172 Gui, %GuiA%:+OwnDialogs
1173 FileSelectFile, File, S, %A_ThisFunc%-dx-%A_Now%.txt
1174 If !ErrorLevel {
1175 FileDelete, %File%
1176 StringReplace, @, DxInfo, `r, `r`n, All
1177 FileAppend, %@%, %File%
1178 MsgBox, 262144, %A_ScriptName% - %A_ThisFunc%: Alert, Disgnostic file saved successfully.
1179 }
1180 Gui, %GuiA%:-OwnDialogs
1181 } Else If (TempGuiCommand = A_ThisFunc "MenuHelp") {
1182 If (A_ThisMenuItem = MenuHelpWhitespaceView)
1183 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.
1184 Else If (A_ThisMenuItem = MenuHelpAbout)
1185 MsgBox, 262144, About %A_ThisFunc%, FindClick() - ImageSearch utility. Created by berban.`n`nMade with AutoHotkey. Compatible with all versions.`n`nLast updated %LastUpdate%.
1186 Else If (A_ThisMenuItem = MenuHelpDocs)
1187 Run, %ForumURL%
1188 Else
1189 MsgBox, 262160, %A_ScriptName%: Error, This menu item currently doesn't do anything. Sorry about that. ; xxx
1190 } Else {
1191 If (TempGuiCommand = A_ThisFunc "MenuSettings") {
1192 If (Settings = "")
1193 RegExMatch(Menus, "\bSettings:\K\S*", Settings)
1194 Loop, Parse, Settings, `,
1195 If (A_LoopField <> "") and (InStr(A_ThisMenuItem A_Tab, MenuSettings%A_LoopField% A_Tab) = 1) {
1196 Menu, %A_ThisFunc%MenuSettings, % (%A_LoopField% := !%A_LoopField%) ? "Check" : "Uncheck", %A_ThisMenuItem%
1197 Break
1198 }
1199 }
1200 GuiCommand := SubStr(A_ThisMenuItem, 1, InStr(A_ThisMenuItem A_Tab, A_Tab) - 1), PreviousStep := 0
1201 }
1202 If (CurrentStep <> PreviousStep) {
1203 Loop, Parse, MenuCopyItems, `,
1204 If (A_LoopField <> "") {
1205 %A_LoopField%_ := %A_LoopField%_Orig_ := ""
1206 Menu, %A_ThisFunc%MenuCopy, Delete, %A_LoopField%
1207 }
1208 Loop, Parse, MenuHelpItems, `,
1209 If (A_LoopField <> "")
1210 Menu, %A_ThisFunc%MenuHelp, Delete, %A_LoopField%
1211 MenuCopyItems := MenuHelpItems := ""
1212 While (%CurrentStep%_c%A_Index% <> "") {
1213 @ := SubStr(%CurrentStep%_c%A_Index%, 1, InStr(%CurrentStep%_c%A_Index%, ":") - 1)
1214 , %@%_Orig_ := %A_ThisFunc%(">UnEscape<", SubStr(%CurrentStep%_c%A_Index%, InStr(%CurrentStep%_c%A_Index%, ":") + 1))
1215 , %@%_ := ShowChars ? %A_ThisFunc%(">ShowChars<", %@%_Orig_) : %@%_Orig_
1216 , MenuCopyItems .= @ ","
1217 Menu, %A_ThisFunc%MenuCopy, Add, %@%, %A_ThisFunc%Menu
1218 }
1219 Loop, Parse, %CurrentStep%_u, |
1220 If (A_LoopField <> "") {
1221 Menu, %A_ThisFunc%MenuHelp, Add, %A_LoopField%, %A_ThisFunc%Menu
1222 MenuHelpItems .= A_LoopField ","
1223 }
1224 PreviousStep := CurrentStep, @ := 0, CurrentStepText := %CurrentStep%_t
1225 Transform, CurrentStepText, Deref, % CurrentStepText := RegExReplace(CurrentStepText, "%([A-Za-z0-9_#@$?]+)%", "%$1_%") ; xxx
1226 While InStr(CurrentStepText, "<table>")
1227 CurrentStepText := %A_ThisFunc%(">Table<", CurrentStepText)
1228 StringReplace, CurrentStepText, CurrentStepText, `n, `r`n, All
1229 GuiControl, %GuiA%:, Edit1, %CurrentStepText%
1230 If %CurrentStep%_q
1231 While (%@%_Level > %CurrentStep%_Level) or !%@%_q
1232 @ := CurrentStep + A_Index
1233 Menu, %A_ThisFunc%MenuFile, Rename, %MenuFileEdit%%LastLine%, ----
1234 Menu, %A_ThisFunc%MenuFile, Rename, ----, % MenuFileEdit LastLine := A_Space %CurrentStep%_l
1235 Menu, %A_ThisFunc%MenuFile, % %CurrentStep%_l ? "Enable" : "Disable", %MenuFileEdit%%LastLine%
1236 ControlSetText, Edit2, % "Time (ms): " (%CurrentStep%_q ? Round((%@%_q - %CurrentStep%_q) * QPC_Rate, 3) : "") "`r`nLine No.: " %CurrentStep%_l, ahk_id %GuiHWND%
1237 Gui, %GuiB%:Destroy
1238 If (%CurrentStep%_g <> "") and ShowGraphics {
1239 @ := CurrentStep, @1 := Asc(%CurrentStep%_g) = 43 ? 1 : Asc(%CurrentStep%_g) = 45 ? -1 : 0
1240 If @1
1241 While !RegExMatch(%@%_Title, "is)^" SubStr(%CurrentStep%_g, 2) "$") and @ and (@ <= Items)
1242 @ += @1
1243 If (%@%_g <> "")
1244 %A_ThisFunc%(">NewGui<", GuiB ";+ToolWindow -SysMenu -Caption +AlwaysOnTop +E0x20;" %@%_g)
1245 Else
1246 MsgBox, 262160, %A_ScriptName%: Error, Error with referenced graphics!!!! Fix me ben! ; xxx
1247 }
1248 TempGuiCommand := GuiCommand, TV_Modify(%CurrentStep%_ID)
1249 }
1250 If RightClick
1251 Menu, %A_ThisFunc%MenuContext, Show
1252 If (GuiCommand = "") {
1253 WinSetTitle, ahk_id %GuiHWND%, , % GuiTitle := A_ThisFunc " Debugger" (Playing ? " - " PlayingText : "") ": " CurrentStep " - " %CurrentStep%_Title
1254 WinWaitClose, %GuiTitle% ahk_id %GuiHWND%, , Playing ? ((%CurrentStep%_d ? %CurrentStep%_d : 1) * PlaySpeed) : ""
1255 }
1256 }
1257 } Else If (GuiHWND = "") { ;--------------------------------------------------Screenshot Builder--------------------------------------------------
1258 CoordMode, Mouse, Screen
1259 CoordMode, Pixel, Screen
1260 CoordMode, Menu, Screen
1261 ;||||||||||||||||||||||||||||||||||| Screenshot Builder Settings ||||||||||||||||||||||||||||||||||||
1262 ;----------------------------------------- General Settings -----------------------------------------
1263 TempFile = %A_Temp%\%A_ThisFunc%Temp.png ; Directory where a temporary imagefile will be created (ImageSearch only accepts an imagefile as input)
1264 NewFilePlaceHolder = NewFile ; The filename that will populate the field if none is provided. Omit the extension unless %DefaultExts% has also been omitted
1265 PauseHotkey = `` ; Hotkey that pauses updating of the screen magnifier, allowing you to select a screenshot region and add options
1266 SquareSize = 19 ; Width and height of each magnifier color square, in pixels
1267 SquaresWide = 22 ; Width in color squares of the magnifier. Also signifies the width of the region to be magnified, in pixels
1268 SquaresHigh = 18 ; Same as above for height
1269 SquareSpacing = 2 ; Spacing between the color squares, in pixels
1270 ControlHeight = 20 ; Height of GUI elements, in pixels
1271 Margins = 10 ; Spacing between gui controls, in pixels
1272 FontSize = 10 ; Font size, in points
1273 FontFace = Segoe UI ; Name of the font used for textual gui elements
1274 SelectionColor = 0xFF0000 ; Color of the screenshot region selection rectangle
1275 CurRegionColor = 0x0000FF ; Color of the box that indicates what part of the screen is currently being magnified
1276 CurRegionThickness = 3 ; Thickness of this box, in pixels
1277 GuiX = ; X-coordinate where the dialog is shown (leave blank for center of screen)
1278 GuiY = ; Y-coordinate where the dialog is shown (leave blank for center of screen)
1279 DoubleTapToSelect = %True% ; Normally, selecting a screenshot region is done by clicking & dragging. Indicating %True% here means you must instead click to begin selection and then click again to stop. Leave as %False% unless this behavior gives issues
1280 PromptOnOverwrite = %True% ; If the output file already exists, it will be overwritten without asking
1281 RecycleOnOverwrite = %False% ; When overwriting an output file, the existing file will be recycled instead of deleted permanently
1282 AutoJumpToFileName = %True% ; Will send focus to the filename portion of the output file field upon unpause or change of file name
1283 InputBoxWidth = 300 ; Width of the dialog box used for adding new options
1284 StartPaused = %False% ; Magnifier will start paused when the gui is created
1285 AllowOffset = %False% ; True to have this checkbox cleared by default
1286 DiagnosticMode = %True% ; True to have this checkbox cleared by default
1287 DiagnosticModeOptions = Playing=0 ; Diagnostic Mode options that will be applied when you press the test button with the diagnostic mode box checked. Analogous to appending "dx<options>" to the test options field
1288 CopyToClipboard = %False% ; True to have this checkbox cleared by default
1289 ;----------------------------------------- Gui Text Elements ----------------------------------------
1290 ; Edit the variables below to change the text of the buttons and other elements in the image creator GUI. This can be done to change the language of the interface, or to change the accelerator keys (using the "&" symbol).
1291 CheckboxOffset = Allow O&ffset
1292 ButtonPause = &Pause ( %PauseHotkey% )
1293 ButtonUnPause = Un&pause ( %PauseHotkey% )
1294 ButtonTest = &Test
1295 ButtonSave = &Save
1296 ButtonBrowse = &Browse
1297 ButtonOther = &Other
1298 ButtonCancel = &Cancel
1299 ButtonAddOption = &Add option...
1300 ButtonJumpToFileName = &I
1301 CheckboxCopyToClipboard = Copy code to c&lipboard
1302 CheckboxDiagnosticMode = &Use diagnostic mode:
1303 ButtonInputBoxAdd = &Add
1304 ButtonInputBoxCancel = &Cancel
1305 ButtonInputBoxHelp = &Help
1306 ;||||||||||||||||||||||||||||||||||||||||||| End Settings |||||||||||||||||||||||||||||||||||||||||||
1307 CenterX := SquaresWide // 2, CenterY := SquaresHigh // 2, OffsetX := 0, OffsetY := 0, Cache := ">2" Cache, OptionInfo := SubStr(%A_ThisFunc%(A_Space), 2), WinDelay := A_WinDelay
1308 Loop, Parse, OptionInfo, `r
1309 {
1310 Loop, Parse, A_LoopField, `n
1311 {
1312 StringSplit, @, A_LoopField, %A_Tab%
1313 If (A_Index = 1)
1314 Item := @1, @1 := "Main"
1315 If (@2 <> "")
1316 StringReplace, @, @1, %A_Space%, , All
1317 OptionInfo_%Item%_%@% .= @2 = "" ? "`n`n" @1 : @2, @2 := ""
1318 }
1319 Menu, %A_ThisFunc%OptionInfo, Add, % Item A_Tab OptionInfo_%Item%_Main, %A_ThisFunc%Menu
1320 }
1321 OptionInfo := GuiTitle := "", LastPos := "x-300 y-300 w10 h10"
1322 Loop {
1323 If (FilePaths = "") {
1324 StringReplace, ImageFile, ImageFile, >, , UseErrorLevel
1325 AbsolutePath := (ErrorLevel - 1) * (ImageFile <> "")
1326 SplitPath, ImageFile, , @1, @2, @3, @4
1327 If (@2 <> "")
1328 @2 := "." @2
1329 Else If (DefaultExts <> "")
1330 @2 := "." SubStr(DefaultExts, 1, InStr(DefaultExts, "|") - 1)
1331 If (@3 = "")
1332 @3 := NewFilePlaceHolder
1333 FilePaths := "|" (@4 = "" ? "" : @1 "\" @3 @2 "|")
1334 If !AbsolutePath or (@4 = "")
1335 FilePaths .= RegExReplace(DefaultDirs, "\\?(\||$)", (@4 = "" ? "\" @1 : "") "\" @3 @2 "$1")
1336 While InStr(FilePaths, "\\")
1337 StringReplace, FilePaths, FilePaths, \\, \, All
1338 StringReplace, FilePaths, FilePaths, |\, |\\, All
1339 FilePaths := RegExReplace(FilePaths, "\\\K[^\\|]+\\\.\.\\") "|", Destination := SubStr(FilePaths, 2, InStr(FilePaths, "|", 0, 2) - 2)
1340 }
1341 StringReplace, TempFilePaths, FilePaths, |%Destination%|, |, All
1342 GuiCommand := A_Index <> 1 or StartPaused ? ButtonPause : ButtonUnpause
1343 , LastItem := 1
1344 , VarSetCapacity(GuiHWND, 18000)
1345 , GuiHWND := GuiA . ";+AlwaysOnTop +Label" A_ThisFunc . ";Add,Progress,-0x20000 " LastPos " c" SelectionColor ",100;"
1346 While (SquaresHigh >= @ := A_Index)
1347 Loop % SquaresWide
1348 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;"
1349 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
1350 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 * 5 ",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:"
1351 Hotkey, IfWinExist, ahk_id %GuiHWND%
1352 Hotkey, ~LButton, %A_ThisFunc%Close, On
1353 Hotkey, %PauseHotkey%, %A_ThisFunc%Close, On
1354 Hotkey, IfWinExist
1355 Loop {
1356 TempGuiCommand := GuiCommand, GuiCommand := ""
1357 If (TempGuiCommand = "ErrorLevel") {
1358 GuiControlGet, @, %GuiA%:FocusV
1359 If (@ = "ErrorLevel") {
1360 ControlGetText, Destination, ComboBox1, ahk_id %GuiHWND%
1361 If AutoJumpToFileName and !AbsolutePath {
1362 GuiControlGet, ThisItem, %GuiA%:, ErrorLevel
1363 If (ThisItem < 100) and (ThisItem <> LastItem)
1364 GuiCommand := ButtonJumpToFileName, LastItem := ThisItem
1365 }
1366 } Else
1367 GuiControl, %GuiA%:Focus, ErrorLevel
1368 } Else If (TempGuiCommand = PauseHotkey) or (TempGuiCommand = ButtonUnpause) or (TempGuiCommand = ButtonPause) {
1369 If (TempGuiCommand <> ButtonPause) {
1370 Gui, %GuiA%:Show, % "NA h" Margins * 4 + 1 + ControlHeight * 2 + (SquareSize + SquareSpacing) * SquaresHigh - SquareSpacing
1371 ControlSetText, Button2, %ButtonPause%, ahk_id %GuiHWND%
1372 GuiControl, %GuiA%:, Edit2
1373 WinSet, AlwaysOnTop, On, ahk_id %GuiHWND%
1374 If (A_Index <> 1) {
1375 ControlGet, AllowOffset, Checked, , Button1, ahk_id %GuiHWND%
1376 If AllowOffset and (MouseX <> "") {
1377 MouseGetPos, MouseX2, MouseY2
1378 OffsetX := MouseX2 - MouseX, OffsetY := MouseY2 - MouseY
1379 } Else
1380 OffsetX := 0, OffsetY := 0
1381 ControlSetText, Button1, % CheckboxOffset " (" (OffsetX < 0 ? "+" : "") 0 - OffsetX ", " (OffsetY < 0 ? "+" : "") 0 - OffsetY ")", ahk_id %GuiHWND%
1382 }
1383 If !WinExist("ahk_id " BoxHWND)
1384 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)
1385 If A_PtrSize ; Start GDI+
1386 Ptr := "UPtr", PtrA := "UPtr*"
1387 Else
1388 Ptr := "UInt", PtrA := "UInt*"
1389 If !DllCall("GetModuleHandle", "str", "gdiplus", Ptr)
1390 DllCall("LoadLibrary", "str", "gdiplus")
1391 VarSetCapacity(si, A_PtrSize = 8 ? 24 : 16, 0), si := Chr(1), DllCall("gdiplus\GdiplusStartup", PtrA, pToken, Ptr, &si, Ptr, 0)
1392 GuiCommand := "~LButton"
1393 While (GuiCommand = "~LButton") {
1394 MouseGetPos, MouseX, MouseY
1395 MouseX -= OffsetX, MouseY -= OffsetY
1396 Gui, %GuiB%:Show, % "NA x" MouseX - CenterX - CurRegionThickness " y" MouseY - CenterY - CurRegionThickness
1397 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) ; Gdip_BitmapFromScreen
1398 If !chdc
1399 DllCall("ReleaseDC", Ptr, False, Ptr, hdc2)
1400 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)
1401 While (SquaresHigh >= @ := A_Index)
1402 Loop %SquaresWide% {
1403 SetFormat, Integer, Hex
1404 DllCall("gdiplus\GdipBitmapGetPixel", Ptr, pBitmap, "int", CenterX + A_Index - Floor(SquaresWide / 2) - 1, "int", CenterY + @ - Floor(SquaresHigh / 2) - 1, "uint*", Color), Color := Color & 0x00ffffff ; Gdip_GetPixel
1405 SetFormat, Integer, Decimal
1406 GuiControl, % GuiA ":+c" SubStr(Color_%A_Index%_%@% := Color, 3), % "msctls_progress32" 1 + (@ - 1) * SquaresWide + A_Index
1407 }
1408 ControlSetText, Edit3, %MouseX% `, %MouseY%, ahk_id %GuiHWND%
1409 DllCall("gdiplus\GdipDisposeImage", Ptr, pBitmap) ; Dispose Image
1410 }
1411 WinSet, AlwaysOnTop, Off, ahk_id %GuiHWND%
1412 MouseGetPos, OffsetX, OffsetY
1413 OffsetX -= MouseX, OffsetY -= MouseY
1414 DllCall("gdiplus\GdiplusShutdown", Ptr, pToken) ; Shutdown
1415 If (hModule := DllCall("GetModuleHandle", "str", "gdiplus", Ptr))
1416 DllCall("FreeLibrary", Ptr, hModule)
1417 } ; End GDI+
1418 Gui, %GuiA%:Show, % "h" Margins * 17 + 1 + ControlHeight * 5 + (SquareSize + SquareSpacing) * SquaresHigh - SquareSpacing
1419 ControlSetText, Button2, %ButtonUnpause%, ahk_id %GuiHWND%
1420 GuiCommand := GuiCommand = "Normal" ? "Normal" : !AbsolutePath and AutoJumpToFileName ? ButtonJumpToFileName : "ErrorLevel"
1421 } Else If (TempGuiCommand = ButtonAddOption) {
1422 WinGetPos, @1, @2, , @3, ahk_id %OptionsHWND%
1423 Menu, %A_ThisFunc%OptionInfo, Show, % @1 + 1, % @2 + @3 - 1
1424 } Else If (TempGuiCommand = ButtonJumpToFileName) {
1425 SplitPath, Destination, , @1, , @2
1426 ControlFocus, ComboBox1, ahk_id %GuiHWND%
1427 SendMessage, 0xB1, StrLen(@1) + 1, StrLen(@1 @2) + 1, Edit6, ahk_id %GuiHWND%
1428 } Else If (TempGuiCommand = ButtonBrowse) {
1429 ControlGetText, FilePaths, ComboBox1, ahk_id %GuiHWND%
1430 Gui, %GuiA%:+OwnDialogs
1431 FileSelectFile, Destination, , %FilePaths%, , % "Screenshot Files (" SubStr(RegExReplace(DefaultExts, "(?:\||^)\.?(\w+)", "*.$1;"), 1, -1) ")"
1432 If !ErrorLevel
1433 ControlSetText, Edit6, % Destination .= InStr(Destination, ".", 0, InStr("\" Destination, "\", 0, 0)) ? "" : SubStr(DefaultExts, 1, InStr(DefaultExts, "|") - 1), ahk_id %GuiHWND%
1434 Gui, %GuiA%:-OwnDialogs
1435 GuiCommand := AutoJumpToFileName ? ButtonJumpToFileName : "ErrorLevel"
1436 } Else If (TempGuiCommand = ButtonOther) {
1437 WinGetPos, GuiX, GuiY, , , ahk_id %GuiHWND%
1438 ImageFile := ">" ImageFile, GuiHWND := FilePaths := ""
1439 Break
1440 } Else If (TempGuiCommand = CheckboxDiagnosticMode) {
1441 ControlGet, DiagnosticMode, Checked, , Button5, ahk_id %GuiHWND%
1442 GuiControl, % GuiA ":" (DiagnosticMode ? "-" : "+") "ReadOnly", Edit5
1443 } Else If (TempGuiCommand = A_ThisFunc "OptionInfo") {
1444 @ := SubStr(A_ThisMenuItem, 1, InStr(A_ThisMenuItem, A_Tab) - 1)
1445 Gui, %GuiA%:+Disabled
1446 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)
1447 Gui, %GuiA%:-Disabled
1448 TempGuiCommand := GuiCommand, GuiCommand := ""
1449 If (InStr(TempGuiCommand, ButtonInputBoxAdd) = 1) {
1450 NewOption := SubStr(TempGuiCommand, InStr(TempGuiCommand, "`n") + 1)
1451 If InStr(NewOption, A_Space) or InStr(NewOption, Literal) {
1452 StringReplace, NewOption, NewOption, %Literal%, %Literal%%Literal%, All
1453 NewOption := Literal NewOption Literal
1454 }
1455 ControlGetText, Options, Edit4, ahk_id %GuiHWND%
1456 ControlSetText, Edit4, % (Options .= SubStr(A_Space Options, 0) = A_Space ? "" : A_Space) @ NewOption, ahk_id %GuiHWND%
1457 ControlFocus, Edit4, ahk_id %GuiHWND%
1458 SendMessage, 0xB1, @1 := StrLen(Options), @2 := @1 + StrLen(@ NewOption), Edit4, ahk_id %GuiHWND%
1459 Sleep 200
1460 SendMessage, 0xB1, @1 + StrLen(@), @2, Edit4, ahk_id %GuiHWND%
1461 } Else If (InStr(TempGuiCommand, ButtonInputBoxHelp) = 1)
1462 Run, %ForumURL%
1463 ;~ GuiCommand := "ErrorLevel"
1464 } Else If InStr(TempGuiCommand, "LButton") {
1465 MouseGetPos, , , MouseWin, MouseControl1
1466 If (MouseWin = GuiHWND)
1467 If (InStr(MouseControl1, "msctls_progress32") = 1) and (MouseControl1 <> "msctls_progress321") {
1468 GuiControlGet, Con1, %GuiA%:Pos, %MouseControl1%
1469 While (!DoubleTapToSelect and GetKeyState("LButton", "P")) or (DoubleTapToSelect and (GuiCommand = "")) {
1470 MouseGetPos, , , MouseWin, MouseControl
1471 If (MouseControl <> MouseControl2) and (InStr(MouseControl, "msctls_progress32") = 1) and (MouseControl <> "msctls_progress321") {
1472 GuiControlGet, Con2, %GuiA%:Pos, % MouseControl2 := MouseControl
1473 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
1474 GuiControl, %GuiA%:, Edit1, % Round((Abs(Con2X - Con1X) + SquareSize + SquareSpacing) / (SquareSize + SquareSpacing)) "x" Round((Abs(Con2Y - Con1Y) + SquareSize + SquareSpacing) / (SquareSize + SquareSpacing))
1475 @1 := Round((Con2X + SquareSize - Margins + SquareSpacing) / (SquareSize + SquareSpacing)), @2 := Round((Con2Y + SquareSize - Margins + SquareSpacing) / (SquareSize + SquareSpacing))
1476 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)
1477 }
1478 Sleep 10
1479 }
1480 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 := ""
1481 } Else If (MouseControl1 = "") or (MouseControl1 = "Button3") or (MouseControl1 = "Button7") or (InStr(MouseControl1, "Static") = 1) {
1482 WinGetPos, WinX, WinY, , , ahk_id %GuiHWND%
1483 MouseGetPos, MouseX1, MouseY1
1484 While GetKeyState("LButton", "P") {
1485 MouseGetPos, MouseX2, MouseY2
1486 WinMove, ahk_id %GuiHWND%, , WinX + MouseX2 - MouseX1, WinY + MouseY2 - MouseY1
1487 }
1488 }
1489 } Else {
1490 If (TempGuiCommand = ButtonSave) or (TempGuiCommand = ButtonTest) {
1491 Gui, %GuiA%:+OwnDialogs
1492 If (TempGuiCommand = ButtonTest) {
1493 OutputFile := TempFile
1494 ControlGet, DiagnosticMode, Checked, , Button5, ahk_id %GuiHWND%
1495 ControlGetText, DiagnosticModeOptions, Edit5, ahk_id %GuiHWND%
1496 WinGetPos, GuiX, GuiY, , , ahk_id %GuiHWND%
1497 } Else
1498 OutputFile := Destination
1499 SplitPath, OutputFile, , , Extension, Name
1500 If (Extension <> "")
1501 StringTrimRight, OutputFile, OutputFile, StrLen(Extension) + 1
1502 If Extension Not In bmp,dib,rle,jpg,jpeg,jpe,jfif,gif,tif,tiff,png
1503 {
1504 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." : "")
1505 IfMsgBox YES
1506 Extension := "png"
1507 Else
1508 TempGuiCommand := GuiCommand := "ErrorLevel"
1509 }
1510 If (TempGuiCommand = ButtonSave) {
1511 If InStr(@ := FileExist(OutputFile "." Extension), "D") {
1512 MsgBox, 262160, %A_ScriptName%: Error, Please enter a file name.
1513 GuiCommand := "ErrorLevel"
1514 } Else If (@ <> "") {
1515 If PromptOnOverWrite {
1516 MsgBox, 262148, %A_ScriptName%: Input Required, File "%OutputFile%.%Extension%" already exists. Overwrite it?
1517 IfMsgBox No
1518 TempGuiCommand := GuiCommand := "ErrorLevel"
1519 }
1520 If (GuiCommand <> "ErrorLevel")
1521 If RecycleOnOverWrite
1522 FileRecycle, %OutputFile%.%Extension%
1523 Else
1524 FileDelete, %OutputFile%.%Extension%
1525 }
1526 } Else If (TempGuiCommand = ButtonTest)
1527 FileDelete, %OutputFile%.%Extension%
1528 ControlGetText, Options, Edit4, ahk_id %GuiHWND%
1529 ControlGet, CopyToClipboard, Checked, , Button9, ahk_id %GuiHWND%
1530 }
1531 If (GuiCommand <> "ErrorLevel") {
1532 Gui, %GuiA%:Destroy
1533 Gui, %GuiB%:Destroy
1534 Hotkey, IfWinExist, ahk_id %GuiHWND%
1535 Hotkey, ~LButton, Off
1536 Hotkey, %PauseHotkey%, Off
1537 Hotkey, IfWinExist
1538 SetWinDelay, %WinDelay%
1539 } Else
1540 Gui, %GuiA%:-OwnDialogs
1541 If (TempGuiCommand = ButtonSave) or (TempGuiCommand = ButtonTest) {
1542 If (X1 = "")
1543 X1 := 1, Y1 := 1, X2 := SquaresWide, Y2 := SquaresHigh
1544 VarSetCapacity(Colors, (X2 - X1 + 1) * (Y2 - Y1 + 1) * 7) ; Width := X2 - X1 + 1, Height := Y2 - Y1 + 1
1545 While (Y2 >= IndexY := A_Index + Y1 - 1)
1546 While (X2 >= IndexX := A_Index + X1 - 1)
1547 Colors .= "|" SubStr(Color_%IndexX%_%IndexY%, 3)
1548 %A_ThisFunc%(">MakeImage<", "" OutputFile "|" Extension "|" X2 - X1 + 1 "|" Y2 - Y1 + 1 Colors)
1549 }
1550 If (TempGuiCommand = ButtonTest) {
1551 %A_ThisFunc%(OutputFile "." Extension, Options (DiagnosticMode ? (SubStr(A_Space Options, 0) = A_Space ? "" : A_Space) "dx" DiagnosticModeOptions : ""))
1552 FileDelete, %OutputFile%.%Extension%
1553 %A_ThisFunc%(">ParseCache<", OutputFile "." Extension), LastImageFile := ""
1554 Break
1555 } Else If (GuiCommand <> "ErrorLevel") {
1556 GuiHWND := ""
1557 If (TempGuiCommand = ButtonSave) {
1558 FileCreateDir, % SubStr(OutputFile, 1, InStr(OutputFile, "\", 0, 0))
1559 Cache := Name A_Tab OutputFile "." Extension A_Tab X2 - X1 + 1 "|" Y2 - Y1 + 1 "||`n" Cache, FoundX := OutputFile "." Extension, FoundY := Options
1560 If CopyToClipboard {
1561 DefaultDirs := SubStr(RegExReplace(DefaultDirs "|", "\\*(?:\||^)+", "\|"), 3, -1), DefaultExts := SubStr(RegExReplace("|" DefaultExts "|", "\|\.*", "|."), 2, -2), OutputFile := "|" OutputFile "|"
1562 Loop, Parse, DefaultDirs, |
1563 StringReplace, OutputFile, OutputFile, |%A_LoopField%
1564 Loop, Parse, DefaultExts, |
1565 StringReplace, OutputFile, OutputFile, %A_LoopField%|
1566 StringReplace, OutputFile, OutputFile, |, , All
1567 StringReplace, Options, Options, ", "", All ;"
1568 Clipboard := A_ThisFunc "(""" OutputFile """" (Options = "" ? "" : ", """ Options """") ")"
1569 }
1570 Return True
1571 }
1572 Return False
1573 }
1574 }
1575 If (GuiCommand = "") {
1576 WinSetTitle, ahk_id %GuiHWND%, , % GuiTitle := A_ThisFunc " Screenshot Creator: Paused"
1577 WinWaitClose, %GuiTitle% ahk_id %GuiHWND%
1578 }
1579 }
1580 }
1581 } Else
1582 MsgBox, 262160, %A_ScriptName% - %A_ThisFunc%(): Error, The image creator is already running.`n`nPlease finish the current task before continuing.
1583 Return
1584 FindClickMenu:
1585 FindClickClose:
1586 FindClickEscape:
1587 Return FindClick(">GuiEvent<")
1588}
1589
1590#NoEnv
1591#MaxHotkeysPerInterval 99000000
1592#HotkeyInterval 99000000
1593#KeyHistory 0
1594SetBatchLines, -1
1595Process, Priority,, High
1596
1597;--------------------------------- Function included in your script ---------------------------------
1598
1599F2::
1600Suspend
1601
1602Pause,,1
1603
1604return
1605
1606$F1::
1607FindClick("C:\Users\kingLIGHT\Desktop\giveitem.png", "k{LButton}")
1608Click 3
1609Return