PageRenderTime 52ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/source/toolbar/ComInterface.ahk

http://github.com/fincs/SciTE4AutoHotkey
AutoHotKey | 399 lines | 312 code | 61 blank | 26 comment | 23 complexity | 89f512140a3e5c21e01d6a9544095a56 MD5 | raw file
  1. ;
  2. ; File encoding: UTF-8
  3. ;
  4. ; COM interface for SciTE4AutoHotkey
  5. ; version 1.0 - fincs
  6. ;
  7. ;------------------------------------------------------------------------------
  8. ; COM interface methods
  9. ;------------------------------------------------------------------------------
  10. class InvalidUsage
  11. {
  12. __Get(m, p*)
  13. {
  14. throw Exception("Property does not exist", m)
  15. }
  16. __Set(m, p*)
  17. {
  18. throw Exception("Property does not exist", m)
  19. }
  20. __Call(m, p*)
  21. {
  22. throw Exception("Method does not exist", m)
  23. }
  24. }
  25. CoI_CallEvent(event, args*)
  26. {
  27. badEvts := {}
  28. for cookie, handler in CoI.EventHandlers
  29. {
  30. try
  31. handler[event](args*)
  32. catch
  33. badEvts[cookie] := 1
  34. }
  35. for cookie in badEvts
  36. CoI.EventHandlers.Remove(cookie, "")
  37. }
  38. class CoI extends InvalidUsage
  39. {
  40. static EventHandlers := {}
  41. ConnectEvent(handler)
  42. {
  43. if !IsObject(handler)
  44. throw Exception("Invalid event handler")
  45. this.EventHandlers[&handler] := handler
  46. return &handler
  47. }
  48. DisconnectEvent(cookie)
  49. {
  50. this.EventHandlers.Remove(cookie, "")
  51. }
  52. Message(msg, wParam := 0, lParam := 0)
  53. {
  54. global _msg, _wParam, _lParam, scitehwnd, hwndgui, ATM_OFFSET
  55. if (_msg := msg+0) = "" || (_wParam := wParam+0) = "" || (_lParam := lParam+0) = ""
  56. return
  57. if (msg >= ATM_OFFSET)
  58. {
  59. ; Send message in a different thread in order to not crap out whilst exiting
  60. Critical
  61. SetTimer, SelfMessage, -10
  62. }else
  63. SendMessage, _msg, _wParam, _lParam,, ahk_id %scitehwnd%
  64. return ErrorLevel
  65. SelfMessage:
  66. PostMessage, _msg, _wParam, _lParam,, ahk_id %hwndgui%
  67. return
  68. }
  69. ReloadProps()
  70. {
  71. global scitehwnd
  72. SendMessage, 1024+1, 0, 0,, ahk_id %scitehwnd%
  73. }
  74. SciTEDir[]
  75. {
  76. get
  77. {
  78. global SciTEDir
  79. return SciTEDir
  80. }
  81. }
  82. IsPortable[]
  83. {
  84. get
  85. {
  86. global IsPortable
  87. return IsPortable
  88. }
  89. }
  90. UserDir[]
  91. {
  92. get
  93. {
  94. global LocalSciTEPath
  95. return LocalSciTEPath
  96. }
  97. }
  98. Tabs[]
  99. {
  100. get
  101. {
  102. global filesmenu
  103. static VT_BSTR := 8
  104. filescount := DllCall("GetMenuItemCount", "ptr", filesmenu, "int") - 5
  105. tabs := ComObjArray(VT_BSTR, filescount)
  106. ; This code is not 64-bit compatible.
  107. Loop, %filescount%
  108. ; Prepare a structure
  109. VarSetCapacity(MENUITEMINFO, 12*4, 0)
  110. ; MENUITEMINFO.cbSize = sizeof(MENUITEMINFO)
  111. , NumPut(12*4, MENUITEMINFO, "UInt")
  112. ; MENUITEMINFO.fMask = MIIM_STRING
  113. , NumPut(0x00000040, MENUITEMINFO, 1*4, "UInt")
  114. ; Get the size of the item name
  115. , DllCall("GetMenuItemInfo", "ptr", filesmenu, "uint", 4+A_Index, "int", 1, "ptr", &MENUITEMINFO)
  116. ; Prepare a buffer for holding the data
  117. , VarSetCapacity(_data, (cch := NumGet(MENUITEMINFO, 10*4, "UInt")) * (!!A_IsUnicode + 1))
  118. ; Fill the structure with the buffer
  119. , NumPut(&_data, MENUITEMINFO, 9*4), NumPut(cch + 1, MENUITEMINFO, 10*4, "UInt")
  120. ; Retrieve the item name
  121. , DllCall("GetMenuItemInfo", "ptr", filesmenu, "uint", 4+A_Index, "int", 1, "ptr", &MENUITEMINFO)
  122. , VarSetCapacity(_data, -1)
  123. ; Append the item to the list
  124. , tabs[A_Index-1] := RegExReplace(RegExReplace(_data, "^&\d\s"), "&&", "&")
  125. ; Return the Tabs object
  126. return new CoI.__Tabs(tabs)
  127. }
  128. }
  129. class __Tabs
  130. {
  131. __New(p)
  132. {
  133. this.p := p
  134. }
  135. Array[]
  136. {
  137. get
  138. {
  139. return this.p
  140. }
  141. }
  142. List[]
  143. {
  144. get
  145. {
  146. for item in this.p
  147. list .= item "`n"
  148. StringTrimRight, list, list, 1
  149. return list
  150. }
  151. }
  152. Count[]
  153. {
  154. get
  155. {
  156. return this.p.MaxIndex() + 1
  157. }
  158. }
  159. }
  160. SwitchToTab(idx)
  161. {
  162. global scitehwnd
  163. if IsObject(idx) || (idx+0) = ""
  164. return
  165. PostMessage, 0x111, 1200+idx, 0,, ahk_id %scitehwnd%
  166. }
  167. Document[]
  168. {
  169. get
  170. {
  171. global scintillahwnd
  172. return SciUtil_GetText(scintillahwnd)
  173. }
  174. set
  175. {
  176. throw Exception("Not implemented yet")
  177. }
  178. }
  179. InsertText(text, pos=-1)
  180. {
  181. global scintillahwnd
  182. if !IsObject(text) && text && !IsObject(pos) && (pos+0) >= -1
  183. SciUtil_InsertText(scintillahwnd, text, pos)
  184. }
  185. Selection[]
  186. {
  187. get
  188. {
  189. global scintillahwnd
  190. return SciUtil_GetSelection(scintillahwnd)
  191. }
  192. }
  193. Output(text)
  194. {
  195. Director_Send("output:" CEscape(text))
  196. }
  197. SciTEHandle[]
  198. {
  199. get
  200. {
  201. global scitehwnd
  202. return scitehwnd
  203. }
  204. }
  205. ActivePlatform[]
  206. {
  207. get
  208. {
  209. global curplatform
  210. return curplatform
  211. }
  212. set
  213. {
  214. global platforms, curplatform
  215. if !platforms[value]
  216. throw Exception("Invalid platform",, value)
  217. else
  218. {
  219. curplatform := value
  220. gosub platswitch2
  221. return value
  222. }
  223. }
  224. }
  225. ; Backwards compatibility
  226. SetPlatform(plat)
  227. {
  228. try
  229. {
  230. this.ActivePlatform := plat
  231. return 1
  232. } catch
  233. return 0
  234. }
  235. CurrentFile[]
  236. {
  237. get
  238. {
  239. return GetSciTEOpenedFile()
  240. }
  241. set
  242. {
  243. this.OpenFile(file)
  244. return file
  245. }
  246. }
  247. Version[]
  248. {
  249. get
  250. {
  251. global CurrentSciTEVersion
  252. return CurrentSciTEVersion
  253. }
  254. }
  255. OpenFile(file)
  256. {
  257. global scitehwnd
  258. WinActivate, ahk_id %scitehwnd%
  259. if this.CurrentFile = file
  260. return
  261. Director_Send("open:" CEscape(file))
  262. }
  263. DebugFile(file)
  264. {
  265. this.OpenFile(file)
  266. Cmd_Debug()
  267. }
  268. SendDirectorMsg(msg)
  269. {
  270. return Director_Send(msg)
  271. }
  272. SendDirectorMsgRet(msg)
  273. {
  274. return Director_Send(msg, true)
  275. }
  276. SendDirectorMsgRetArray(msg)
  277. {
  278. obj := Director_Send(msg, true, true)
  279. array := ComObjArray(VT_VARIANT:=12, (t := obj.MaxIndex()) ? t : 0), ComObjFlags(array, -1)
  280. for each, msg in obj
  281. array[each - 1] := msg
  282. return array
  283. }
  284. ResolveProp(propname)
  285. {
  286. propVal := Director_Send("askproperty:" propname, true).value
  287. if SubStr(propVal, 1, 11) != "stringinfo:"
  288. return
  289. propVal := SubStr(propVal, 12)
  290. while RegExMatch(propVal, "O)\$\((.+?)\)", o)
  291. propVal := SubStr(propVal, 1, o.Pos-1) this.ResolveProp(o.1) SubStr(propVal, o.Pos+o.Len)
  292. return propVal
  293. }
  294. }
  295. ;------------------------------------------------------------------------------
  296. ; Initialization code
  297. ;------------------------------------------------------------------------------
  298. goto _skip_file
  299. InitComInterface()
  300. {
  301. global CLSID_SciTE4AHK, APPID_SciTE4AHK, oSciTE, hSciTE_Remote, IsPortable
  302. if IsPortable
  303. {
  304. ; Register our CLSID and APPID
  305. OnExit, IDCleanup
  306. RegisterIDs(CLSID_SciTE4AHK, APPID_SciTE4AHK)
  307. }
  308. ; Expose it
  309. if !(hSciTE_Remote := ComRemote(ComObject(9, &CoI), CLSID_SciTE4AHK))
  310. {
  311. MsgBox, 16, SciTE4AutoHotkey, Can't create COM interface!`nSome program functions may not work.
  312. if IsPortable
  313. RevokeIDs(CLSID_SciTE4AHK, APPID_SciTE4AHK)
  314. OnExit
  315. }
  316. }
  317. IDCleanup:
  318. RevokeIDs(CLSID_SciTE4AHK, APPID_SciTE4AHK)
  319. ExitApp
  320. RegisterIDs(CLSID, APPID)
  321. {
  322. RegWrite, REG_SZ, HKCU, Software\Classes\%APPID%,, %APPID%
  323. RegWrite, REG_SZ, HKCU, Software\Classes\%APPID%\CLSID,, %CLSID%
  324. RegWrite, REG_SZ, HKCU, Software\Classes\CLSID\%CLSID%,, %APPID%
  325. }
  326. RevokeIDs(CLSID, APPID)
  327. {
  328. RegDelete, HKCU, Software\Classes\%APPID%
  329. RegDelete, HKCU, Software\Classes\CLSID\%CLSID%
  330. }
  331. Str2GUID(ByRef var, str)
  332. {
  333. VarSetCapacity(var, 16)
  334. DllCall("ole32\CLSIDFromString", "wstr", str, "ptr", &var)
  335. return &var
  336. }
  337. _skip_file:
  338. _=_