Advertisement
Guest User

GdOcrTool_Cross.ahk

a guest
Nov 20th, 2021
181
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.43 KB | None | 0 0
  1. ;=======================================================================================
  2. ; GdOcrTool.ahk is an AutoHotkey (v1.1) script to enhance the GoldenDict with OCR
  3. ; functionality using Capture2Text.
  4. ; Written by Johnny Van, 2021/11/13
  5. ; Updated 2021/11/14, add support for MDict, Eudic.
  6. ; Updated 2021/11/19, add visual feedback for single word capture.
  7. ; Updated 2021/11/21, added + mouse pointer.
  8. ;=======================================================================================
  9. ; Auto-execution section.
  10.  
  11. #NoEnv
  12. #SingleInstance, force
  13. SendMode Input
  14. SetWorkingDir %A_ScriptDir%
  15. SetBatchLines -1
  16. CoordMode, ToolTip, Screen
  17. DetectHiddenWindows, On
  18.  
  19. ;Global GoldenDictFileName := "C:\Program Files\GoldenDict\GoldenDict.exe"
  20. Global GoldenDictFileName := ".\GoldenDict.exe"
  21. Global MdictFileName := "C:\Program Files\MDictPC\MDict.exe"
  22. Global EudicFileName := "C:\Program Files (x86)\eudic\eudic.exe"
  23. ;Global Capture2TextFileName := A_ScriptDir . "\Capture2Text.exe"
  24. Global Capture2TextFileName := ".\Capture2Text\Capture2Text.exe"
  25. Global DictSelected := "GoldenDict" ; Dictionary selected: "GoldenDict", "MDict", "Eudic"
  26. Global CaptureMode := "NoCapture" ; Capture mode: "NoCapture", "SingleWordCapture", "BoxCapture"
  27. Global CaptureCount := 0
  28. Global LineCaptured := ""
  29. Global ForwardLineCaptured := ""
  30. Global Timeout := 8000 ; Timeout in millisecond. Abort capture if the timeout has expired.
  31. Global StartTime, EndTime
  32.  
  33. Main()
  34.  
  35. ;=======================================================================================
  36. ;
  37.  
  38. Main() {
  39. Menu, Tray, Icon, shell32.dll, 172
  40.  
  41. If !FileExist(Capture2TextFileName) {
  42. MsgBox, 48, Warning, Capture2Text.exe not found! Exiting program...
  43. ExitApp
  44. } Else {
  45. Run % Capture2TextFileName
  46. }
  47.  
  48. Switch DictSelected {
  49. Case "GoldenDict":
  50. If !FileExist(GoldenDictFileName) {
  51. MsgBox, 48, Warning, GoldenDict.exe not found! Exiting program...
  52. ExitApp
  53. } Else If !WinExist("ahk_exe GoldenDict.exe") {
  54. Run % GoldenDictFileName
  55. }
  56. Case "MDict":
  57. If !FileExist(MDictFileName) {
  58. MsgBox, 48, Warning, MDict.exe not found! Exiting program...
  59. ExitApp
  60. } Else If !WinExist("ahk_exe MDict.exe") {
  61. Run % MDictFileName
  62. }
  63. Case "Eudic":
  64. If !FileExist(EudicFileName) {
  65. MsgBox, 48, Warning, eudic.exe not found! Exiting program...
  66. ExitApp
  67. } Else If !WinExist("ahk_exe eudic.exe") {
  68. Run % EudicFileName
  69. }
  70. }
  71.  
  72. OnClipboardChange("ClipboardChange")
  73. Return
  74. }
  75.  
  76. ; Monitoring clipboard change.
  77. ClipboardChange(Type) {
  78. ; 0 = Clipboard is now empty.
  79. ; 1 = Clipboard contains something that can be expressed as text (this includes files copied from an Explorer window).
  80. ; 2 = Clipboard contains something entirely non-text such as a picture.
  81. If (Type != 1) {
  82. Return
  83. }
  84.  
  85. Switch CaptureMode {
  86. Case "NoCapture":
  87. Return
  88. Case "SingleWordCapture":
  89. SingleWordCaptureHandler()
  90. Case "BoxCapture":
  91. BoxCaptureHandler()
  92. }
  93.  
  94. Return
  95. }
  96.  
  97. SingleWordCaptureHandler() {
  98. CaptureCount += 1
  99. Switch CaptureCount {
  100. Case 1:
  101. ; ClipboardChange invoked by line capture.
  102. LineCaptured := Clipboard
  103. StartForwardLineCapture()
  104. Case 2:
  105. ; ClipboardChange invoked by forward line capture.
  106. ResetCaptureMode()
  107. ForwardLineCaptured := Clipboard
  108. ArrayTemp := ExtractSingleWord()
  109. SearchTerm := ArrayTemp[1]
  110. ExtractError := ArrayTemp[2]
  111. If !ExtractError {
  112. SendToSelectedDict(SearchTerm)
  113. ToolTip % SearchTerm
  114. SetTimer, TurnOffToolTip, -1000
  115. }
  116. Default:
  117. ResetCaptureMode()
  118. }
  119. Return
  120. }
  121.  
  122. BoxCaptureHandler() {
  123. ResetCaptureMode()
  124. SendToSelectedDict(Clipboard)
  125.  
  126. Return
  127. }
  128.  
  129. ; Extract the single word from the two-step OCR.
  130. ExtractSingleWord() {
  131. ExtractError := 0
  132.  
  133. ForwardLineCapturedPos := InStr(LineCaptured, ForwardLineCaptured)
  134. If (ForwardLineCapturedPos == 0) {
  135. ExtractError := 1
  136. ToolTip, Recognition failed.
  137. SetTimer, TurnOffToolTip, -1000
  138. Return ["", ExtractError]
  139. }
  140.  
  141. FrontString := SubStr(LineCaptured, 1, ForwardLineCapturedPos-1)
  142. ArrayTemp := StrSplit(FrontString, A_Space)
  143. SearchTermFront := ArrayTemp[ArrayTemp.Length()]
  144. ArrayTemp := StrSplit(ForwardLineCaptured, A_Space)
  145. SearchTermEnd := ArrayTemp[1]
  146. SearchTerm := SearchTermFront . SearchTermEnd
  147. SearchTerm := Trim(SearchTerm, ",.!?:;“”'""/()[]{}<>")
  148.  
  149. Return [SearchTerm, ExtractError]
  150. }
  151.  
  152. SendToSelectedDict(SearchTerm) {
  153. Switch DictSelected {
  154. Case "GoldenDict":
  155. SendToGoldenDict(SearchTerm)
  156. Case "MDict":
  157. SendToMDict(SearchTerm)
  158. Case "Eudic":
  159. SendToEudic(SearchTerm)
  160. }
  161. Return
  162. }
  163.  
  164. ; Send the captured text to GoldenDict.
  165. SendToGoldenDict(SearchTerm) {
  166. SearchTermCli := """" . StrReplace(SearchTerm, """", """""") . """"
  167. Run, %GoldenDictFileName% %SearchTermCli%
  168. Return
  169. }
  170.  
  171. ; Send the captured text to MDict.
  172. SendToMDict(SearchTerm) {
  173. Clipboard := SearchTerm
  174. Run, %MdictFileName%
  175. WinWait, ahk_exe MDict.exe, , 0.2
  176. If WinActive("ahk_exe MDict.exe") {
  177. Send, ^v
  178. Sleep, 50
  179. Send, {Enter}
  180. }
  181. Return
  182. }
  183.  
  184. ; Send the captured text to Eudic.
  185. SendToEudic(SearchTerm) {
  186. Clipboard := SearchTerm
  187. Run, %EudicFileName%
  188. WinWait, ahk_exe eudic.exe, , 0.2
  189. If WinActive("ahk_exe eudic.exe") {
  190. Send, ^v
  191. Sleep, 50
  192. Send, {Enter}
  193. }
  194. Return
  195. }
  196.  
  197. ResetCaptureMode() {
  198. CaptureMode := "NoCapture"
  199. CaptureCount := 0
  200. SetTimer, CaptureTimeout, Off
  201. Return
  202. }
  203.  
  204. CaptureTimeout() {
  205. EndTime := A_TickCount
  206. ElapsedTime := EndTime - StartTime
  207. If (ElapsedTime > Timeout) {
  208. ResetCaptureMode()
  209. ToolTip, Timeout has expired. Aborting capture.
  210. SetTimer, TurnOffToolTip, -1000
  211. }
  212. Return
  213. }
  214.  
  215. TurnOffToolTip() {
  216. ToolTip
  217. Return
  218. }
  219. ;=======================================================================================
  220. ; Hotkeys
  221.  
  222. ^RButton:: ; Capture a single word by pressing ctrl + right click.
  223. SingleWordCapture() {
  224. If !WinExist("ahk_exe Capture2Text.exe") {
  225. MsgBox, 48, Warning, Capture2Text is not running! Aborting single word capture.
  226. Run % Capture2TextFileName
  227. Return
  228. }
  229. StartTime := A_TickCount
  230. CaptureMode := "SingleWordCapture"
  231. CaptureCount := 0
  232. StartLineCapture()
  233. SetTimer, CaptureTimeout, 1000
  234. Return
  235. }
  236.  
  237. ; --------------Added on 2021/11/21
  238.  
  239. ^`::SetSystemCursor("IDC_CROSS")+BoxCapture() ; Start box capture by pressing ctrl + `
  240. ^q::RestoreCursors()
  241.  
  242.  
  243. SetSystemCursor( Cursor = "", cx = 0, cy = 0 )
  244. {
  245. BlankCursor := 0, SystemCursor := 0, FileCursor := 0 ; init
  246.  
  247. SystemCursors = 32512IDC_ARROW,32513IDC_IBEAM,32514IDC_WAIT,32515IDC_CROSS
  248. ,32516IDC_UPARROW,32640IDC_SIZE,32641IDC_ICON,32642IDC_SIZENWSE
  249. ,32643IDC_SIZENESW,32644IDC_SIZEWE,32645IDC_SIZENS,32646IDC_SIZEALL
  250. ,32648IDC_NO,32649IDC_HAND,32650IDC_APPSTARTING,32651IDC_HELP
  251.  
  252. If Cursor = ; empty, so create blank cursor
  253. {
  254. VarSetCapacity( AndMask, 32*4, 0xFF ), VarSetCapacity( XorMask, 32*4, 0 )
  255. BlankCursor = 1 ; flag for later
  256. }
  257. Else If SubStr( Cursor,1,4 ) = "IDC_" ; load system cursor
  258. {
  259. Loop, Parse, SystemCursors, `,
  260. {
  261. CursorName := SubStr( A_Loopfield, 6, 15 ) ; get the cursor name, no trailing space with substr
  262. CursorID := SubStr( A_Loopfield, 1, 5 ) ; get the cursor id
  263. SystemCursor = 1
  264. If ( CursorName = Cursor )
  265. {
  266. CursorHandle := DllCall( "LoadCursor", Uint,0, Int,CursorID )
  267. Break
  268. }
  269. }
  270. If CursorHandle = ; invalid cursor name given
  271. {
  272. Msgbox,, SetCursor, Error: Invalid cursor name
  273. CursorHandle = Error
  274. }
  275. }
  276. Else If FileExist( Cursor )
  277. {
  278. SplitPath, Cursor,,, Ext ; auto-detect type
  279. If Ext = ico
  280. uType := 0x1
  281. Else If Ext in cur,ani
  282. uType := 0x2
  283. Else ; invalid file ext
  284. {
  285. Msgbox,, SetCursor, Error: Invalid file type
  286. CursorHandle = Error
  287. }
  288. FileCursor = 1
  289. }
  290. Else
  291. {
  292. Msgbox,, SetCursor, Error: Invalid file path or cursor name
  293. CursorHandle = Error ; raise for later
  294. }
  295. If CursorHandle != Error
  296. {
  297. Loop, Parse, SystemCursors, `,
  298. {
  299. If BlankCursor = 1
  300. {
  301. Type = BlankCursor
  302. %Type%%A_Index% := DllCall( "CreateCursor"
  303. , Uint,0, Int,0, Int,0, Int,32, Int,32, Uint,&AndMask, Uint,&XorMask )
  304. CursorHandle := DllCall( "CopyImage", Uint,%Type%%A_Index%, Uint,0x2, Int,0, Int,0, Int,0 )
  305. DllCall( "SetSystemCursor", Uint,CursorHandle, Int,SubStr( A_Loopfield, 1, 5 ) )
  306. }
  307. Else If SystemCursor = 1
  308. {
  309. Type = SystemCursor
  310. CursorHandle := DllCall( "LoadCursor", Uint,0, Int,CursorID )
  311. %Type%%A_Index% := DllCall( "CopyImage"
  312. , Uint,CursorHandle, Uint,0x2, Int,cx, Int,cy, Uint,0 )
  313. CursorHandle := DllCall( "CopyImage", Uint,%Type%%A_Index%, Uint,0x2, Int,0, Int,0, Int,0 )
  314. DllCall( "SetSystemCursor", Uint,CursorHandle, Int,SubStr( A_Loopfield, 1, 5 ) )
  315. }
  316. Else If FileCursor = 1
  317. {
  318. Type = FileCursor
  319. %Type%%A_Index% := DllCall( "LoadImageA"
  320. , UInt,0, Str,Cursor, UInt,uType, Int,cx, Int,cy, UInt,0x10 )
  321. DllCall( "SetSystemCursor", Uint,%Type%%A_Index%, Int,SubStr( A_Loopfield, 1, 5 ) )
  322. }
  323. }
  324. }
  325. Return
  326. }
  327.  
  328.  
  329. ;To restore system cursors use SystemParametersInfo/SPI_SETCURSORS
  330. RestoreCursors()
  331. {
  332. SPI_SETCURSORS := 0x57
  333. DllCall( "SystemParametersInfo", UInt,SPI_SETCURSORS, UInt,0, UInt,0, UInt,0 ) ; Reload the system cursors
  334. Return
  335. }
  336. ; --------------Added on 2021/11/21
  337.  
  338.  
  339. BoxCapture() {
  340. If !WinExist("ahk_exe Capture2Text.exe") {
  341. MsgBox, 48, Warning, Capture2Text is not running! Aborting box capture...
  342. Run % Capture2TextFileName
  343. Return
  344. }
  345. CaptureMode := "BoxCapture"
  346. ToolTip, Hold down left mouse button to start box capture.
  347. SetTimer, TurnOffToolTip, -1000
  348. Return
  349. }
  350.  
  351. ; Creates context-sensitive hotkeys.
  352. #If (CaptureMode == "BoxCapture")
  353.  
  354. LButton::
  355. LeftButtonDown() {
  356. TurnOffToolTip()
  357. StartBoxCapture()
  358. Return
  359. }
  360.  
  361. LButton Up::LeftButtonUp()+RestoreCursors()
  362.  
  363. LeftButtonUp() {
  364. Send, {LButton Down}
  365. StartTime := A_TickCount ; Start count down after box is drawn.
  366. SetTimer, CaptureTimeout, 1000
  367. ;RestoreCursors()
  368. Return
  369. }
  370.  
  371. Esc::ForceAbortBoxCapture()+RestoreCursors()
  372. ForceAbortBoxCapture() {
  373. ToolTip, Aborting box capture.
  374. SetTimer, TurnOffToolTip, -1000
  375. ResetCaptureMode()
  376. ;RestoreCursors()
  377. Return
  378. }
  379.  
  380. #If
  381.  
  382. ;=======================================================================================
  383. ; Call Capture2Text by sending hotkeys. Hotkeys are defined in Capture2Text.
  384.  
  385. StartLineCapture() {
  386. Send, ^+#e ; crtl + shift + win + e
  387. Return
  388. }
  389.  
  390. StartForwardLineCapture() {
  391. Send, ^+#w ; crtl + shift + win + w
  392. Return
  393. }
  394.  
  395. StartBoxCapture() {
  396. Send, ^+#q ; crtl + shift + win + q
  397. Return
  398. }
  399. ;=======================================================================================
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement