PageRenderTime 60ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/MiscFunctions.ahk

http://7plus.googlecode.com/
AutoHotKey | 1982 lines | 1583 code | 138 blank | 261 comment | 252 complexity | 24a07046b0c280babd51b8a14b0415d3 MD5 | raw file
Possible License(s): AGPL-1.0, LGPL-2.0
  1. ;This file contains various functions for all kinds of things. YAY!
  2. #include *i %A_ScriptDir%\lib\Array.ahk
  3. ;Gets a localized string from a resource file.
  4. ;usage example:
  5. ;x := TranslateMUI("shell32.dll",31236)
  6. TranslateMUI(resDll, resID)
  7. {
  8. VarSetCapacity(buf, 256)
  9. hDll := DllCall("LoadLibrary", "str", resDll, "Ptr")
  10. Result := DllCall("LoadString", "Ptr", hDll, "uint", resID, "str", buf, "int", 128)
  11. return buf
  12. }
  13. ;Finds the path of the Shell32.dll.mui file
  14. LocateShell32MUI()
  15. {
  16. VarSetCapacity(buffer, 85*2)
  17. length:=DllCall("GetUserDefaultLocaleName","UIntP",buffer,"UInt",85)
  18. if(A_IsUnicode)
  19. locale := StrGet(buffer)
  20. shell32MUIpath:=A_WinDir "\winsxs\*_microsoft-windows-*resources*" locale "*" ;\x86_microsoft-windows-shell32.resources_31bf3856ad364e35_6.1.7600.16385_de-de_b08f46c44b512da0\shell32.dll.mui
  21. loop %shell32MUIpath%,2,0
  22. if(FileExist(A_LoopFileFullPath "\shell32.dll.mui"))
  23. return A_LoopFileFullPath "\shell32.dll.mui"
  24. }
  25. ;Splits a command into command and arguments
  26. SplitCommand(fullcmd, ByRef cmd, ByRef args)
  27. {
  28. if(InStr(fullcmd, """") = 1)
  29. {
  30. pos := InStr(fullcmd, """" , 0, 2)
  31. cmd := SubStr(fullcmd, 2,pos - 2)
  32. args := SubStr(fullcmd, pos + 1)
  33. args := strTrim(args, " ")
  34. }
  35. else if(pos:=InStr(fullcmd, " " , 0, 1))
  36. {
  37. cmd := SubStr(fullcmd, 1, pos-1)
  38. args := SubStr(fullcmd, pos+1)
  39. args := strTrim(args, " ")
  40. }
  41. else
  42. {
  43. cmd := fullcmd
  44. args := ""
  45. }
  46. }
  47. ;Gets a free gui number.
  48. /* Group: About
  49. o v0.81 by majkinetor.
  50. o Licenced under BSD <http://creativecommons.org/licenses/BSD/>
  51. */
  52. GetFreeGuiNum(start, prefix = ""){
  53. loop
  54. {
  55. Gui %prefix%%start%:+LastFoundExist
  56. IfWinNotExist
  57. return prefix start
  58. start++
  59. if(start = 100)
  60. return 0
  61. }
  62. return 0
  63. }
  64. ;Checks if a specific window is under the cursor.
  65. IsWindowUnderCursor(hwnd)
  66. {
  67. MouseGetPos, , , win
  68. if hwnd is number
  69. return win = hwnd
  70. else
  71. return InStr(WinGetClass("ahk_class " win), hwnd)
  72. }
  73. ;Checks if a specific control is under the cursor and returns its ClassNN if it is.
  74. IsControlUnderCursor(ControlClass)
  75. {
  76. MouseGetPos, , , , control
  77. if(InStr(Control, ControlClass))
  78. return control
  79. return false
  80. }
  81. ;Sets window event hook
  82. API_SetWinEventHook(eventMin, eventMax, hmodWinEventProc, lpfnWinEventProc, idProcess, idThread, dwFlags) {
  83. return DllCall("SetWinEventHook", "uint", eventMin, "uint", eventMax, "Ptr", hmodWinEventProc, "uint", lpfnWinEventProc, "uint", idProcess, "uint", idThread, "uint", dwFlags, "Ptr")
  84. }
  85. ;Unhooks window event hook
  86. API_UnhookWinEvent( hWinEventHook ) {
  87. return DllCall("UnhookWinEvent", "Ptr", hWinEventHook)
  88. }
  89. ;disables or restores original minimize anim setting
  90. DisableMinimizeAnim(disable)
  91. {
  92. static original,lastcall
  93. if(disable && !lastcall) ;Backup original value if disabled is called the first time after a restore call
  94. {
  95. lastcall:=1
  96. RegRead, original, HKCU, Control Panel\Desktop\WindowMetrics , MinAnimate
  97. }
  98. else if(!disable) ;this is a restore call, on next disable backup may be created again
  99. lastcall:=0
  100. ;Disable Minimize/Restore animation
  101. VarSetCapacity(struct, 8, 0)
  102. NumPut(8, struct, 0, "UInt")
  103. if(disable || !original)
  104. NumPut(0, struct, 4, "Int")
  105. else
  106. NumPut(1, struct, 4, "UInt")
  107. DllCall("SystemParametersInfo", "UINT", 0x0049,"UINT", 8,"Ptr", &struct,"UINT", 0x0003) ;SPI_SETANIMATION 0x0049 SPIF_SENDWININICHANGE 0x0002
  108. }
  109. /*
  110. Performs a hittest on the window under the mouse and returns the WM_NCHITTEST Result
  111. #define HTERROR (-2)
  112. #define HTTRANSPARENT (-1)
  113. #define HTNOWHERE 0
  114. #define HTCLIENT 1
  115. #define HTCAPTION 2
  116. #define HTSYSMENU 3
  117. #define HTGROWBOX 4
  118. #define HTSIZE HTGROWBOX
  119. #define HTMENU 5
  120. #define HTHSCROLL 6
  121. #define HTVSCROLL 7
  122. #define HTMINBUTTON 8
  123. #define HTMAXBUTTON 9
  124. #define HTLEFT 10
  125. #define HTRIGHT 11
  126. #define HTTOP 12
  127. #define HTTOPLEFT 13
  128. #define HTTOPRIGHT 14
  129. #define HTBOTTOM 15
  130. #define HTBOTTOMLEFT 16
  131. #define HTBOTTOMRIGHT 17
  132. #define HTBORDER 18
  133. #define HTREDUCE HTMINBUTTON
  134. #define HTZOOM HTMAXBUTTON
  135. #define HTSIZEFIRST HTLEFT
  136. #define HTSIZELAST HTBOTTOMRIGHT
  137. #if(WINVER >= 0x0400)
  138. #define HTOBJECT 19
  139. #define HTCLOSE 20
  140. #define HTHELP 21
  141. */
  142. MouseHitTest()
  143. {
  144. CoordMode, Mouse, Screen
  145. MouseGetPos, MouseX, MouseY, WindowUnderMouseID
  146. WinGetClass, winclass , ahk_id %WindowUnderMouseID%
  147. if winclass in BaseBar,D2VControlHost,Shell_TrayWnd,WorkerW,ProgMan ; make sure we're not doing this on the taskbar
  148. return -2
  149. ; WM_NCHITTEST
  150. SendMessage, 0x84,, ( (MouseY&0xFFFF) << 16 )|(MouseX&0xFFFF),, ahk_id %WindowUnderMouseID%
  151. return ErrorLevel
  152. }
  153. ;Returns true if there is an available internet connection
  154. IsConnected(URL="http://code.google.com/p/7plus/")
  155. {
  156. return DllCall("Wininet.dll\InternetCheckConnection", "Str", URL,"UInt", 1, "UInt",0, "UInt")
  157. }
  158. /*! TheGood (modified a bit by Fragman)
  159. Checks if a window is in fullscreen mode.
  160. ______________________________________________________________________________________________________________
  161. sWinTitle - WinTitle of the window to check. Same syntax as the WinTitle parameter of, e.g., WinExist().
  162. bRefreshRes - Forces a refresh of monitor data (necessary if resolution has changed)
  163. UseExcludeList - returns false if window class is in FullScreenExclude (explorer, browser etc)
  164. UseIncludeList - returns true if window class is in FullScreenInclude (applications capturing gamepad input)
  165. Return value o If window is fullscreen, returns the index of the monitor on which the window is fullscreen.
  166. o If window is not fullscreen, returns False.
  167. ErrorLevel - Sets ErrorLevel to True if no window could match sWinTitle
  168. Based on the information found at http://support.microsoft.com/kb/179363/ which discusses under what
  169. circumstances does a program cover the taskbar. Even if the window passed to IsFullscreen is not the
  170. foreground application, IsFullscreen will check if, were it the foreground, it would cover the taskbar.
  171. */
  172. IsFullscreen(sWinTitle = "A", UseExcludeList = true, UseIncludeList=true) {
  173. Static
  174. Local iWinX, iWinY, iWinW, iWinH, iCltX, iCltY, iCltW, iCltH, iMidX, iMidY, iMonitor, c, D, iBestD
  175. ErrorLevel := False
  176. ;Without admin mode processes launched with admin permissions aren't detectable, so better treat all windows as non-fullscreen.
  177. if(!A_IsAdmin)
  178. return false
  179. ;Get the active window's dimension
  180. hWin := WinExist(sWinTitle)
  181. If Not hWin {
  182. ErrorLevel := True
  183. Return False
  184. }
  185. ;Make sure it's not desktop
  186. WinGetClass, c, ahk_id %hWin%
  187. If (hWin = DllCall("GetDesktopWindow", "Ptr") Or (c = "Progman") Or (c = "WorkerW"))
  188. Return False
  189. ;Fullscreen include list
  190. if(UseIncludeList)
  191. {
  192. FullscreenInclude := Settings.Misc.FullScreenInclude
  193. if c in %FullscreenInclude%
  194. return true
  195. }
  196. ;Fullscreen exclude list
  197. if(UseExcludeList)
  198. {
  199. FullscreenExclude := Settings.Misc.FullScreenExclude
  200. if c in %FullscreenExclude%
  201. return false
  202. }
  203. ;Resolution change would only need to be detected every few seconds or so, but since it doesn't add anything notably to cpu usage, just do it always
  204. SysGet, Mon0, MonitorCount
  205. SysGet, iPrimaryMon, MonitorPrimary
  206. Loop %Mon0% { ;Loop through each monitor
  207. SysGet, Mon%A_Index%, Monitor, %A_Index%
  208. Mon%A_Index%MidX := Mon%A_Index%Left + Ceil((Mon%A_Index%Right - Mon%A_Index%Left) / 2)
  209. Mon%A_Index%MidY := Mon%A_Index%Top + Ceil((Mon%A_Index%Top - Mon%A_Index%Bottom) / 2)
  210. }
  211. ;Get the window and client area, and style
  212. VarSetCapacity(iWinRect, 16), VarSetCapacity(iCltRect, 16)
  213. DllCall("GetWindowRect", "Ptr", hWin, "Ptr", &iWinRect)
  214. DllCall("GetClientRect", "Ptr", hWin, "Ptr", &iCltRect)
  215. WinGet, iStyle, Style, ahk_id %hWin%
  216. ;Extract coords and sizes
  217. iWinX := NumGet(iWinRect, 0), iWinY := NumGet(iWinRect, 4)
  218. iWinW := NumGet(iWinRect, 8) - NumGet(iWinRect, 0) ;Bottom-right coordinates are exclusive
  219. iWinH := NumGet(iWinRect, 12) - NumGet(iWinRect, 4) ;Bottom-right coordinates are exclusive
  220. iCltX := 0, iCltY := 0 ;Client upper-left always (0,0)
  221. iCltW := NumGet(iCltRect, 8), iCltH := NumGet(iCltRect, 12)
  222. ; outputdebug iCltW %iCltW% iCltH %iCltH%
  223. ;Check in which monitor it lies
  224. iMidX := iWinX + Ceil(iWinW / 2)
  225. iMidY := iWinY + Ceil(iWinH / 2)
  226. ;Loop through every monitor and calculate the distance to each monitor
  227. iBestD := 0xFFFFFFFF
  228. Loop % Mon0 {
  229. D := Sqrt((iMidX - Mon%A_Index%MidX)**2 + (iMidY - Mon%A_Index%MidY)**2)
  230. If (D < iBestD) {
  231. iBestD := D
  232. iMonitor := A_Index
  233. }
  234. }
  235. ;Check if the client area covers the whole screen
  236. bCovers := (iCltX <= Mon%iMonitor%Left) And (iCltY <= Mon%iMonitor%Top) And (iCltW >= Mon%iMonitor%Right - Mon%iMonitor%Left) And (iCltH >= Mon%iMonitor%Bottom - Mon%iMonitor%Top)
  237. If(bCovers)
  238. Return True
  239. ;Check if the window area covers the whole screen and styles
  240. bCovers := (iWinX <= Mon%iMonitor%Left) And (iWinY <= Mon%iMonitor%Top) And (iWinW >= Mon%iMonitor%Right - Mon%iMonitor%Left) And (iWinH >= Mon%iMonitor%Bottom - Mon%iMonitor%Top)
  241. If (bCovers) ;WS_THICKFRAME or WS_CAPTION
  242. {
  243. bCovers &= Not (iStyle & 0x00040000) Or Not (iStyle & 0x00C00000)
  244. Return bCovers ? iMonitor : False
  245. }
  246. Else
  247. Return False
  248. }
  249. ;Returns the workspace area covered by the active monitor
  250. GetActiveMonitorWorkspaceArea(ByRef MonLeft, ByRef MonTop, ByRef MonW, ByRef MonH,hWndOrMouseX, MouseY = "")
  251. {
  252. mon := GetActiveMonitor(hWndOrMouseX, MouseY)
  253. if(mon>=0)
  254. {
  255. SysGet, Mon, MonitorWorkArea, %mon%
  256. MonW := MonRight - MonLeft
  257. MonH := MonBottom - MonTop
  258. }
  259. }
  260. ;Returns the monitor the mouse or the active window is in
  261. GetActiveMonitor(hWndOrMouseX, MouseY = "")
  262. {
  263. if(MouseY="")
  264. {
  265. WinGetPos,x,y,w,h,ahk_id %hWndOrMouseX%
  266. if(!x && !y && !w && !h)
  267. {
  268. MsgBox GetActiveMonitor(): invalid window handle!
  269. return -1
  270. }
  271. x := x + Round(w/2)
  272. y := y + Round(h/2)
  273. }
  274. else
  275. {
  276. x := hWndOrMouseX
  277. y := MouseY
  278. }
  279. ;Loop through every monitor and calculate the distance to each monitor
  280. iBestD := 0xFFFFFFFF
  281. SysGet, Mon0, MonitorCount
  282. Loop %Mon0% { ;Loop through each monitor
  283. SysGet, Mon%A_Index%, Monitor, %A_Index%
  284. Mon%A_Index%MidX := Mon%A_Index%Left + Ceil((Mon%A_Index%Right - Mon%A_Index%Left) / 2)
  285. Mon%A_Index%MidY := Mon%A_Index%Top + Ceil((Mon%A_Index%Top - Mon%A_Index%Bottom) / 2)
  286. }
  287. Loop % Mon0 {
  288. D := Sqrt((x - Mon%A_Index%MidX)**2 + (y - Mon%A_Index%MidY)**2)
  289. If (D < iBestD) {
  290. iBestD := D
  291. iMonitor := A_Index
  292. }
  293. }
  294. return iMonitor
  295. }
  296. ;Returns the (signed) minimum of the absolute values of x and y
  297. absmin(x,y)
  298. {
  299. return abs(x) > abs(y) ? y : x
  300. }
  301. ;Returns the (signed) maximum of the absolute values of x and y
  302. absmax(x,y)
  303. {
  304. return abs(x) < abs(y) ? y : x
  305. }
  306. ;Returns 1 if x is positive or 0 and -1 if x is negative
  307. sign(x)
  308. {
  309. return x < 0 ? -1 : 1
  310. }
  311. ;returns the maximum of xdir and y, but with the sign of xdir
  312. dirmax(xdir,y)
  313. {
  314. if(xdir = 0)
  315. return 0
  316. if(abs(xdir) > y)
  317. return xdir
  318. return xdir / abs(xdir) * abs(y)
  319. }
  320. ;returns the maximum of xdir and y, but with the sign of xdir
  321. dirmin(xdir,y)
  322. {
  323. if(xdir = 0)
  324. return 0
  325. if(abs(xdir) < y)
  326. return xdir
  327. return xdir / abs(xdir) * abs(y)
  328. }
  329. ;Formats a number in hexadecimal
  330. DecToHex( ByRef var )
  331. {
  332. f := A_FormatInteger
  333. SetFormat, Integer, Hex
  334. var += 0
  335. ; SetFormat, Integer, %f%
  336. return var
  337. }
  338. ;Determines if a string starts with another string. NOTE: It's a bit faster to simply use InStr(string, start) = 1
  339. strStartsWith(string,start)
  340. {
  341. return InStr(string, start) = 1
  342. }
  343. ;Determines if a string ends with another string
  344. strEndsWith(string, end)
  345. {
  346. return strlen(end) <= strlen(string) && Substr(string, -strlen(end) + 1) = end
  347. }
  348. ;Removes all occurences of trim at the beginning and end of string
  349. ;trim can be an array of strings that should be removed.
  350. strTrim(string, trim)
  351. {
  352. return strTrimLeft(strTrimRight(string, trim), trim)
  353. }
  354. ;Removes all occurences of trim at the beginning of string
  355. ;trim can be an array of strings that should be removed.
  356. strTrimLeft(string, trim)
  357. {
  358. if(!IsObject(trim))
  359. trim := [trim]
  360. for index, trimString in trim
  361. {
  362. len := strLen(trimString)
  363. while(InStr(string, trimString) = 1)
  364. StringTrimLeft, string, string, %len%
  365. }
  366. return string
  367. }
  368. ;Removes all occurences of trim at the end of string
  369. ;trim can be an array of strings that should be removed.
  370. strTrimRight(string, trim)
  371. {
  372. if(!IsObject(trim))
  373. trim := [trim]
  374. for index, trimString in trim
  375. {
  376. len := strLen(trimString)
  377. while(strEndsWith(string, trimString))
  378. StringTrimRight, string, string, %len%
  379. }
  380. return string
  381. }
  382. ;Finds the first window matching specific criterias.
  383. FindWindow(title, class="", style="", exstyle="", processname="", allowempty = false)
  384. {
  385. WinGet, id, list,,, Program Manager
  386. Loop, %id%
  387. {
  388. this_id := id%A_Index%
  389. WinGetClass, this_class, ahk_id %this_id%
  390. if(class && class!=this_class)
  391. Continue
  392. WinGetTitle, this_title, ahk_id %this_id%
  393. if(title && title!=this_title)
  394. Continue
  395. WinGet, this_style, style, ahk_id %this_id%
  396. if(style && style!=this_style)
  397. Continue
  398. WinGet, this_exstyle, exstyle, ahk_id %this_id%
  399. if(exstyle && exstyle!=this_exstyle)
  400. Continue
  401. WinGetPos ,,,w,h,ahk_id %this_id%
  402. if(!allowempty && (w=0 || h=0))
  403. Continue
  404. WinGet, this_processname, processname, ahk_id %this_id%
  405. if(processname && processname!=this_processname)
  406. Continue
  407. return this_id
  408. }
  409. return 0
  410. }
  411. ;Gets the process name from a window handle.
  412. GetProcessName(hwnd)
  413. {
  414. WinGet, ProcessName, processname, ahk_id %hwnd%
  415. return ProcessName
  416. }
  417. ;Gets the path of a process by its pid
  418. GetModuleFileNameEx(pid)
  419. {
  420. if A_OSVersion in WIN_95,WIN_98,WIN_ME
  421. {
  422. MsgBox, This Windows version (%A_OSVersion%) is not supported.
  423. return
  424. }
  425. /*
  426. #define PROCESS_VM_READ (0x0010)
  427. #define PROCESS_QUERY_INFORMATION (0x0400)
  428. */
  429. h_process := DllCall("OpenProcess", "uint", 0x10|0x400, "int", false, "uint", pid, "Ptr")
  430. if (ErrorLevel || h_process = 0)
  431. {
  432. outputdebug [OpenProcess] failed. PID = %pid%
  433. return
  434. }
  435. name_size := A_IsUnicode ? 510 : 255
  436. VarSetCapacity(name, name_size)
  437. result := DllCall("psapi.dll\GetModuleFileNameEx", "Ptr", h_process, "uint", 0, "str", name, "uint", name_size)
  438. if(ErrorLevel || result = 0)
  439. outputdebug [GetModuleFileNameExA] failed
  440. DllCall("CloseHandle", "Ptr", h_process)
  441. return name
  442. }
  443. ; Extract an icon from an executable, DLL or icon file.
  444. ExtractIcon(Filename, IconNumber = 0, IconSize = 64)
  445. {
  446. ; LoadImage is not used..
  447. ; ..with exe/dll files because:
  448. ; it only works with modules loaded by the current process,
  449. ; it needs the resource ordinal (which is not the same as an icon index), and
  450. ; ..with ico files because:
  451. ; it can only load the first icon (of size %IconSize%) from an .ico file.
  452. ; If possible, use PrivateExtractIcons, which supports any size of icon.
  453. ; r:=DllCall("PrivateExtractIcons" , "str", Filename, "int", IconNumber-1, "int", IconSize, "int", IconSize, "Ptr*", h_icon, "PTR*", 0, "uint", 1, "uint", 0, "int")
  454. ;if !ErrorLevel
  455. ; return h_icon
  456. r := DllCall("Shell32.dll\SHExtractIconsW", "str", Filename, "int", IconNumber-1, "int", IconSize, "int", IconSize, "Ptr*", h_icon, "Ptr*", pIconId, "uint", 1, "uint", 0, "int")
  457. If (!ErrorLevel && r != 0)
  458. return h_icon
  459. return 0
  460. }
  461. ;Gets the visible window at a screen coordinate
  462. GetVisibleWindowAtPoint(x,y,IgnoredWindow)
  463. {
  464. DetectHiddenWindows,off
  465. WinGet, id, list,,,
  466. Loop, %id%
  467. {
  468. this_id := id%A_Index%
  469. ;WinActivate, ahk_id %this_id%
  470. WinGetClass, this_class, ahk_id %this_id%
  471. WinGetPos , WinX, WinY, Width, Height, ahk_id %this_id%
  472. if(IsInArea(x,y,WinX,WinY,Width,Height)&&this_class!=IgnoredWindow)
  473. {
  474. DetectHiddenWindows,on
  475. return this_class
  476. }
  477. }
  478. DetectHiddenWindows,on
  479. }
  480. ;checks if a point is in a rectangle
  481. IsInArea(px,py,x,y,w,h)
  482. {
  483. return (px > x && py > y && px < x + w && py < y + h)
  484. }
  485. ;Checks if two rectangles overlap
  486. RectsOverlap(x1,y1,w1,h1,x2,y2,w2,h2)
  487. {
  488. Union := RectUnion(x1,y1,w1,h1,x2,y2,w2,h2)
  489. return Union.w && Union.h
  490. }
  491. ;Checks if two rectangles are separate
  492. RectsSeparate(x1,y1,w1,h1,x2,y2,w2,h2)
  493. {
  494. Union := RectUnion(x1,y1,w1,h1,x2,y2,w2,h2)
  495. return Union.w = 0 && Union.h = 0
  496. }
  497. ;Check if the first rectangle includes the second one
  498. RectIncludesRect(x1,y1,w1,h1,ix,iy,iw,ih)
  499. {
  500. Union := RectUnion(x1,y1,w1,h1,ix,iy,iw,ih)
  501. return Union.x = ix && Union.y = iy && Union.w = iw && Union.h = ih
  502. }
  503. ;Calculates the union of two rectangles
  504. RectUnion(x1,y1,w1,h1,x2,y2,w2,h2)
  505. {
  506. x3 := ""
  507. y3 := ""
  508. ;X Axis
  509. if(x1 > x2 && x1 < x2 + w2)
  510. x3 := x1
  511. else if(x2 > x1 && x2 < x1 + w1)
  512. x3 := x2
  513. if(y1 > y2 && y1 < y2 + h2)
  514. y3 := y1
  515. else if(y2 > y1 && y2 < y1 + h1)
  516. y3 := y2
  517. if(x3 != x1 && x3 != x2) ;Not overlapping
  518. w3 := 0
  519. else
  520. w3 := w1 - (x3 - x1) < w2 - (x3 - x2) ? w1 - (x3 - x1) : w2 - (x3 - x2) ;Choose the smaller width
  521. if(y3 != y1 && y3 != y2) ;Not overlapping
  522. h3 := 0
  523. else
  524. h3 := h1 - (y3 - y1) < h2 - (y3 - y2) ? h1 - (y3 - y1) : h2 - (y3 - y2) ;Choose the smaller height
  525. if(w3 = 0)
  526. h3 := 0
  527. else if(h3 = 0)
  528. w3 := 0
  529. return Object("x", x3, "y", y3, "w", w3, "h", h3)
  530. }
  531. ;Gets window position using workspace coordinates (-> no taskbar)
  532. WinGetPlacement(hwnd, ByRef x="", ByRef y="", ByRef w="", ByRef h="", ByRef state="")
  533. {
  534. VarSetCapacity(wp, 44), NumPut(44, wp)
  535. DllCall("GetWindowPlacement", "Ptr", hwnd, "Ptr", &wp)
  536. x := NumGet(wp, 28, "int")
  537. y := NumGet(wp, 32, "int")
  538. w := NumGet(wp, 36, "int") - x
  539. h := NumGet(wp, 40, "int") - y
  540. state := NumGet(wp, 8, "UInt")
  541. ;outputdebug get x%x% y%y% w%w% h%h% state%state%
  542. }
  543. ;Sets window position using workspace coordinates (-> no taskbar)
  544. WinSetPlacement(hwnd, x="",y="",w="",h="",state="")
  545. {
  546. WinGetPlacement(hwnd, x1, y1, w1, h1, state1)
  547. if(x = "")
  548. x := x1
  549. if(y = "")
  550. y := y1
  551. if(w = "")
  552. w := w1
  553. if(h = "")
  554. h := h1
  555. if(state = "")
  556. state := state1
  557. VarSetCapacity(wp, 44), NumPut(44, wp)
  558. if(state = 6)
  559. NumPut(7, wp, 8) ;SW_SHOWMINNOACTIVE
  560. else if(state = 1)
  561. NumPut(4, wp, 8) ;SW_SHOWNOACTIVATE
  562. else if(state = 3)
  563. NumPut(3, wp, 8) ;SW_SHOWMAXIMIZED and/or SW_MAXIMIZE
  564. else
  565. NumPut(state, wp, 8)
  566. NumPut(x, wp, 28, "Int")
  567. NumPut(y, wp, 32, "Int")
  568. NumPut(x+w, wp, 36, "Int")
  569. NumPut(y+h, wp, 40, "Int")
  570. DllCall("SetWindowPlacement", "Ptr", hwnd, "Ptr", &wp)
  571. }
  572. ;Checks if the current LClick hotkey comes from a double click
  573. IsDoubleClick()
  574. {
  575. return A_TimeSincePriorHotkey < DllCall("GetDoubleClickTime") && A_ThisHotkey=A_PriorHotkey
  576. }
  577. ;Checks if a specific control class is active. Matches by start of ClassNN.
  578. IsControlActive(controlclass)
  579. {
  580. if(WinVer >= WIN_7)
  581. ControlGetFocus active, A
  582. else
  583. active := XPGetFocussed()
  584. if(InStr(active, controlclass))
  585. return true
  586. return false
  587. }
  588. ; This script retrieves the ahk_id (HWND) of the active window's focused control.
  589. ; This script requires Windows 98+ or NT 4.0 SP3+.
  590. /*
  591. typedef struct tagGUITHREADINFO {
  592. DWORD cbSize;
  593. DWORD flags;
  594. HWND hwndActive;
  595. HWND hwndFocus;
  596. HWND hwndCapture;
  597. HWND hwndMenuOwner;
  598. HWND hwndMoveSize;
  599. HWND hwndCaret;
  600. RECT rcCaret;
  601. } GUITHREADINFO, *PGUITHREADINFO;
  602. */
  603. GetFocusedControl()
  604. {
  605. guiThreadInfoSize := 8 + 6 * A_PtrSize + 16
  606. VarSetCapacity(guiThreadInfo, guiThreadInfoSize, 0)
  607. NumPut(GuiThreadInfoSize, GuiThreadInfo, 0)
  608. ; DllCall("RtlFillMemory" , "PTR", &guiThreadInfo, "UInt", 1 , "UChar", guiThreadInfoSize) ; Below 0xFF, one call only is needed
  609. If(DllCall("GetGUIThreadInfo" , "UInt", 0 ; Foreground thread
  610. , "PTR", &guiThreadInfo) = 0)
  611. {
  612. ErrorLevel := A_LastError ; Failure
  613. Return 0
  614. }
  615. focusedHwnd := NumGet(guiThreadInfo,8+A_PtrSize, "Ptr") ; *(addr + 12) + (*(addr + 13) << 8) + (*(addr + 14) << 16) + (*(addr + 15) << 24)
  616. Return focusedHwnd
  617. }
  618. ; Force kill program on Alt+F5 and on right click close button
  619. CloseKill(hwnd)
  620. {
  621. WinGet, pid, pid, ahk_id %hwnd%
  622. WinKill ahk_id %hwnd%
  623. if(WinExist("ahk_id " hwnd))
  624. Process, close, %pid%
  625. }
  626. /*
  627. Converts a string list with separators to an array. It also removes and splits at quotes
  628. To be parsed:
  629. file a
  630. file b
  631. "file a"
  632. "file b"
  633. "file a" "file b"
  634. "file a"|"file b"
  635. file a|file b
  636. */
  637. ToArray(SourceFiles, ByRef Separator = "`n", ByRef wasQuoted = 0)
  638. {
  639. if(IsArray(SourceFiles))
  640. return SourceFiles
  641. files := Array()
  642. pos := 1
  643. wasQuoted := 0
  644. Loop
  645. {
  646. if(pos > strlen(SourceFiles))
  647. break
  648. char := SubStr(SourceFiles, pos, 1)
  649. if(char = """" || wasQuoted) ;Quoted paths
  650. {
  651. file := SubStr(SourceFiles, InStr(SourceFiles, """", 0, pos) + 1, InStr(SourceFiles, """", 0, pos + 1) - pos - 1)
  652. if(!wasQuoted)
  653. {
  654. wasQuoted := 1
  655. Separator := SubStr(SourceFiles, InStr(SourceFiles, """", 0, pos + 1) + 1, InStr(SourceFiles, """", 0, InStr(SourceFiles, """", 0, pos + 1) + 1) - InStr(SourceFiles, """", 0, pos + 1) - 1)
  656. }
  657. if(file)
  658. {
  659. files.Insert(file)
  660. pos += strlen(file) + 3
  661. continue
  662. }
  663. else
  664. Msgbox Invalid source format %SourceFiles%
  665. }
  666. else
  667. {
  668. file := SubStr(SourceFiles, pos, max(InStr(SourceFiles, Separator, 0, pos + 1) - pos, 0)) ; separator
  669. if(!file)
  670. file := SubStr(SourceFiles, pos) ;no quotes or separators, single file
  671. if(file)
  672. {
  673. files.Insert(file)
  674. pos += strlen(file) + strlen(Separator)
  675. continue
  676. }
  677. else
  678. Msgbox Invalid source format
  679. }
  680. pos++ ;Shouldn't happen
  681. }
  682. return files
  683. }
  684. ;Flattens an array to a list with separators
  685. ArrayToList(array, separator = "`n", quote = 0)
  686. {
  687. Loop % array.MaxIndex()
  688. result .= (A_Index != 1 ? separator : "") (quote ? """" : "") array[A_Index] (quote ? """" : "")
  689. return result
  690. }
  691. ;Compares two (already separated) version numbers. Returns 1 if 1st is greater, 0 if equal, -1 if second is greater
  692. CompareVersion(major1,major2,minor1,minor2,bugfix1,bugfix2)
  693. {
  694. if(major1 > major2)
  695. return 1
  696. else if(major1 = major2 && minor1 > minor2)
  697. return 1
  698. else if(major1 = major2 && minor1 = minor2 && bugfix1 > bugfix2)
  699. return 1
  700. else if(major1 = major2 && minor1 = minor2 && bugfix1 = bugfix2)
  701. return 0
  702. else
  703. return -1
  704. }
  705. ;Returns true if x is a number
  706. IsNumeric(x)
  707. {
  708. If x is number
  709. Return 1
  710. Return 0
  711. }
  712. ;Performs quote unescaping of a string. Transforms \" to " and \\ to \
  713. StringUnescape(String)
  714. {
  715. return StringReplace(StringReplace(StringReplace(String, "\\", Chr(1), 1), "\""", """", 1), Chr(1), "\", 1)
  716. }
  717. ;Performs quote escaping of a string. Transforms " to \" and \ to \\
  718. StringEscape(String)
  719. {
  720. return StringReplace(StringReplace(String, "\", "\\", 1), """", "\""", 1)
  721. }
  722. ;Decodes a URL
  723. uriDecode(str) {
  724. Loop
  725. If RegExMatch(str, "i)(?<=%)[\da-f]{1,2}", hex)
  726. StringReplace, str, str, `%%hex%, % Chr("0x" . hex), All
  727. Else Break
  728. Return, str
  729. }
  730. ; modified from jackieku's code (http://www.autohotkey.com/forum/post-310959.html#310959)
  731. UriEncode(str, Enc = "UTF-8")
  732. {
  733. try
  734. {
  735. oSC := ComObjCreate("ScriptControl")
  736. oSC.Language := "JScript"
  737. Script := "var Encoded = encodeURIComponent(""" . str . """)"
  738. oSC.ExecuteStatement(Script)
  739. encoded := oSC.Eval("Encoded")
  740. Return encoded
  741. }
  742. catch e
  743. {
  744. StrPutVar(str, Var, Enc)
  745. f := A_FormatInteger
  746. SetFormat, IntegerFast, H
  747. Loop
  748. {
  749. Code := NumGet(Var, A_Index - 1, "UChar")
  750. If (!Code)
  751. Break
  752. If (Code >= 0x30 && Code <= 0x39 ; 0-9
  753. || Code >= 0x41 && Code <= 0x5A ; A-Z
  754. || Code >= 0x61 && Code <= 0x7A) ; a-z
  755. Res .= Chr(Code)
  756. Else
  757. Res .= "%" . SubStr(Code + 0x100, -1)
  758. }
  759. SetFormat, IntegerFast, %f%
  760. Return, Res
  761. }
  762. }
  763. StrPutVar(Str, ByRef Var, Enc = "")
  764. {
  765. Len := StrPut(Str, Enc) * (Enc = "UTF-16" || Enc = "CP1200" ? 2 : 1)
  766. VarSetCapacity(Var, Len, 0)
  767. Return, StrPut(Str, &Var, Enc)
  768. }
  769. ;Old function for codepage conversions. AHK_L can do this now.
  770. Unicode2Ansi(ByRef wString, ByRef sString, CP = 0)
  771. {
  772. nSize := DllCall("WideCharToMultiByte" , "Uint", CP, "Uint", 0 , "UintP", wString , "int", -1 , "Uint", 0 , "int", 0 , "Uint", 0 , "Uint", 0)
  773. VarSetCapacity(sString, nSize)
  774. DllCall("WideCharToMultiByte" , "Uint", CP , "Uint", 0 , "UintP", wString , "int", -1 , "str", sString , "int", nSize , "Uint", 0 , "Uint", 0)
  775. }
  776. ;Old function for codepage conversions. AHK_L can do this now.
  777. Ansi2Unicode(ByRef sString, ByRef wString, CP = 0)
  778. {
  779. nSize := DllCall("MultiByteToWideChar" , "Uint", CP , "Uint", 0 , "UintP", sString , "int", -1 , "Uint", 0 , "int", 0)
  780. VarSetCapacity(wString, nSize * 2)
  781. DllCall("MultiByteToWideChar" , "Uint", CP , "Uint", 0 , "UintP", sString , "int", -1 , "UintP", wString , "int", nSize)
  782. }
  783. ;Performs a fuzzy search for string2 in string1.
  784. ;return values range from 0.0 = identical to 1.0 = completely different. 0.4 seems appropriate
  785. FuzzySearch(longer, shorter, UseFuzzySearch = false)
  786. {
  787. if(longer = shorter)
  788. return 1
  789. lenl := StrLen(longer)
  790. lens := StrLen(shorter)
  791. if(lens > lenl)
  792. return 0
  793. ;Check if the shorter string is a substring of the longer string
  794. Contained := InStr(longer, shorter)
  795. if(Contained)
  796. return Contained = 1 ? 1 : 0.8
  797. ;Check if string can be matched by omitting characters
  798. if(lens < 5)
  799. {
  800. pos := 0
  801. matched := 0
  802. Loop % lens
  803. {
  804. char := SubStr(shorter, A_Index, 1)
  805. StringUpper, char, char
  806. Loop % lenl - pos
  807. {
  808. if(SubStr(longer, pos + A_Index, 1) == char)
  809. {
  810. pos := A_Index
  811. matched++
  812. break
  813. }
  814. else
  815. continue
  816. }
  817. }
  818. if(matched = lens)
  819. return 0.9 ;Slightly worse than direct matches
  820. }
  821. ;Calculate fuzzy string difference
  822. if(UseFuzzySearch)
  823. {
  824. max := 0
  825. Loop % lenl - lens + 1
  826. {
  827. distance := 1 - StringDifference(shorter, SubStr(longer, A_Index, lens))
  828. if(distance < max)
  829. max := distance
  830. }
  831. return max
  832. }
  833. return 0
  834. }
  835. ;By Toralf:
  836. ;basic idea for SIFT3 code by Siderite Zackwehdex
  837. ;http://siderite.blogspot.com/2007/04/super-fast-and-accurate-string-distance.html
  838. ;took idea to normalize it to longest string from Brad Wood
  839. ;http://www.bradwood.com/string_compare/
  840. ;Own work:
  841. ; - when character only differ in case, LSC is a 0.8 match for this character
  842. ; - modified code for speed, might lead to different results compared to original code
  843. ; - optimized for speed (30% faster then original SIFT3 and 13.3 times faster than basic Levenshtein distance)
  844. ;http://www.autohotkey.com/forum/topic59407.html
  845. StringDifference(string1, string2, maxOffset=3) { ;returns a float: between "0.0 = identical" and "1.0 = nothing in common"
  846. If (string1 = string2)
  847. Return (string1 == string2 ? 0/1 : 0.2/StrLen(string1)) ;either identical or (assumption:) "only one" char with different case
  848. If (string1 = "" OR string2 = "")
  849. Return (string1 = string2 ? 0/1 : 1/1)
  850. StringSplit, n, string1
  851. StringSplit, m, string2
  852. ni := 1, mi := 1, lcs := 0
  853. While((ni <= n0) AND (mi <= m0)) {
  854. If (n%ni% == m%mi%)
  855. EnvAdd, lcs, 1
  856. Else If (n%ni% = m%mi%)
  857. EnvAdd, lcs, 0.8
  858. Else{
  859. Loop, %maxOffset% {
  860. oi := ni + A_Index, pi := mi + A_Index
  861. If ((n%oi% = m%mi%) AND (oi <= n0)){
  862. ni := oi, lcs += (n%oi% == m%mi% ? 1 : 0.8)
  863. Break
  864. }
  865. If ((n%ni% = m%pi%) AND (pi <= m0)){
  866. mi := pi, lcs += (n%ni% == m%pi% ? 1 : 0.8)
  867. Break
  868. }
  869. }
  870. }
  871. EnvAdd, ni, 1
  872. EnvAdd, mi, 1
  873. }
  874. Return ((n0 + m0)/2 - lcs) / (n0 > m0 ? n0 : m0)
  875. }
  876. ;Returns true if the string is in URL format. Use CouldBeURL() for weaker checks.
  877. IsURL(string)
  878. {
  879. return RegexMatch(strTrim(string, " "), "(?:(?:ht|f)tps?://|www\.).+\..+") > 0
  880. }
  881. ;Returns true if the string could be a URL. Use IsURL() to be sure.
  882. CouldBeURL(string)
  883. {
  884. return RegexMatch(strTrim(string, " "), "(?:(?:ht|f)tps?://|www\.)?.+\..+") > 0
  885. }
  886. ;Tests for write access to a specific file
  887. WriteAccess( F ) {
  888. if(FileExist(F))
  889. Return ((h := DllCall("_lopen", AStr, F, Int, 1, "Ptr")) > 0 ? 1 : 0) (DllCall("_lclose", "Ptr", h) + NULL)
  890. else
  891. {
  892. SplitPath, F,,Dir
  893. F := FindFreeFilename(Dir)
  894. FileAppend, x, %F%
  895. Success := !ErrorLevel
  896. FileDelete, %F%
  897. return !ErrorLevel
  898. }
  899. }
  900. ;Generates MD5 value of a file
  901. FileMD5(sFile´= "", cSz = 4 )
  902. { ; www.autohotkey.com/forum/viewtopic.php?p=275910#275910
  903. cSz := (cSz < 0 || cSz > 8) ? 2 ** 22 : 2 ** (18 + cSz)
  904. VarSetCapacity(Buffer, cSz, 0)
  905. hFil := DllCall("CreateFile", Str, sFile, UInt, 0x80000000, Int, 1, Int, 0, Int, 3, Int, 0, Int, 0, "Ptr")
  906. if(hFil < 1)
  907. return hFil
  908. DllCall("GetFileSizeEx", Ptr, hFil, Ptr, &Buffer)
  909. fSz := NumGet(Buffer, 0, "Int64")
  910. VarSetCapacity(MD5_CTX, 104, 0)
  911. DllCall("advapi32\MD5Init", PTR, &MD5_CTX)
  912. Loop % (fSz // cSz + !!Mod(fSz, cSz))
  913. DllCall("ReadFile", PTR, hFil, PTR, &Buffer, UInt, cSz, UIntP, bytesRead, UInt, 0)
  914. DllCall("advapi32\MD5Update", PTR, &MD5_CTX, PTR, &Buffer, UInt,bytesRead)
  915. DllCall("advapi32\MD5Final", PTR, &MD5_CTX )
  916. DllCall("CloseHandle", PTR, hFil)
  917. Loop % StrLen(Hex := "123456789ABCDEF0")
  918. {
  919. N := NumGet(MD5_CTX, 87 + A_Index, "Char")
  920. MD5 .= SubStr(Hex, N >> 4, 1) SubStr(Hex, N & 15, 1)
  921. }
  922. return MD5
  923. }
  924. ;Formats a file size in bytes to a human-readable size string
  925. FormatFileSize(Bytes, Decimals = 1, Prefixes = "B,KB,MB,GB,TB,PB,EB,ZB,YB")
  926. {
  927. StringSplit, Prefix, Prefixes, `,
  928. Loop, Parse, Prefixes, `,
  929. if(Bytes < e := 1024 ** A_Index)
  930. return % Round(Bytes / (e / 1024), decimals) Prefix%A_Index%
  931. }
  932. ;Returns a string containing the formatted object keys and values
  933. ExploreObj(Obj, NewRow = "`n", Equal = " = ", Indent = "`t", Depth = 12, CurIndent = "")
  934. {
  935. for k,v in Obj
  936. ToReturn .= CurIndent k (IsObject(v) && depth > 1 ? NewRow ExploreObj(v, NewRow, Equal, Indent, Depth - 1, CurIndent Indent) : Equal v) NewRow
  937. return RTrim(ToReturn, NewRow)
  938. }
  939. GetFullPathName(SPath)
  940. {
  941. VarSetCapacity(lPath,A_IsUnicode ? 520 : 260, 0)
  942. DllCall("GetLongPathName", Str, SPath, Str, lPath, UInt, 260)
  943. Return lPath
  944. }
  945. ;This function calls a function of an event on every key in it
  946. objDeepPerform(obj, function, Event)
  947. {
  948. if(!IsFunc(function))
  949. return
  950. if(obj.HasKey("base"))
  951. objDeepPerform(obj.base, function, Event)
  952. enum := obj._newenum()
  953. while enum[key, value]
  954. {
  955. if(IsObject(value))
  956. objDeepPerform(value, function, Event)
  957. else
  958. obj[key] := %function%(Event, value)
  959. }
  960. }
  961. ;Finds a non-existing filename for Filepath by appending a number in brackets to the name
  962. FindFreeFileName(FilePath)
  963. {
  964. SplitPath, FilePath,, dir, extension, filename
  965. Testpath := FilePath ;Return path if it doesn't exist
  966. i := 1
  967. while FileExist(TestPath)
  968. {
  969. i++
  970. Testpath := dir "\" filename " (" i ")" (extension = "" ? "" : "." extension)
  971. }
  972. return TestPath
  973. }
  974. ;Attaches a window as a tool window to another window from a different process. QUESTION: Is this still needed?
  975. AttachToolWindow(hParent, GUINumber, AutoClose)
  976. {
  977. global ToolWindows
  978. outputdebug AttachToolWindow %GUINumber% to %hParent%
  979. if(!IsObject(ToolWindows))
  980. ToolWindows := Object()
  981. if(!WinExist("ahk_id " hParent))
  982. return false
  983. Gui %GUINumber%: +LastFoundExist
  984. if(!(hGui := WinExist()))
  985. return false
  986. ;SetWindowLongPtr is defined as SetWindowLong in x86
  987. if(A_PtrSize = 4)
  988. DllCall("SetWindowLong", "Ptr", hGui, "int", -8, "PTR", hParent) ;This line actually sets the owner behavior
  989. else
  990. DllCall("SetWindowLongPtr", "Ptr", hGui, "int", -8, "PTR", hParent) ;This line actually sets the owner behavior
  991. ToolWindows.Insert(Object("hParent", hParent, "hGui", hGui,"AutoClose", AutoClose))
  992. Gui %GUINumber%: Show, NoActivate
  993. return true
  994. }
  995. DeAttachToolWindow(GUINumber)
  996. {
  997. global ToolWindows
  998. Gui %GUINumber%: +LastFoundExist
  999. if(!(hGui := WinExist()))
  1000. return false
  1001. Loop % ToolWindows.MaxIndex()
  1002. {
  1003. if(ToolWindows[A_Index].hGui = hGui)
  1004. {
  1005. ;SetWindowLongPtr is defined as SetWindowLong in x86
  1006. if(A_PtrSize = 4)
  1007. DllCall("SetWindowLong", "Ptr", hGui, "int", -8, "PTR", 0) ;Remove tool window behavior
  1008. else
  1009. DllCall("SetWindowLongPtr", "Ptr", hGui, "int", -8, "PTR", 0) ;Remove tool window behavior
  1010. DllCall("SetWindowLongPtr", "Ptr", hGui, "int", -8, "PTR", 0)
  1011. ToolWindows.Remove(A_Index)
  1012. break
  1013. }
  1014. }
  1015. }
  1016. ;Adds a tooltip to a control.
  1017. AddToolTip(con, text, Modify = 0)
  1018. {
  1019. Static TThwnd,GuiHwnd
  1020. l_DetectHiddenWindows := A_DetectHiddenWindows
  1021. If(!TThwnd)
  1022. {
  1023. Gui, +LastFound
  1024. GuiHwnd := WinExist()
  1025. TThwnd := CreateTooltipControl(GuiHwnd)
  1026. Varsetcapacity(TInfo, 6 * 4 + 6 * A_PtrSize, 0)
  1027. Numput(6 * 4 + 6 * A_PtrSize, TInfo, "UInt")
  1028. Numput(1 | 16, TInfo, 4, "UInt")
  1029. Numput(GuiHwnd, TInfo, 8, "PTR")
  1030. Numput(GuiHwnd, TInfo, 8 + A_PtrSize, "PTR")
  1031. ;Numput(&text,TInfo,36)
  1032. Detecthiddenwindows, on
  1033. Sendmessage, 1028, 0, &TInfo, , ahk_id %TThwnd%
  1034. SendMessage, 1048, 0, 300, , ahk_id %TThwnd%
  1035. }
  1036. Varsetcapacity(TInfo, 6 * 4 + 6 * A_PtrSize, 0)
  1037. Numput(6 * 4 + 6 * A_PtrSize, TInfo, "UInt")
  1038. Numput(1 | 16, TInfo, 4, "UInt")
  1039. Numput(GuiHwnd, TInfo, 8, "PTR")
  1040. Numput(con, TInfo, 8 + A_PtrSize, "PTR")
  1041. VarSetCapacity(ANSItext, StrPut(text, ""))
  1042. StrPut(text, &ANSItext, "")
  1043. Numput(&ANSIText, TInfo, 6 * 4 + 3 * A_PtrSize, "PTR")
  1044. Detecthiddenwindows, on
  1045. if(Modify)
  1046. SendMessage, 1036, 0, &TInfo, , ahk_id %TThwnd%
  1047. else
  1048. {
  1049. Sendmessage, 1028, 0, &TInfo, , ahk_id %TThwnd%
  1050. SendMessage, 1048, 0, 300, , ahk_id %TThwnd%
  1051. }
  1052. DetectHiddenWindows %l_DetectHiddenWindows%
  1053. }
  1054. CreateTooltipControl(hwind)
  1055. {
  1056. Ret := DllCall("CreateWindowEx"
  1057. ,"Uint", 0
  1058. ,"Str", "TOOLTIPS_CLASS32"
  1059. ,"PTR", 0
  1060. ,"Uint", 2147483648 | 3
  1061. ,"Uint", -2147483648
  1062. ,"Uint", -2147483648
  1063. ,"Uint", -2147483648
  1064. ,"Uint", -2147483648
  1065. ,"PTR", hwind
  1066. ,"PTR", 0
  1067. ,"PTR", 0
  1068. ,"PTR", 0, "PTR")
  1069. return Ret
  1070. }
  1071. ;Gets width of all screens combined. NOTE: Single screens may have different vertical resolutions so some parts of the area returned here might not belong to any screens!
  1072. GetVirtualScreenCoordinates(ByRef x, ByRef y, ByRef w, ByRef h)
  1073. {
  1074. SysGet, x, 76 ;Get virtual screen coordinates of all monitors
  1075. SysGet, y, 77
  1076. SysGet, w, 78
  1077. SysGet, h, 79
  1078. }
  1079. ;Determines if a window is visible completely on the screen. Returns 1 if it is, 2 if it's partially on a screen (also if between monitors) and 0 if it's outside of all screens.
  1080. IsWindowOnScreen(hwnd)
  1081. {
  1082. if(IsObject(hwnd))
  1083. {
  1084. x := hwnd.x
  1085. y := hwnd.y
  1086. w := hwnd.w
  1087. h := hwnd.h
  1088. }
  1089. else
  1090. WinGetPos, x, y, w, h, ahk_id %hwnd%
  1091. Monitors := GetMonitors()
  1092. for index, Monitor in Monitors
  1093. {
  1094. if(RectIncludesRect(Monitor.x, Monitor.y, Monitor.w, Monitor.h, x, y, w, h))
  1095. return 1
  1096. if(RectsOverlap(Monitor.x, Monitor.y, Monitor.w, Monitor.h, x, y, w, h))
  1097. return 2
  1098. }
  1099. return 0
  1100. }
  1101. GetMonitors()
  1102. {
  1103. Monitors := []
  1104. SysGet, Mon0, MonitorCount
  1105. ;Loop through each monitor
  1106. Loop %Mon0%
  1107. {
  1108. SysGet, Mon, Monitor, %A_Index%
  1109. Monitor := {}
  1110. Monitor.X := MonLeft
  1111. Monitor.Y := MonTop
  1112. Monitor.Width := MonRight - Monitor.X
  1113. Monitor.Height := MonBottom - Monitor.Y
  1114. Monitors.Insert(Monitor)
  1115. }
  1116. return Monitors
  1117. }
  1118. GetMonitorWorkAreas()
  1119. {
  1120. Monitors := []
  1121. SysGet, Mon0, MonitorCount
  1122. ;Loop through each monitor
  1123. Loop %Mon0%
  1124. {
  1125. SysGet, Mon, MonitorWorkArea, %A_Index%
  1126. Monitor := {}
  1127. Monitor.X := MonLeft
  1128. Monitor.Y := MonTop
  1129. Monitor.Width := MonRight - Monitor.X
  1130. Monitor.Height := MonBottom - Monitor.Y
  1131. Monitors.Insert(Monitor)
  1132. }
  1133. return Monitors
  1134. }
  1135. ;WinGetPos function wrapper
  1136. WinGetPos(WinTitle = "", WinText = "", ExcludeTitle = "", ExcludeText = "")
  1137. {
  1138. WinGetPos, x, y, w, h, %WinTitle%, %WinText%, %ExcludeTitle%, %ExcludeText%
  1139. return Object("x", x, "y", y, "w", w, "h", h)
  1140. }
  1141. ;WinMove function wrapper
  1142. WinMove(WinTitle, Rect, WinText = "", ExcludeTitle = "", ExcludeText = "")
  1143. {
  1144. WinMove, %WinTitle%, %WinText%, % Rect.x, % Rect.y, % Rect.w, % Rect.h, %ExcludeTitle%, %ExcludeText%
  1145. }
  1146. ;Returns true if a window is visible in Alt+Tab list
  1147. IsAltTabWindow(hwnd)
  1148. {
  1149. if(!hwnd)
  1150. return false
  1151. WinGet, ExStyle, ExStyle, ahk_id %hwnd%
  1152. if(ExStyle & 0x80) ;WS_EX_TOOLWINDOW
  1153. return false
  1154. hwndWalk := DllCall("GetAncestor", "PTR", hwnd, "INT", 3, "PTR")
  1155. ; See if we are the last active visible popup
  1156. while((hwndTry := DllCall("GetLastActivePopup", "PTR", hwndWalk, "PTR")) != hwndWalk)
  1157. {
  1158. if(DllCall("IsWindowVisible", "PTR", hwndTry))
  1159. break
  1160. hwndWalk := hwndTry
  1161. }
  1162. return hwndWalk = hwnd
  1163. }
  1164. ;Gets ClassNN from hwnd
  1165. HWNDToClassNN(hwnd)
  1166. {
  1167. win := DllCall("GetParent", "PTR", hwnd, "PTR")
  1168. WinGet ctrlList, ControlList, ahk_id %win%
  1169. ; Built an array indexing the control names by their hwnd
  1170. Loop Parse, ctrlList, `n
  1171. {
  1172. ControlGet hwnd1, Hwnd, , %A_LoopField%, ahk_id %win%
  1173. if(hwnd1=hwnd)
  1174. return A_LoopField
  1175. }
  1176. }
  1177. ;Gets focused control in XP to prevent blocking double clicks like with ControlGetFocus
  1178. XPGetFocussed()
  1179. {
  1180. WinGet ctrlList, ControlList, A
  1181. ctrlHwnd:=GetFocusedControl()
  1182. ; Built an array indexing the control names by their hwnd
  1183. Loop Parse, ctrlList, `n
  1184. {
  1185. ControlGet hwnd, Hwnd, , %A_LoopField%, A
  1186. hwnd += 0 ; Convert from hexa to decimal
  1187. if(hwnd=ctrlHwnd)
  1188. return A_LoopField
  1189. }
  1190. }
  1191. ;Watches a directory/file for file changes
  1192. ;By HotKeyIt
  1193. ;Docs: http://www.autohotkey.com/forum/viewtopic.php?p=398565#398565
  1194. WatchDirectory(p*){
  1195. global _Struct
  1196. ;Structures
  1197. static FILE_NOTIFY_INFORMATION:="DWORD NextEntryOffset,DWORD Action,DWORD FileNameLength,WCHAR FileName[1]"
  1198. static OVERLAPPED:="ULONG_PTR Internal,ULONG_PTR InternalHigh,{struct{DWORD offset,DWORD offsetHigh},PVOID Pointer},HANDLE hEvent"
  1199. ;Variables
  1200. static running,sizeof_FNI=65536,WatchDirectory:=RegisterCallback("WatchDirectory","F",0,0) ;,nReadLen:=VarSetCapacity(nReadLen,8)
  1201. static timer,ReportToFunction,LP,nReadLen:=VarSetCapacity(LP,(260)*(A_PtrSize/2),0)
  1202. static @:=Object(),reconnect:=Object(),#:=Object(),DirEvents,StringToRegEx="\\\|.\.|+\+|[\[|{\{|(\(|)\)|^\^|$\$|?\.?|*.*"
  1203. ;ReadDirectoryChanges related
  1204. static FILE_NOTIFY_CHANGE_FILE_NAME=0x1,FILE_NOTIFY_CHANGE_DIR_NAME=0x2,FILE_NOTIFY_CHANGE_ATTRIBUTES=0x4
  1205. ,FILE_NOTIFY_CHANGE_SIZE=0x8,FILE_NOTIFY_CHANGE_LAST_WRITE=0x10,FILE_NOTIFY_CHANGE_CREATION=0x40
  1206. ,FILE_NOTIFY_CHANGE_SECURITY=0x100
  1207. static FILE_ACTION_ADDED=1,FILE_ACTION_REMOVED=2,FILE_ACTION_MODIFIED=3
  1208. ,FILE_ACTION_RENAMED_OLD_NAME=4,FILE_ACTION_RENAMED_NEW_NAME=5
  1209. static OPEN_EXISTING=3,FILE_FLAG_BACKUP_SEMANTICS=0x2000000,FILE_FLAG_OVERLAPPED=0x40000000
  1210. ,FILE_SHARE_DELETE=4,FILE_SHARE_WRITE=2,FILE_SHARE_READ=1,FILE_LIST_DIRECTORY=1
  1211. If p.MaxIndex(){
  1212. If (p.MaxIndex()=1 && p.1=""){
  1213. for i,folder in #
  1214. DllCall("CloseHandle","Uint",@[folder].hD),DllCall("CloseHandle","Uint",@[folder].O.hEvent)
  1215. ,@.Remove(folder)
  1216. #:=Object()
  1217. DirEvents:=new _Struct("HANDLE[1000]")
  1218. DllCall("KillTimer","Uint",0,"Uint",timer)
  1219. timer=
  1220. Return 0
  1221. } else {
  1222. if p.2
  1223. ReportToFunction:=p.2
  1224. If !IsFunc(ReportToFunction)
  1225. Return -1 ;DllCall("MessageBox","Uint",0,"Str","Function " ReportToFunction " does not exist","Str","Error Missing Function","UInt",0)
  1226. RegExMatch(p.1,"^([^/\*\?<>\|""]+)(\*)?(\|.+)?$",dir)
  1227. if (SubStr(dir1,0)="\")
  1228. StringTrimRight,dir1,dir1,1
  1229. StringTrimLeft,dir3,dir3,1
  1230. If (p.MaxIndex()=2 && p.2=""){
  1231. for i,folder in #
  1232. If (dir1=SubStr(folder,1,StrLen(folder)-1))
  1233. Return 0 ,DirEvents[i]:=DirEvents[#.MaxIndex()],DirEvents[#.MaxIndex()]:=0
  1234. @.Remove(folder),#[i]:=#[#.MaxIndex()],#.Remove(i)
  1235. Return 0
  1236. }
  1237. }
  1238. if !InStr(FileExist(dir1),"D")
  1239. Return -1 ;DllCall("MessageBox","Uint",0,"Str","Folder " dir1 " does not exist","Str","Error Missing File","UInt",0)
  1240. for i,folder in #
  1241. {
  1242. If (dir1=SubStr(folder,1,StrLen(folder)-1) || (InStr(dir1,folder) && @[folder].sD))
  1243. Return 0
  1244. else if (InStr(SubStr(folder,1,StrLen(folder)-1),dir1 "\") && dir2){ ;replace watch
  1245. DllCall("CloseHandle","Uint",@[folder].hD),DllCall("CloseHandle","Uint",@[folder].O.hEvent),reset:=i
  1246. }
  1247. }
  1248. LP:=SubStr(LP,1,DllCall("GetLongPathName","Str",dir1,"Uint",&LP,"Uint",VarSetCapacity(LP))) "\"
  1249. If !(reset && @[reset]:=LP)
  1250. #.Insert(LP)
  1251. @[LP,"dir"]:=LP
  1252. @[LP].hD:=DllCall("CreateFile","Str",StrLen(LP)=3?SubStr(LP,1,2):LP,"UInt",0x1,"UInt",0x1|0x2|0x4
  1253. ,"UInt",0,"UInt",0x3,"UInt",0x2000000|0x40000000,"UInt",0)
  1254. @[LP].sD:=(dir2=""?0:1)
  1255. Loop,Parse,StringToRegEx,|
  1256. StringReplace,dir3,dir3,% SubStr(A_LoopField,1,1),% SubStr(A_LoopField,2),A
  1257. StringReplace,dir3,dir3,%A_Space%,\s,A
  1258. Loop,Parse,dir3,|
  1259. {
  1260. If A_Index=1
  1261. dir3=
  1262. pre:=(SubStr(A_LoopField,1,2)="\\"?2:0)
  1263. succ:=(SubStr(A_LoopField,-1)="\\"?2:0)
  1264. dir3.=(dir3?"|":"") (pre?"\\\K":"")
  1265. . SubStr(A_LoopField,1+pre,StrLen(A_LoopField)-pre-succ)
  1266. . ((!succ && !InStr(SubStr(A_LoopField,1+pre,StrLen(A_LoopField)-pre-succ),"\"))?"[^\\]*$":"") (succ?"$":"")
  1267. }
  1268. @[LP].FLT:="i)" dir3
  1269. @[LP].FUNC:=ReportToFunction
  1270. @[LP].CNG:=(p.3?p.3:(0x1|0x2|0x4|0x8|0x10|0x40|0x100))
  1271. If !reset {
  1272. @[LP].SetCapacity("pFNI",sizeof_FNI)
  1273. @[LP].FNI:=new _Struct(FILE_NOTIFY_INFORMATION,@[LP].GetAddress("pFNI"))
  1274. @[LP].O:=new _Struct(OVERLAPPED)
  1275. }
  1276. @[LP].O.hEvent:=DllCall("CreateEvent","Uint",0,"Int",1,"Int",0,"UInt",0)
  1277. If (!DirEvents)
  1278. DirEvents:=new _Struct("HANDLE[1000]")
  1279. DirEvents[reset?reset:#.MaxIndex()]:=@[LP].O.hEvent
  1280. DllCall("ReadDirectoryChangesW","UInt",@[LP].hD,"UInt",@[LP].FNI[],"UInt",sizeof_FNI
  1281. ,"Int",@[LP].sD,"UInt",@[LP].CNG,"UInt",0,"UInt",@[LP].O[],"UInt",0)
  1282. Return timer:=DllCall("SetTimer","Uint",0,"UInt",timer,"Uint",50,"UInt",WatchDirectory)
  1283. } else {
  1284. Sleep, 0
  1285. for LP in reconnect
  1286. {
  1287. If (FileExist(@[LP].dir) && reconnect.Remove(LP)){
  1288. DllCall("CloseHandle","Uint",@[LP].hD)
  1289. @[LP].hD:=DllCall("CreateFile","Str",StrLen(@[LP].dir)=3?SubStr(@[LP].dir,1,2):@[LP].dir,"UInt",0x1,"UInt",0x1|0x2|0x4
  1290. ,"UInt",0,"UInt",0x3,"UInt",0x2000000|0x40000000,"UInt",0)
  1291. DllCall("ResetEvent","UInt",@[LP].O.hEvent)
  1292. DllCall("ReadDirectoryChangesW","UInt",@[LP].hD,"UInt",@[LP].FNI[],"UInt",sizeof_FNI
  1293. ,"Int",@[LP].sD,"UInt",@[LP].CNG,"UInt",0,"UInt",@[LP].O[],"UInt",0)
  1294. }
  1295. }
  1296. if !( (r:=DllCall("MsgWaitForMultipleObjectsEx","UInt",#.MaxIndex()
  1297. ,"UInt",DirEvents[],"UInt",0,"UInt",0x4FF,"UInt",6))>=0
  1298. && r<#.MaxIndex() ){
  1299. return
  1300. }
  1301. DllCall("KillTimer", UInt,0, UInt,timer)
  1302. LP:=#[r+1],DllCall("GetOverlappedResult","UInt",@[LP].hD,"UInt",@[LP].O[],"UIntP",nReadLen,"Int",1)
  1303. If (A_LastError=64){ ; ERROR_NETNAME_DELETED - The specified network name is no longer available.
  1304. If !FileExist(@[LP].dir) ; If folder does not exist add to reconnect routine
  1305. reconnect.Insert(LP,LP)
  1306. } else
  1307. Loop {
  1308. FNI:=A_Index>1?(new _Struct(FILE_NOTIFY_INFORMATION,FNI[]+FNI.NextEntryOffset)):(new _Struct(FILE_NOTIFY_INFORMATION,@[LP].FNI[]))
  1309. If (FNI.Action < 0x6){
  1310. FileName:=@[LP].dir . StrGet(FNI.FileName[""],FNI.FileNameLength/2,"UTF-16")
  1311. If (FNI.Action=FILE_ACTION_RENAMED_OLD_NAME)
  1312. FileFromOptional:=FileName
  1313. If (@[LP].FLT="" || RegExMatch(FileName,@[LP].FLT) || FileFrom)
  1314. If (FNI.Action=FILE_ACTION_ADDED){
  1315. FileTo:=FileName
  1316. } else If (FNI.Action=FILE_ACTION_REMOVED){
  1317. FileFrom:=FileName
  1318. } else If (FNI.Action=FILE_ACTION_MODIFIED){
  1319. FileFrom:=FileTo:=FileName
  1320. } else If (FNI.Action=FILE_ACTION_RENAMED_OLD_NAME){
  1321. FileFrom:=FileName
  1322. } else If (FNI.Action=FILE_ACTION_RENAMED_NEW_NAME){
  1323. FileTo:=FileName
  1324. }
  1325. If (FNI.Action != 4 && (FileTo . FileFrom) !="")
  1326. @[LP].Func(FileFrom=""?FileFromOptional:FileFrom,FileTo)
  1327. }
  1328. } Until (!FNI.NextEntryOffset || ((FNI[]+FNI.NextEntryOffset) > (@[LP].FNI[]+sizeof_FNI-12)))
  1329. DllCall("ResetEvent","UInt",@[LP].O.hEvent)
  1330. DllCall("ReadDirectoryChangesW","UInt",@[LP].hD,"UInt",@[LP].FNI[],"UInt",sizeof_FNI
  1331. ,"Int",@[LP].sD,"UInt",@[LP].CNG,"UInt",0,"UInt",@[LP].O[],"UInt",0)
  1332. timer:=DllCall("SetTimer","Uint",0,"UInt",timer,"Uint",50,"UInt",WatchDirectory)
  1333. Return
  1334. }
  1335. Return
  1336. }
  1337. ;Clamps a value
  1338. Clamp(value, min, max)
  1339. {
  1340. if(value < min)
  1341. value := min
  1342. else if(value > max)
  1343. value := max
  1344. return value
  1345. }
  1346. ;Generates 7plus version string
  1347. VersionString(Short = 0)
  1348. {
  1349. global
  1350. if(Short)
  1351. return MajorVersion "." MinorVersion "." BugfixVersion
  1352. else
  1353. return MajorVersion "." MinorVersion "." BugfixVersion "." PatchVersion
  1354. }
  1355. ;Generates an UUID
  1356. uuid(c = false) { ; v1.1 - by Titan
  1357. static n = 0, l, i
  1358. f := A_FormatInteger, t := A_Now, s := "-"
  1359. SetFormat, Integer, H
  1360. t -= 1970, s
  1361. t := (t . A_MSec) * 10000 + 122192928000000000
  1362. If !i and c {
  1363. Loop, HKLM, System\MountedDevices
  1364. If i := A_LoopRegName
  1365. Break
  1366. StringGetPos, c, i, %s%, R2
  1367. StringMid, i, i, c + 2, 17
  1368. } Else {
  1369. Random, x, 0x100, 0xfff
  1370. Random, y, 0x10000, 0xfffff
  1371. Random, z, 0x100000, 0xffffff
  1372. x := 9 . SubStr(x, 3) . s . 1 . SubStr(y, 3) . SubStr(z, 3)
  1373. } t += n += l = A_Now, l := A_Now
  1374. SetFormat, Integer, %f%
  1375. Return, SubStr(t, 10) . s . SubStr(t, 6, 4) . s . 1 . SubStr(t, 3, 3) . s . (c ? i : x)
  1376. }
  1377. ;Extracted from HotkeyIts WatchDirectory function
  1378. ConvertFilterStringToRegex(FilterString)
  1379. {
  1380. StringToRegEx := "\\\|.\.|+\+|[\[|{\{|(\(|)\)|^\^|$\$|?\.?|*.*"
  1381. Loop,Parse,StringToRegEx,|
  1382. StringReplace,FilterString,FilterString,% SubStr(A_LoopField,1,1),% SubStr(A_LoopField,2),A
  1383. StringReplace,FilterString,FilterString,%A_Space%,\s,A
  1384. return "i)" FilterString
  1385. }
  1386. ;Gets client area of a window
  1387. GetClientRect(hwnd)
  1388. {
  1389. VarSetCapacity(rc, 16)
  1390. result := DllCall("GetClientRect", "PTR", hwnd, "PTR", &rc, "UINT")
  1391. return {x : NumGet(rc, 0, "int"), y : NumGet(rc, 4, "int"), w : NumGet(rc, 8, "int"), h : NumGet(rc, 12, "int")}
  1392. }
  1393. ;Gets the selected text by copying it to the clipboard.
  1394. ;OnClipboardChange ignores this due to MuteClipboardList flag, however, calling this function changes the clipboard owner to AHK.
  1395. GetSelectedText()
  1396. {
  1397. global MuteClipboardList
  1398. MuteClipboardList := true
  1399. clipboardbackup := clipboardall
  1400. clipboard := ""
  1401. WaitForEvent("ClipboardChange", 100)
  1402. Send ^c
  1403. WaitForEvent("ClipboardChange", 100)
  1404. result := clipboard
  1405. clipboard := clipboardbackup
  1406. WaitForEvent("ClipboardChange", 100)
  1407. MuteClipboardList := false
  1408. return result
  1409. }
  1410. ;Gets all kind of window information of open windows.
  1411. GetWindowInfo()
  1412. {
  1413. global WindowList
  1414. WS_EX_CONTROLPARENT :=0x10000
  1415. WS_EX_DLGMODALFRAME :=0x1
  1416. WS_CLIPCHILDREN :=0x2000000
  1417. WS_EX_APPWINDOW :=0x40000
  1418. WS_EX_TOOLWINDOW :=0x80
  1419. WS_DISABLED :=0x8000000
  1420. WS_VSCROLL :=0x200000
  1421. WS_POPUP :=0x80000000
  1422. windows := Array()
  1423. DetectHiddenWindows, Off
  1424. WinGet, Window_List, List ; Gather a list of running programs
  1425. hInstance := GetModuleHandle(0)
  1426. order := 0
  1427. Loop, %Window_List%
  1428. {
  1429. wid := Window_List%A_Index%
  1430. WinGetTitle, wid_Title, ahk_id %wid%
  1431. WinGet, Style, Style, ahk_id %wid%
  1432. If ((Style & WS_DISABLED) or ! (wid_Title)) ; skip unimportant windows ; ! wid_Title or
  1433. Continue
  1434. WinGet, es, ExStyle, ahk_id %wid%
  1435. Parent := Parent := GetParent(wid)
  1436. WinGet, Style_parent, Style, ahk_id %Parent%
  1437. Owner := Owner := GetWindow(wid, 4) ; GW_OWNER = 4
  1438. WinGet, Style_Owner, Style, ahk_id %Owner%
  1439. If (((es & WS_EX_TOOLWINDOW) and !(Parent)) ; filters out program manager, etc
  1440. or ( !(es & WS_EX_APPWINDOW)
  1441. and (((Parent) and ((Style_parent & WS_DISABLED) =0)) ; These 2 lines filter out windows that have a parent or owner window that is NOT disabled -
  1442. or ((Owner) and ((Style_Owner & WS_DISABLED) =0))))) ; NOTE - some windows result in blank value so must test for zero instead of using NOT operator!
  1443. continue
  1444. if(wid_Title = CAccessor.Instance.GUI.Title)
  1445. continue
  1446. if(WindowList.HasKey(wid))
  1447. Exe_Name := WindowList[wid].Executable
  1448. else
  1449. WinGet, Exe_Name, ProcessName, ahk_id %wid%
  1450. WinGet, PID, PID, ahk_id %wid%
  1451. FullPath := GetModuleFileNameEx(PID)
  1452. WinGetClass, Win_Class, ahk_id %wid%
  1453. hw_popup := hw_popup := DllCall("GetLastActivePopup", "Ptr", wid)
  1454. Dialog := 0 ; init/reset
  1455. If (Parent and ! Style_parent)
  1456. CPA_file_name := GetCPA_file_name( wid ) ; check if it's a control panel window
  1457. Else
  1458. CPA_file_name =
  1459. If (CPA_file_name or (Win_Class ="#32770") or ((style & WS_POPUP) and (es & WS_EX_DLGMODALFRAME)))
  1460. Dialog =1 ; found a Dialog window
  1461. If (CPA_file_name)
  1462. hIcon := ExtractIcon(hInstance, CPA_file_name, 1)
  1463. Else
  1464. hIcon := GetWindowIcon(wid, 1) ; (window id, whether to get large icons)
  1465. order++
  1466. windows.Insert(Object("hwnd",wid,"Title", wid_Title, "Class", Win_Class, "Style", Style, "ExStyle", es, "ExeName", Exe_Name, "Path", FullPath, "OnTop", (es&0x8 > 0 ? "On top" : ""), "PID", PID, "Order", order, "Type", "Window", "Icon", hIcon))
  1467. }
  1468. return windows
  1469. }
  1470. ; (window id, whether to get large icons)
  1471. GetWindowIcon(wid, LargeIcons)
  1472. {
  1473. Local NR_temp, h_icon, Responding
  1474. ; check status of window - if window is responding or "Not Responding"
  1475. NR_temp =0 ; init
  1476. h_icon =
  1477. Responding := DllCall("SendMessageTimeout", "Ptr", wid, "UInt", 0x0, "Int", 0, "Int", 0, "UInt", 0x2, "UInt", 150, "UInt *", NR_temp) ; 150 = timeout in millisecs
  1478. If (Responding)
  1479. {
  1480. ; WM_GETICON values - ICON_SMALL =0, ICON_BIG =1, ICON_SMALL2 =2
  1481. If LargeIcons =1
  1482. {
  1483. SendMessage, 0x7F, 1, 0,, ahk_id %wid%
  1484. h_icon := ErrorLevel
  1485. }
  1486. If ( ! h_icon )
  1487. {
  1488. SendMessage, 0x7F, 2, 0,, ahk_id %wid%
  1489. h_icon := ErrorLevel
  1490. If ( ! h_icon )
  1491. {
  1492. SendMessage, 0x7F, 0, 0,, ahk_id %wid%
  1493. h_icon := ErrorLevel
  1494. If ( ! h_icon )
  1495. {
  1496. If LargeIcons =1
  1497. h_icon := DllCall( "GetClassLong" (A_PtrSize = 8 ? "Ptr" : ""), "Ptr", wid, "int", -14, UPtr) ; GCL_HICON is -14
  1498. If ( ! h_icon )
  1499. {
  1500. h_icon := DllCall( "GetClassLong" (A_PtrSize = 8 ? "Ptr" : ""), "Ptr", wid, "int", -34, UPtr) ; GCL_HICONSM is -34
  1501. If ( ! h_icon )
  1502. h_icon := DllCall( "LoadIcon", "Ptr", 0, "uint", 32512 ) ; IDI_APPLICATION is 32512
  1503. }
  1504. }
  1505. }
  1506. }
  1507. }
  1508. If ! ( h_icon = "" or h_icon = "FAIL") ; Add the HICON directly to the icon list
  1509. return h_icon
  1510. Else ; use a generic icon
  1511. return Accessor.GenericIcons.Application
  1512. }
  1513. ; retrives Control Panel applet icon
  1514. GetCPA_file_name( p_hw_target )
  1515. {
  1516. WinGet, pid_target, PID, ahk_id %p_hw_target%
  1517. hp_target := DllCall( "OpenProcess", "uint", 0x18, "int", false, "uint", pid_target, "Ptr")
  1518. hm_kernel32 := GetModuleHandle("kernel32.dll")
  1519. pGetCommandLine := DllCall( "GetProcAddress", "Ptr", hm_kernel32, "str", A_IsUnicode ? "GetCommandLineW" : "GetCommandLineA")
  1520. buffer_size := 6
  1521. VarSetCapacity( buffer, buffer_size )
  1522. DllCall( "ReadProcessMemory", "Ptr", hp_target, "uint", pGetCommandLine, "uint", &buffer, "uint", buffer_size, "uint", 0 )
  1523. loop, 4
  1524. ppCommandLine += ( ( *( &buffer+A_Index ) ) << ( 8*( A_Index-1 ) ) )
  1525. buffer_size := 4
  1526. VarSetCapacity( buffer, buffer_size, 0 )
  1527. DllCall( "ReadProcessMemory", "Ptr", hp_target, "uint", ppCommandLine, "uint", &buffer, "uint", buffer_size, "uint", 0 )
  1528. loop, 4
  1529. pCommandLine += ( ( *( &buffer+A_Index-1 ) ) << ( 8*( A_Index-1 ) ) )
  1530. buffer_size := 260
  1531. VarSetCapacity( buffer, buffer_size, 1 )
  1532. DllCall( "ReadProcessMemory", "Ptr", hp_target, "uint", pCommandLine, "uint", &buffer, "uint", buffer_size, "uint", 0 )
  1533. DllCall( "CloseHandle", "Ptr", hp_target )
  1534. IfInString, buffer, desk.cpl ; exception to usual string format
  1535. return, "C:\WINDOWS\system32\desk.cpl"
  1536. ix_b := InStr( buffer, "Control_RunDLL" )+16
  1537. ix_e := InStr( buffer, ".cpl", false, ix_b )+3
  1538. StringMid, CPA_file_name, buffer, ix_b, ix_e-ix_b+1
  1539. if ( ix_e )
  1540. return, CPA_file_name
  1541. else
  1542. return, false
  1543. }
  1544. ;gets CPU Usage
  1545. GetSystemTimes() ;Total CPU Load
  1546. {
  1547. Static oldIdleTime, oldKrnlTime, oldUserTime
  1548. Static newIdleTime, newKrnlTime, newUserTime
  1549. oldIdleTime := newIdleTime
  1550. oldKrnlTime := newKrnlTime
  1551. oldUserTime := newUserTime
  1552. DllCall("GetSystemTimes", "int64P", newIdleTime, "int64P", newKrnlTime, "int64P", newUserTime)
  1553. Return (1 - (newIdleTime-oldIdleTime)/(newKrnlTime-oldKrnlTime + newUserTime-oldUserTime)) * 100
  1554. }
  1555. ;Starts a timer that can call functions and object methods
  1556. SetTimerF( Function, Period=0, ParmObject=0, Priority=0 ) {
  1557. Static current,tmrs:=Object() ;current will hold timer that is currently running
  1558. If IsFunc( Function ) || IsObject( Function ){
  1559. if IsObject(tmr:=tmrs[Function]) ;destroy timer before creating a new one
  1560. ret := DllCall( "KillTimer", UInt,0, UInt, tmr.tmr)
  1561. , DllCall("GlobalFree", UInt, tmr.CBA)
  1562. , tmrs.Remove(Function)
  1563. if (Period = 0 || Period ? "off")
  1564. return ret ;Return as we want to turn off timer
  1565. ; create object that will hold information for timer, it will be passed trough A_EventInfo when Timer is launched
  1566. tmr:=tmrs[Function]:=Object("func",Function,"Period",Period="on" ? 250 : Period,"Priority",Priority
  1567. ,"OneTime",(Period<0),"params",IsObject(ParmObject)?ParmObject:Object()
  1568. ,"Tick",A_TickCount)
  1569. tmr.CBA := RegisterCallback(A_ThisFunc,"F",4,&tmr)
  1570. return !!(tmr.tmr := DllCall("SetTimer", UInt,0, UInt,0, UInt
  1571. , (Period && Period!="On") ? Abs(Period) : (Period := 250)
  1572. , UInt,tmr.CBA)) ;Create Timer and return true if a timer was created
  1573. , tmr.Tick:=A_TickCount
  1574. }
  1575. tmr := Object(A_EventInfo) ;A_Event holds object which contains timer information
  1576. if IsObject(tmr) {
  1577. DllCall("KillTimer", UInt,0, UInt,tmr.tmr) ;deactivate timer so it does not run again while we are processing the function
  1578. If (!tmr.active && tmr.Priority<(current.priority ? current.priority : 0)) ;Timer with higher priority is already current so return
  1579. Return (tmr.tmr:=DllCall("SetTimer", UInt,0, UInt,0, UInt, 100, UInt,tmr.CBA)) ;call timer again asap
  1580. current:=tmr
  1581. tmr.tick:=ErrorLevel :=Priority ;update tick to launch function on time
  1582. func := tmr.func.(tmr.params*) ;call function
  1583. current= ;reset timer
  1584. if (tmr.OneTime) ;One time timer, deactivate and delete it
  1585. return DllCall("GlobalFree", UInt,tmr.CBA)
  1586. ,tmrs.Remove(tmr.func)
  1587. tmr.tmr:= DllCall("SetTimer", UInt,0, UInt,0, UInt ;reset timer
  1588. ,((A_TickCount-tmr.Tick) > tmr.Period) ? 0 : (tmr.Period-(A_TickCount-tmr.Tick)), UInt,tmr.CBA)
  1589. }
  1590. }
  1591. ;Duplicates an icon. The copy needs to be deleted with DestroyIcon.
  1592. DuplicateIcon(hIcon)
  1593. {
  1594. return DllCall("Shell32.dll\DuplicateIcon", "PTR", 0, "Ptr", hIcon, "PTR")
  1595. }
  1596. ;Returns an object containing the area of the monitor in pixels where the mouse cursor currently is
  1597. FindMonitorFromMouseCursor()
  1598. {
  1599. CoordMode, Mouse, Screen
  1600. MouseGetPos, x, y
  1601. SysGet, Mon0, MonitorCount
  1602. Loop %Mon0%
  1603. { ;Loop through each monitor
  1604. SysGet, Mon%A_Index%, Monitor, %A_Index%
  1605. if(x >= Mon%A_Index%Left && x < Mon%A_Index%Right && y >= Mon%A_Index%Top && y < Mon%A_Index%Bottom)
  1606. return {Index : A_Index, Left : Mon%A_Index%Left, Top : Mon%A_Index%Top, Right : Mon%A_Index%Right, Bottom : Mon%A_Index%Bottom}
  1607. }
  1608. }
  1609. ;Determines if this script is running as 32bit version in a 64bit OS
  1610. IsWow64Process()
  1611. {
  1612. ThisProcess := DllCall("GetCurrentProcess")
  1613. ; If IsWow64Process() fails or can not be found,
  1614. ; assume this process is not running under wow64.
  1615. ; Otherwise, use the value returned in IsWow64Process.
  1616. if !DllCall("IsWow64Process", "PTR", ThisProcess, "PTR*", IsWow64Process)
  1617. IsWow64Process := false
  1618. return IsWow64Process
  1619. }
  1620. ;Shows icon picker dialog. Returns true if OK is pressed, false if cancelled.
  1621. PickIcon(ByRef sIconPath, ByRef nIndex)
  1622. {
  1623. VarSetCapacity(IconPath, 260 * 2, 0)
  1624. nIndex--
  1625. DllCall("shell32\PickIconDlg", "Ptr", 0, "str", IconPath, "Uint", 260, "PTRP", nIndex)
  1626. if(IconPath)
  1627. {
  1628. sIconPath := IconPath
  1629. nIndex++
  1630. return true
  1631. }
  1632. nIndex++
  1633. return false
  1634. }
  1635. ;Append two paths together and treat possibly double or missing backslashes
  1636. AppendPaths(BasePath, RelativePath)
  1637. {
  1638. if(!BasePath)
  1639. return RelativePath
  1640. if(!RelativePath)
  1641. return BasePath
  1642. return strTrimRight(BasePath, "\") "\" strTrimLeft(RelativePath, "\")
  1643. }
  1644. ;Add quotes around a string if necessary
  1645. Quote(string, once = 1)
  1646. {
  1647. if(once)
  1648. {
  1649. if(InStr(string, """") != 1)
  1650. string := """" string
  1651. if(!strEndsWith(string, """"))
  1652. string := string """"
  1653. return string
  1654. }
  1655. return """" string """"
  1656. }
  1657. ;Remove quotes from a string if necessary
  1658. UnQuote(string)
  1659. {
  1660. if(InStr(string, """") = 1 && strEndsWith(string, """"))
  1661. return strTrim(string, """")
  1662. return string
  1663. }
  1664. ;This function separates a list of file paths into two lists,
  1665. ;where one contains the files that have one of the extensions specified in extensions and one (SplitFiles) that doesn't
  1666. SplitByExtension(ByRef files, ByRef SplitFiles, extensions)
  1667. {
  1668. ;Init string incase it wasn't resetted before or so
  1669. SplitFiles := Array()
  1670. newFiles := Array()
  1671. for index, file in files
  1672. {
  1673. SplitPath, file , , , OutExtension
  1674. if (InStr(extensions, OutExtension) && OutExtension != "")
  1675. SplitFiles.Insert(file)
  1676. else
  1677. newFiles.Insert(file)
  1678. }
  1679. files := newFiles
  1680. return
  1681. }
  1682. ;This function makes an absolute path relative to a base path
  1683. MakeRelativePath(AbsolutePath, BasePath)
  1684. {
  1685. if(InStr(AbsolutePath, BasePath) != 1)
  1686. {
  1687. MsgBox MakeRelativePath: %AbsolutePath% doesn't start with %BasePath%
  1688. return ""
  1689. }
  1690. RelativePath := SubStr(AbsolutePath, StrLen(BasePath) + 1)
  1691. RelativePath := strTrimLeft(RelativePath, ["\", "/"])
  1692. return RelativePath
  1693. }
  1694. ;These two functions are used to convert an icon resource id (as those used in the registry) to icon index(as used by ahk)
  1695. ;By Lexikos http://www.autohotkey.com/community/viewtopic.php?p=168951
  1696. IndexOfIconResource(Filename, ID)
  1697. {
  1698. hmod := DllCall("GetModuleHandle", "str", Filename, "PTR")
  1699. ; If the DLL isn't already loaded, load it as a data file.
  1700. loaded := !hmod
  1701. && hmod := DllCall("LoadLibraryEx", "str", Filename, "PTR", 0, "uint", 0x2)
  1702. enumproc := RegisterCallback("IndexOfIconResource_EnumIconResources","F")
  1703. VarSetCapacity(param,12,0)
  1704. NumPut(ID,param,0)
  1705. ; Enumerate the icon group resources. (RT_GROUP_ICON=14)
  1706. DllCall("EnumResourceNames", "uint", hmod, "uint", 14, "uint", enumproc, "PTR", &param)
  1707. DllCall("GlobalFree", "PTR", enumproc)
  1708. ; If we loaded the DLL, free it now.
  1709. if loaded
  1710. DllCall("FreeLibrary", "PTR", hmod)
  1711. return NumGet(param,8) ? NumGet(param,4) : 0
  1712. }
  1713. IndexOfIconResource_EnumIconResources(hModule, lpszType, lpszName, lParam)
  1714. {
  1715. NumPut(NumGet(lParam+4)+1, lParam+4)
  1716. if (lpszName = NumGet(lParam+0))
  1717. {
  1718. NumPut(1, lParam+8)
  1719. return false ; break
  1720. }
  1721. return true
  1722. }
  1723. ;Tries to read from HKCU and then from HKLM if not found
  1724. RegReadUser(Key, Name)
  1725. {
  1726. RegRead, value, HKCU, %Key%, %Name%
  1727. if(ErrorLevel)
  1728. RegRead, value, HKLM, %Key%, %Name%
  1729. return value
  1730. }
  1731. ;Expand path placeholders like %ProgramFiles% or %TEMP%.
  1732. ;It's basically ExpandEnvironmentStrings() with some additional directories
  1733. ExpandPathPlaceholders(InputString)
  1734. {
  1735. static Replacements := { "Desktop" : GetFullPathName(A_Desktop)
  1736. , "MyDocuments" : GetFullPathName(A_MyDocuments)
  1737. , "StartMenu" : GetFullPathName(A_StartMenu)
  1738. , "StartMenuCommon" : GetFullPathName(A_StartMenuCommon)
  1739. , "7plusDrive" : ""
  1740. , "7plusDir" : A_ScriptDir
  1741. , "ImageEditor" : ""
  1742. , "TextEditor" : ""}
  1743. if(!Replacements.7plusDrive)
  1744. {
  1745. SplitPath, A_ScriptDir,,,,,s7plusDrive
  1746. Replacements.7plusDrive := s7plusDrive
  1747. }
  1748. Replacements.ImageEditor := Settings.Misc.DefaultImageEditor
  1749. Replacements.TextEditor := Settings.Misc.DefaultTextEditor
  1750. for Placeholder, Replacement in Replacements
  1751. while(InStr(InputString, Placeholder) && A_Index < 10)
  1752. StringReplace, InputString, InputString, % "%" Placeholder "%", % Replacement, All
  1753. ; get the required size for the expanded string
  1754. SizeNeeded := DllCall("ExpandEnvironmentStrings", "Str", InputString, "PTR", 0, "Int", 0)
  1755. if(SizeNeeded == "" || SizeNeeded <= 0)
  1756. return InputString ; unable to get the size for the expanded string for some reason
  1757. ByteSize := SizeNeeded * 2 + 2
  1758. VarSetCapacity(TempValue, ByteSize, 0)
  1759. ; attempt to expand the environment string
  1760. if(!DllCall("ExpandEnvironmentStrings", "Str", InputString, "Str", TempValue, "Int", SizeNeeded))
  1761. return InputString ; unable to expand the environment string
  1762. return TempValue
  1763. }
  1764. ;Gets (and sets) LoWord of first parameter (to the value of the second parameter)
  1765. LoWord(value*)
  1766. {
  1767. if(value.MaxIndex() = 1)
  1768. return value[1] & 0x0000FFFF
  1769. else if(value.MaxIndex() = 2)
  1770. return (value[1] & 0xFFFF0000) + (value[2] & 0x0000FFFF)
  1771. }
  1772. ;Gets (and sets) HiWord of first parameter (to the value of the second parameter)
  1773. HiWord(value*)
  1774. {
  1775. if(value.MaxIndex() = 1)
  1776. return value[1] & 0xFFFF0000
  1777. else if(value.MaxIndex() = 2)
  1778. return (value[1] & 0x0000FFFF) + (value[2] << 16)
  1779. }
  1780. HighWord(value*)
  1781. {
  1782. return value & 0xFFFF0000
  1783. }
  1784. #include <CGUI>
  1785. #include <ObjectTools>
  1786. Class CInputWindow extends CGUI
  1787. {
  1788. editText := this.AddControl("Edit", "editText", "x10 y10 w300", "")
  1789. btnOK := this.AddControl("Button", "btnOK", "x180 y+10 Default w50", "&OK")
  1790. btnCancel := this.AddControl("Button", "btnCancel", "x+10 w70", "&Cancel")
  1791. static EM_SETSEL := 0x00B1
  1792. __new(Text)
  1793. {
  1794. this.ActiveControl := this.editText
  1795. this.editText.Text := Text
  1796. this.DestroyOnClose := true
  1797. this.CloseOnEscape := true
  1798. }
  1799. WaitForInput()
  1800. {
  1801. this.Show()
  1802. SendMessage, this.EM_SETSEL, 0, -1, , % "ahk_id " this.editText.hwnd
  1803. while(!this.IsDestroyed)
  1804. Sleep 10
  1805. return result
  1806. }
  1807. WaitForInputAsync(OnCloseHandler)
  1808. {
  1809. this.Show()
  1810. SendMessage, this.EM_SETSEL, 0, -1, , % "ahk_id " this.editText.hwnd
  1811. this.OnClose.Handler := OnCloseHandler
  1812. }
  1813. btnCancel_Click()
  1814. {
  1815. this.Close()
  1816. }
  1817. btnOK_Click()
  1818. {
  1819. this.result := this.editText.Text
  1820. this.Close()
  1821. }
  1822. }
  1823. New(Obj, Params*)
  1824. {
  1825. return value := new Obj(Params*)
  1826. }
  1827. ;Loads an icon from a path and returns the hIcon. Needs to be freed afterwards with DestroyIcon()
  1828. LoadIcon(Path)
  1829. {
  1830. return DllCall("LoadImage", "PTR", 0, "str", Path, "uint", IMAGE_ICON := 1, "int", 0, "int", 0, "uint", LD_LOADFROMFILE := 0x00000010, "PTR")
  1831. }
  1832. ;Supports paths, icon handles and hBitmaps
  1833. GetBitmapFromAnything(Anything)
  1834. {
  1835. if(FileExist(Anything))
  1836. {
  1837. pBitmap :=