wrb 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (271) hide show
  1. checksums.yaml +7 -0
  2. data/README +28 -0
  3. data/Rakefile +66 -0
  4. data/bin/wrb +41 -0
  5. data/bin/wrb.bat +6 -0
  6. data/ext/rwin/aatree.c +192 -0
  7. data/ext/rwin/aatree.h +55 -0
  8. data/ext/rwin/extconf.rb +47 -0
  9. data/ext/rwin/rw_api.c +2058 -0
  10. data/ext/rwin/rw_devices.c +215 -0
  11. data/ext/rwin/rw_gdiplus.h +278 -0
  12. data/ext/rwin/rw_graphics.c +1583 -0
  13. data/ext/rwin/rw_resources.c +1988 -0
  14. data/ext/rwin/rw_ubfuncs.c +281 -0
  15. data/ext/rwin/rw_windows.c +1936 -0
  16. data/ext/rwin/rwin.c +451 -0
  17. data/ext/rwin/rwin.h +442 -0
  18. data/lib/rwin.rb +820 -0
  19. data/lib/wrb.rb +20 -0
  20. data/lib/wrb/applications/frmdesigner/angle.cur +0 -0
  21. data/lib/wrb/applications/frmdesigner/angle2.cur +0 -0
  22. data/lib/wrb/applications/frmdesigner/controls/Button.bmp +0 -0
  23. data/lib/wrb/applications/frmdesigner/controls/Button.rb +34 -0
  24. data/lib/wrb/applications/frmdesigner/controls/Checkbox.bmp +0 -0
  25. data/lib/wrb/applications/frmdesigner/controls/Checkbox.rb +10 -0
  26. data/lib/wrb/applications/frmdesigner/controls/Combobox.bmp +0 -0
  27. data/lib/wrb/applications/frmdesigner/controls/Combobox.rb +88 -0
  28. data/lib/wrb/applications/frmdesigner/controls/ComboboxEx.rb +97 -0
  29. data/lib/wrb/applications/frmdesigner/controls/Comboboxex.bmp +0 -0
  30. data/lib/wrb/applications/frmdesigner/controls/DateTimePicker.bmp +0 -0
  31. data/lib/wrb/applications/frmdesigner/controls/DateTimePicker.rb +11 -0
  32. data/lib/wrb/applications/frmdesigner/controls/Edit.bmp +0 -0
  33. data/lib/wrb/applications/frmdesigner/controls/Edit.rb +8 -0
  34. data/lib/wrb/applications/frmdesigner/controls/Groupbox.bmp +0 -0
  35. data/lib/wrb/applications/frmdesigner/controls/Groupbox.rb +9 -0
  36. data/lib/wrb/applications/frmdesigner/controls/Hotkeyctrl.bmp +0 -0
  37. data/lib/wrb/applications/frmdesigner/controls/Hotkeyctrl.rb +9 -0
  38. data/lib/wrb/applications/frmdesigner/controls/Imagelist.bmp +0 -0
  39. data/lib/wrb/applications/frmdesigner/controls/Imagelist.rb +115 -0
  40. data/lib/wrb/applications/frmdesigner/controls/Listbox.bmp +0 -0
  41. data/lib/wrb/applications/frmdesigner/controls/Listbox.rb +77 -0
  42. data/lib/wrb/applications/frmdesigner/controls/Listview.bmp +0 -0
  43. data/lib/wrb/applications/frmdesigner/controls/Listview.rb +157 -0
  44. data/lib/wrb/applications/frmdesigner/controls/Menu.bmp +0 -0
  45. data/lib/wrb/applications/frmdesigner/controls/Menu.rb +198 -0
  46. data/lib/wrb/applications/frmdesigner/controls/Menubar.bmp +0 -0
  47. data/lib/wrb/applications/frmdesigner/controls/Menubar.rb +9 -0
  48. data/lib/wrb/applications/frmdesigner/controls/MonthCalender.bmp +0 -0
  49. data/lib/wrb/applications/frmdesigner/controls/Monthcalender.rb +9 -0
  50. data/lib/wrb/applications/frmdesigner/controls/Panel.bmp +0 -0
  51. data/lib/wrb/applications/frmdesigner/controls/Panel.rb +30 -0
  52. data/lib/wrb/applications/frmdesigner/controls/Progressbar.rb +10 -0
  53. data/lib/wrb/applications/frmdesigner/controls/Radiobutton.bmp +0 -0
  54. data/lib/wrb/applications/frmdesigner/controls/Radiobutton.rb +13 -0
  55. data/lib/wrb/applications/frmdesigner/controls/Rebar.bmp +0 -0
  56. data/lib/wrb/applications/frmdesigner/controls/Rebar.rb +162 -0
  57. data/lib/wrb/applications/frmdesigner/controls/Splitter.bmp +0 -0
  58. data/lib/wrb/applications/frmdesigner/controls/Splitter.rb +66 -0
  59. data/lib/wrb/applications/frmdesigner/controls/Static.bmp +0 -0
  60. data/lib/wrb/applications/frmdesigner/controls/Static.rb +9 -0
  61. data/lib/wrb/applications/frmdesigner/controls/Statusbar.bmp +0 -0
  62. data/lib/wrb/applications/frmdesigner/controls/Statusbar.rb +103 -0
  63. data/lib/wrb/applications/frmdesigner/controls/Tabctrl.bmp +0 -0
  64. data/lib/wrb/applications/frmdesigner/controls/Tabctrl.rb +136 -0
  65. data/lib/wrb/applications/frmdesigner/controls/Timer.bmp +0 -0
  66. data/lib/wrb/applications/frmdesigner/controls/Timer.rb +36 -0
  67. data/lib/wrb/applications/frmdesigner/controls/Toolbar.bmp +0 -0
  68. data/lib/wrb/applications/frmdesigner/controls/Toolbar.rb +165 -0
  69. data/lib/wrb/applications/frmdesigner/controls/Trackbar.bmp +0 -0
  70. data/lib/wrb/applications/frmdesigner/controls/Trackbar.rb +34 -0
  71. data/lib/wrb/applications/frmdesigner/controls/Treeview.bmp +0 -0
  72. data/lib/wrb/applications/frmdesigner/controls/Treeview.rb +107 -0
  73. data/lib/wrb/applications/frmdesigner/controls/Updown.bmp +0 -0
  74. data/lib/wrb/applications/frmdesigner/controls/Updown.rb +31 -0
  75. data/lib/wrb/applications/frmdesigner/controls/default.bmp +0 -0
  76. data/lib/wrb/applications/frmdesigner/controls/progressbar.bmp +0 -0
  77. data/lib/wrb/applications/frmdesigner/controls/unselect.bmp +0 -0
  78. data/lib/wrb/applications/frmdesigner/fddialogs.rb +87 -0
  79. data/lib/wrb/applications/frmdesigner/fdesign.rb +1315 -0
  80. data/lib/wrb/applications/frmdesigner/fdmodules.rb +1394 -0
  81. data/lib/wrb/applications/frmdesigner/fdparseform.rb +197 -0
  82. data/lib/wrb/applications/frmdesigner/img13.bmp +0 -0
  83. data/lib/wrb/base.rb +1294 -0
  84. data/lib/wrb/combocommon.rb +77 -0
  85. data/lib/wrb/commctrlconst.rb +139 -0
  86. data/lib/wrb/commdlg.rb +77 -0
  87. data/lib/wrb/components/animate.rb +114 -0
  88. data/lib/wrb/components/bitmap.rb +116 -0
  89. data/lib/wrb/components/button.rb +134 -0
  90. data/lib/wrb/components/canvas.rb +266 -0
  91. data/lib/wrb/components/checkbox.rb +118 -0
  92. data/lib/wrb/components/choosecolordlg.rb +87 -0
  93. data/lib/wrb/components/choosefontdlg.rb +142 -0
  94. data/lib/wrb/components/clipboard.rb +174 -0
  95. data/lib/wrb/components/combobox.rb +282 -0
  96. data/lib/wrb/components/comboboxex.rb +574 -0
  97. data/lib/wrb/components/cursor.rb +91 -0
  98. data/lib/wrb/components/datetimepicker.rb +197 -0
  99. data/lib/wrb/components/ddeclient.rb +180 -0
  100. data/lib/wrb/components/ddeserver.rb +131 -0
  101. data/lib/wrb/components/dialog.rb +228 -0
  102. data/lib/wrb/components/edit.rb +412 -0
  103. data/lib/wrb/components/font.rb +35 -0
  104. data/lib/wrb/components/form.rb +65 -0
  105. data/lib/wrb/components/groupbox.rb +122 -0
  106. data/lib/wrb/components/header.rb +479 -0
  107. data/lib/wrb/components/hotkeyctrl.rb +72 -0
  108. data/lib/wrb/components/icon.rb +109 -0
  109. data/lib/wrb/components/imagelist.rb +396 -0
  110. data/lib/wrb/components/inifile.rb +97 -0
  111. data/lib/wrb/components/listbox.rb +149 -0
  112. data/lib/wrb/components/listview.rb +1467 -0
  113. data/lib/wrb/components/menu.rb +592 -0
  114. data/lib/wrb/components/menubar.rb +84 -0
  115. data/lib/wrb/components/monthcalender.rb +164 -0
  116. data/lib/wrb/components/openfilenamedlg.rb +147 -0
  117. data/lib/wrb/components/pager.rb +199 -0
  118. data/lib/wrb/components/panel.rb +103 -0
  119. data/lib/wrb/components/picture.rb +55 -0
  120. data/lib/wrb/components/printdlg.rb +148 -0
  121. data/lib/wrb/components/printdlgex.rb +117 -0
  122. data/lib/wrb/components/printer.rb +97 -0
  123. data/lib/wrb/components/progressbar.rb +140 -0
  124. data/lib/wrb/components/radiobutton.rb +49 -0
  125. data/lib/wrb/components/rebar.rb +830 -0
  126. data/lib/wrb/components/registry.rb +408 -0
  127. data/lib/wrb/components/richedit.rb +1181 -0
  128. data/lib/wrb/components/savefilenamedlg.rb +27 -0
  129. data/lib/wrb/components/scintilla.rb +1298 -0
  130. data/lib/wrb/components/scrollbar.rb +239 -0
  131. data/lib/wrb/components/splitter.rb +494 -0
  132. data/lib/wrb/components/static.rb +198 -0
  133. data/lib/wrb/components/statusbar.rb +490 -0
  134. data/lib/wrb/components/tabctrl.rb +686 -0
  135. data/lib/wrb/components/timer.rb +117 -0
  136. data/lib/wrb/components/toolbar.rb +1107 -0
  137. data/lib/wrb/components/tooltip.rb +651 -0
  138. data/lib/wrb/components/trackbar.rb +298 -0
  139. data/lib/wrb/components/treeview.rb +845 -0
  140. data/lib/wrb/components/updown.rb +198 -0
  141. data/lib/wrb/ddeml.rb +241 -0
  142. data/lib/wrb/documents/animate.html +46 -0
  143. data/lib/wrb/documents/bitmap.html +69 -0
  144. data/lib/wrb/documents/button.html +78 -0
  145. data/lib/wrb/documents/canvas.html +137 -0
  146. data/lib/wrb/documents/checkbox.html +77 -0
  147. data/lib/wrb/documents/choosecolordlg.html +29 -0
  148. data/lib/wrb/documents/choosefontdlg.html +31 -0
  149. data/lib/wrb/documents/clipboard.html +31 -0
  150. data/lib/wrb/documents/combobox.html +117 -0
  151. data/lib/wrb/documents/comboboxex.html +139 -0
  152. data/lib/wrb/documents/control.html +53 -0
  153. data/lib/wrb/documents/cursor.html +45 -0
  154. data/lib/wrb/documents/datetimepicker.html +70 -0
  155. data/lib/wrb/documents/ddeclient.html +33 -0
  156. data/lib/wrb/documents/ddeserver.html +26 -0
  157. data/lib/wrb/documents/dialog.html +78 -0
  158. data/lib/wrb/documents/edit.html +169 -0
  159. data/lib/wrb/documents/empty.html +11 -0
  160. data/lib/wrb/documents/favicon.png +0 -0
  161. data/lib/wrb/documents/font.html +38 -0
  162. data/lib/wrb/documents/form.html +63 -0
  163. data/lib/wrb/documents/groupbox.html +57 -0
  164. data/lib/wrb/documents/header.html +85 -0
  165. data/lib/wrb/documents/hotkeyctrl.html +42 -0
  166. data/lib/wrb/documents/icon.html +45 -0
  167. data/lib/wrb/documents/imagelist.html +101 -0
  168. data/lib/wrb/documents/images/button.png +0 -0
  169. data/lib/wrb/documents/images/checkbox.png +0 -0
  170. data/lib/wrb/documents/images/combobox.png +0 -0
  171. data/lib/wrb/documents/images/comboboxex.png +0 -0
  172. data/lib/wrb/documents/images/datetimepicker.png +0 -0
  173. data/lib/wrb/documents/images/edit.png +0 -0
  174. data/lib/wrb/documents/images/groupbox.png +0 -0
  175. data/lib/wrb/documents/images/hotkeyctrl.png +0 -0
  176. data/lib/wrb/documents/images/listbox.png +0 -0
  177. data/lib/wrb/documents/images/listview.png +0 -0
  178. data/lib/wrb/documents/images/menu.png +0 -0
  179. data/lib/wrb/documents/images/menubar.png +0 -0
  180. data/lib/wrb/documents/images/monthcalender.png +0 -0
  181. data/lib/wrb/documents/images/progressbar.png +0 -0
  182. data/lib/wrb/documents/images/radiobutton.png +0 -0
  183. data/lib/wrb/documents/images/rebar.png +0 -0
  184. data/lib/wrb/documents/images/richedit.png +0 -0
  185. data/lib/wrb/documents/images/splitter.png +0 -0
  186. data/lib/wrb/documents/images/static.png +0 -0
  187. data/lib/wrb/documents/images/statusbar.png +0 -0
  188. data/lib/wrb/documents/images/tabctrl.png +0 -0
  189. data/lib/wrb/documents/images/toolbar.png +0 -0
  190. data/lib/wrb/documents/images/tooltip.png +0 -0
  191. data/lib/wrb/documents/images/trackbar.png +0 -0
  192. data/lib/wrb/documents/images/treeview.png +0 -0
  193. data/lib/wrb/documents/images/updown.png +0 -0
  194. data/lib/wrb/documents/index.html +155 -0
  195. data/lib/wrb/documents/inifile.html +36 -0
  196. data/lib/wrb/documents/license.txt +22 -0
  197. data/lib/wrb/documents/listbox.html +96 -0
  198. data/lib/wrb/documents/listview.html +277 -0
  199. data/lib/wrb/documents/make_doc.rb +596 -0
  200. data/lib/wrb/documents/menu.html +144 -0
  201. data/lib/wrb/documents/menubar.html +54 -0
  202. data/lib/wrb/documents/monthcalender.html +48 -0
  203. data/lib/wrb/documents/openfilenamedlg.html +36 -0
  204. data/lib/wrb/documents/pager.html +63 -0
  205. data/lib/wrb/documents/panel.html +32 -0
  206. data/lib/wrb/documents/picture.html +48 -0
  207. data/lib/wrb/documents/printdlg.html +35 -0
  208. data/lib/wrb/documents/printdlgex.html +35 -0
  209. data/lib/wrb/documents/printer.html +40 -0
  210. data/lib/wrb/documents/progressbar.html +69 -0
  211. data/lib/wrb/documents/radiobutton.html +51 -0
  212. data/lib/wrb/documents/rebar.html +143 -0
  213. data/lib/wrb/documents/registry.html +36 -0
  214. data/lib/wrb/documents/richedit.html +232 -0
  215. data/lib/wrb/documents/samples/editimg.bmp +0 -0
  216. data/lib/wrb/documents/samples/editimg.iml +0 -0
  217. data/lib/wrb/documents/samples/fileimg.bmp +0 -0
  218. data/lib/wrb/documents/samples/fileimg.iml +0 -0
  219. data/lib/wrb/documents/samples/sample_button.rb +21 -0
  220. data/lib/wrb/documents/samples/sample_checkbox.rb +18 -0
  221. data/lib/wrb/documents/samples/sample_combobox.rb +18 -0
  222. data/lib/wrb/documents/samples/sample_comboboxex.rb +23 -0
  223. data/lib/wrb/documents/samples/sample_datetimepicker.rb +11 -0
  224. data/lib/wrb/documents/samples/sample_edit.rb +25 -0
  225. data/lib/wrb/documents/samples/sample_groupbox.rb +19 -0
  226. data/lib/wrb/documents/samples/sample_hotkeyctrl.rb +12 -0
  227. data/lib/wrb/documents/samples/sample_listbox.rb +12 -0
  228. data/lib/wrb/documents/samples/sample_listview.rb +32 -0
  229. data/lib/wrb/documents/samples/sample_menu.rb +21 -0
  230. data/lib/wrb/documents/samples/sample_menubar.rb +23 -0
  231. data/lib/wrb/documents/samples/sample_monthcalender.rb +11 -0
  232. data/lib/wrb/documents/samples/sample_progressbar.rb +14 -0
  233. data/lib/wrb/documents/samples/sample_radiobutton.rb +14 -0
  234. data/lib/wrb/documents/samples/sample_rebar.rb +25 -0
  235. data/lib/wrb/documents/samples/sample_richedit.rb +60 -0
  236. data/lib/wrb/documents/samples/sample_splitter.rb +33 -0
  237. data/lib/wrb/documents/samples/sample_static.rb +15 -0
  238. data/lib/wrb/documents/samples/sample_statusbar.rb +17 -0
  239. data/lib/wrb/documents/samples/sample_tabctrl.rb +19 -0
  240. data/lib/wrb/documents/samples/sample_toolbar.rb +29 -0
  241. data/lib/wrb/documents/samples/sample_tooltip.rb +50 -0
  242. data/lib/wrb/documents/samples/sample_trackbar.rb +30 -0
  243. data/lib/wrb/documents/samples/sample_treeview.rb +19 -0
  244. data/lib/wrb/documents/samples/sample_updown.rb +18 -0
  245. data/lib/wrb/documents/samples/sampleimg16.iml +0 -0
  246. data/lib/wrb/documents/samples/sampleimg32.iml +0 -0
  247. data/lib/wrb/documents/samples/samplemg16.png +0 -0
  248. data/lib/wrb/documents/samples/samplemg32.png +0 -0
  249. data/lib/wrb/documents/samples/wrb.ico +0 -0
  250. data/lib/wrb/documents/savefilenamedlg.html +19 -0
  251. data/lib/wrb/documents/scrollbar.html +60 -0
  252. data/lib/wrb/documents/splitter.html +96 -0
  253. data/lib/wrb/documents/static.html +84 -0
  254. data/lib/wrb/documents/statusbar.html +110 -0
  255. data/lib/wrb/documents/tabctrl.html +151 -0
  256. data/lib/wrb/documents/timer.html +43 -0
  257. data/lib/wrb/documents/toolbar.html +181 -0
  258. data/lib/wrb/documents/tooltip.html +131 -0
  259. data/lib/wrb/documents/trackbar.html +107 -0
  260. data/lib/wrb/documents/treeview.html +210 -0
  261. data/lib/wrb/documents/updown.html +85 -0
  262. data/lib/wrb/documents/wincontrol.html +258 -0
  263. data/lib/wrb/documents/window.html +499 -0
  264. data/lib/wrb/documents/wrb.css +228 -0
  265. data/lib/wrb/gmem.rb +26 -0
  266. data/lib/wrb/imecommon.rb +59 -0
  267. data/lib/wrb/listcommon.rb +185 -0
  268. data/lib/wrb/lzss.rb +126 -0
  269. data/lib/wrb/scrollinfo.rb +142 -0
  270. data/lib/wrb/toplevelcommon.rb +634 -0
  271. metadata +315 -0
@@ -0,0 +1,408 @@
1
+ require 'wrb'
2
+
3
+ module WR
4
+ module RC
5
+ REG_SZ = 1
6
+ REG_EXPAND_SZ = 2
7
+ REG_BINARY = 3
8
+ REG_DWORD = 4
9
+ REG_MULTI_SZ = 7
10
+ REG_QWORD = 11
11
+
12
+ REG_OPTION_NON_VOLATILE = 0
13
+ REG_OPTION_VOLATILE = 1
14
+
15
+ REG_CREATED_NEW_KEY = 1
16
+ REG_OPENED_EXISTING_KEY = 2
17
+
18
+ HKEY_CLASSES_ROOT = 0x80000000
19
+ HKEY_CURRENT_USER = 0x80000001
20
+ HKEY_LOCAL_MACHINE = 0x80000002
21
+ HKEY_USERS = 0x80000003
22
+ HKEY_CURRENT_CONFIG = 0x80000005
23
+
24
+ HKCR = 0x80000000
25
+ HKCU = 0x80000001
26
+ HKLM = 0x80000002
27
+
28
+ KEY_READ = 0x20019
29
+ KEY_WRITE = 0x20006
30
+ end
31
+
32
+ API.loadlib "advapi32.dll"
33
+
34
+ API.defun "RegOpenKeyEx(
35
+ HKEY hKey,
36
+ LPCWSTR lpSubKey,
37
+ DWORD ulOptions,
38
+ REGSAM samDesired,
39
+ PHKEY phkResult)"
40
+
41
+ API.defun "RegCreateKeyEx(
42
+ HKEY hKey,
43
+ LPCWSTR lpSubKey,
44
+ DWORD Reserved,
45
+ LPWSTR lpClass,
46
+ DWORD dwOptions,
47
+ REGSAM samDesired,
48
+ LPSECURITY_ATTRIBUTES lpSecurityAttributes,
49
+ PHKEY phkResult,
50
+ LPDWORD lpdwDisposition)"
51
+
52
+ API.defun "RegEnumValue(
53
+ HKEY hKey,
54
+ DWORD dwIndex,
55
+ LPWSTR lpValueName,
56
+ LPDWORD lpcchValueName,
57
+ LPDWORD lpReserved,
58
+ LPDWORD lpType,
59
+ LPBYTE lpData,
60
+ LPDWORD lpcbData)"
61
+
62
+ API.defun "RegEnumKeyEx(
63
+ HKEY hKey,
64
+ DWORD dwIndex,
65
+ LPWSTR lpName,
66
+ LPDWORD lpcName,
67
+ LPDWORD lpReserved,
68
+ LPWSTR lpClass,
69
+ LPDWORD lpcbClass,
70
+ PFILETIME lpftLastWriteTime)"
71
+
72
+ API.defun "RegQueryValueEx(
73
+ HKEY hKey,
74
+ LPCWSTR lpValueName,
75
+ LPDWORD lpReserved,
76
+ LPDWORD lpType,
77
+ LPBYTE lpData,
78
+ LPDWORD lpcbData)"
79
+
80
+ API.defun "RegSetValueEx(
81
+ HKEY hKey,
82
+ LPCWSTR lpValueName,
83
+ DWORD Reserved,
84
+ DWORD dwType,
85
+ const BYTE* lpData,
86
+ DWORD cbData)"
87
+
88
+ API.defun "RegQueryInfoKey(
89
+ HKEY hKey,
90
+ LPTSTR lpClass,
91
+ LPDWORD lpcClass,
92
+ LPDWORD lpReserved,
93
+ LPDWORD lpcSubKeys,
94
+ LPDWORD lpcMaxSubKeyLen,
95
+ LPDWORD lpcMaxClassLen,
96
+ LPDWORD lpcValues,
97
+ LPDWORD lpcMaxValueNameLen,
98
+ LPDWORD lpcMaxValueLen,
99
+ LPDWORD lpcbSecurityDescriptor,
100
+ PFILETIME lpftLastWriteTime)"
101
+
102
+ API.defun "RegDeleteValue(HKEY hKey, LPCWSTR lpValueName)"
103
+ API.defun "RegDeleteKey(HKEY hKey, LPCWSTR lpSubKey)"
104
+ API.defun "RegCloseKey(HKEY hKey)"
105
+
106
+ # Provides an interface that allows an application to access the Windows-registry.
107
+ # <br>See also <a href="https://docs.microsoft.com/en-us/windows/desktop/sysinfo/windows-system-information">
108
+ # Windows System Information section of Microsft Docs</a>
109
+ class Registry
110
+ include RC
111
+
112
+ HANDLE = API.defstruct('HANDLE value')
113
+ LPDWORD = HANDLE
114
+ LPLONxG = API.defstruct('LONG value')
115
+
116
+ RegRootKey = {
117
+ 'HKEY_CLASSES_ROOT' => 0x80000000,
118
+ 'HKEY_CURRENT_USER' => 0x80000001,
119
+ 'HKEY_LOCAL_MACHINE' => 0x80000002,
120
+ 'HKEY_USERS' => 0x80000003,
121
+ 'HKEY_CURRENT_CONFIG' => 0x80000005,
122
+ 'HKCR' => 0x80000000,
123
+ 'HKCU' => 0x80000001,
124
+ 'HKLM' => 0x80000002,
125
+ }
126
+
127
+ RegAccessMask = {
128
+ 'r' => KEY_READ,
129
+ 'w' => KEY_WRITE,
130
+ 'rw' => KEY_READ | KEY_WRITE,
131
+ 'wr' => KEY_READ | KEY_WRITE
132
+ }
133
+
134
+ #
135
+ def self.split_regpath(regpath)
136
+ /^(HK.+?)\\(.+)/.match regpath
137
+ k = $1
138
+ hkey = RegRootKey[k]
139
+ raise "Invalid key: #{k}" unless hkey
140
+ subkey = $2.to_s
141
+ [hkey, subkey]
142
+ end
143
+ #
144
+ def self.check_hkey(hkey)
145
+ case hkey
146
+ when HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, HKEY_USERS,
147
+ HKEY_CURRENT_CONFIG
148
+ return
149
+ else
150
+ raise "illegal handle of HKEY 0x#{hkey.to_s(16)}"
151
+ end
152
+ end
153
+
154
+ # self.open(regpath, regmask='r')
155
+ def self.open(*args)
156
+ raise "wrong number of arguments (#{args.size})" if args.size > 3 || args.size == 0
157
+ if args[0].is_a? Integer
158
+ hkey, subkey, regmask = args
159
+ check_hkey(hkey)
160
+ elsif args[0].is_a? String
161
+ hkey, subkey = split_regpath(args[0].tr('/', '\\'))
162
+ regmask = args[1]
163
+ end
164
+ reg = self.new(hkey, subkey, regmask || 'r')
165
+ reg.openkey
166
+ begin
167
+ yield reg
168
+ ensure
169
+ reg.closekey
170
+ reg = nil
171
+ GC.start
172
+ end
173
+ end
174
+
175
+ # self.create(regpath, regmask='r', option=REG_OPTION_NON_VOLATILE)
176
+ def self.create(*args)
177
+ raise "wrong number of arguments (#{args.size})" if args.size > 4 || args.size == 0
178
+ if args[0].is_a? Integer
179
+ hkey, subkey, regmask, option = args
180
+ check_hkey(hkey)
181
+ elsif args[0].is_a? String
182
+ hkey, subkey = split_regpath(args[0].tr('/', '\\'))
183
+ case args[1]
184
+ when REG_OPTION_NON_VOLATILE, REG_OPTION_VOLATILE
185
+ regmask = 'r'
186
+ else
187
+ regmask = args[1]
188
+ option = args[2]
189
+ end
190
+ end
191
+ reg = self.new(hkey, subkey, regmask || 'r')
192
+ reg.createkey(option)
193
+ begin
194
+ yield reg
195
+ ensure
196
+ reg.closekey
197
+ reg = nil
198
+ GC.start
199
+ end
200
+ end
201
+
202
+ attr_reader :created_new_key, :option, :hkey, :subkey, :access_mask
203
+
204
+ def initialize(hkey, subkey, regmask)
205
+ @access_mask = RegAccessMask[regmask]
206
+ raise "Invalid operation type: \"#{regmask}\"" unless @access_mask
207
+ @hkey = hkey
208
+ @subkey = subkey.tr('/', '\\')
209
+ @access_handle = nil
210
+ @created_new_key = nil
211
+ end
212
+
213
+ def openkey()
214
+ haccess = HANDLE.new
215
+ check_err API.RegOpenKeyEx(@hkey, @subkey, nil, @access_mask, haccess)
216
+ @access_handle = haccess.value
217
+ end
218
+
219
+ def createkey(option = REG_OPTION_NON_VOLATILE)
220
+ haccess = HANDLE.new
221
+ lpdispositon = LPDWORD.new
222
+ check_err API.RegCreateKeyEx(@hkey, @subkey, nil, nil, option, @access_mask,
223
+ nil, haccess, lpdispositon)
224
+ @access_handle = haccess.value
225
+ @created_new_key = lpdispositon.value == REG_CREATED_NEW_KEY ? true : nil
226
+ end
227
+
228
+ def closekey()
229
+ # check_err API.RegCloseKey(@hkey)
230
+ API.RegCloseKey(@hkey)
231
+ end
232
+
233
+
234
+
235
+ def read(regentry=nil)
236
+ lptype = LPDWORD.new
237
+ lpcbData = LPDWORD.new
238
+ r = API.RegQueryValueEx(@access_handle, regentry, nil, lptype, nil, lpcbData)
239
+ return nil unless r==0
240
+ regtype = lptype.value
241
+ bufflen = lpcbData.value
242
+ case regtype
243
+ when REG_SZ, REG_EXPAND_SZ
244
+ buff = TCHAR[bufflen]
245
+ check_err API.RegQueryValueEx(@access_handle, regentry, nil, lptype, buff, lpcbData)
246
+ buff.to_s
247
+ when REG_BINARY
248
+ buff = BYTE[bufflen]
249
+ check_err API.RegQueryValueEx(@access_handle, regentry, nil, lptype, buff, lpcbData)
250
+ buff
251
+ when REG_DWORD
252
+ buff = LPDWORD.new
253
+ check_err API.RegQueryValueEx(@access_handle, regentry, nil, lptype, buff, lpcbData)
254
+ buff.value
255
+ when REG_MULTI_SZ
256
+ buff = TCHAR[bufflen]
257
+ check_err API.RegQueryValueEx(@access_handle, regentry, nil, lptype, buff, lpcbData)
258
+ buff.to_s.split("\0")
259
+ when REG_QWORD
260
+ buff = TCHAR[bufflen]
261
+ check_err API.RegQueryValueEx(@access_handle, regentry, nil, lptype, buff, lpcbData)
262
+ buff.unpack('Q')[0]
263
+ else
264
+ raise "Unretrevable type : #{regtype}"
265
+ end
266
+ end
267
+
268
+ def [](regentry) read(regentry); end
269
+
270
+ def write(regentry, data, regtype = nil)
271
+ if regtype
272
+ case regtype
273
+ when REG_SZ
274
+ write_sz(regentry, data)
275
+ when REG_EXPAND_SZ
276
+ write_sz(regentry, data, regtyep)
277
+ when REG_BINARY
278
+ write_binary(regentry, data)
279
+ when REG_DWORD
280
+ write_dword(regentry, data)
281
+ when REG_MULTI_SZ
282
+ write_multi(regentry, data)
283
+ when REG_QWORD
284
+ write_qword(regentry, data)
285
+ else
286
+ raise "illegal data type: #{regtype}"
287
+ end
288
+ else
289
+ if data.is_a? Integer
290
+ if data & 0xffffffff00000000 > 0
291
+ write_qword(regentry, data)
292
+ else
293
+ write_dword(regentry, data)
294
+ end
295
+ elsif data.is_a? Array
296
+ write_multi(regentry, data)
297
+ else
298
+ write_sz(regentry, data)
299
+ end
300
+ end
301
+ end
302
+
303
+ def []=(regentry, data)
304
+ write(regentry, data);
305
+ end
306
+
307
+ def delete_value(regentry)
308
+ check_err API.RegDeleteValue(@access_handle, regentry)
309
+ end
310
+ alias delete delete_value
311
+
312
+ def delete_key(keyname)
313
+ check_err 5 if @access_mask == KEY_READ
314
+ check_err API.RegDeleteKey(@access_handle, keyname)
315
+ end
316
+
317
+ def each_values
318
+ csubkeys, cmaxsubkeylen, cvalues, cmaxvaluenamelen, cmaxvaluelen = self.info
319
+ ar = []
320
+ lpValueName = TCHAR[cmaxvaluenamelen]
321
+ lpDataf = TCHAR[cmaxvaluelen]
322
+ lpType = LPDWORD.new
323
+ cvalues.tmes{|idx|
324
+ check_err RegEnumValue(@access_handle, idx, lpValueName, cmaxvaluenamelen,
325
+ nil, lpType, lpData, cmaxvaluelen)
326
+ yield()
327
+ }
328
+ end
329
+
330
+ def each_keys
331
+ csubkeys, cmaxsubkeylen, cvalues, cmaxvaluenamelen, cmaxvaluelen = self.info
332
+ p [csubkeys, cmaxsubkeylen, cvalues, cmaxvaluenamelen, cmaxvaluelen]
333
+ end
334
+
335
+ def info()
336
+ lpcSubKeys = LPDWORD.new
337
+ lpcMaxSubKeyLen = LPDWORD.new
338
+ lpcValues = LPDWORD.new
339
+ lpcMaxValueNameLen = LPDWORD.new
340
+ lpcMaxValueLen= LPDWORD.new
341
+ check_err API.RegQueryInfoKey(@access_handle, nil, nil, nil, lpcSubKeys,
342
+ lpcMaxSubKeyLen, nil, lpcValues,
343
+ lpcMaxValueNameLen, lpcMaxValueLen, nil, nil)
344
+ [lpcSubKeys.value, lpcMaxSubKeyLen.value, lpcValues.value,
345
+ lpcMaxValueNameLen.value, lpcMaxValueLen.value]
346
+ end
347
+
348
+ private
349
+
350
+ def write_sz(regentry, data, regtype = REG_SZ)
351
+ lpdata = API.encode_internal(data)
352
+ check_err API.RegSetValueEx(@access_handle, regentry, nil, regtype, lpdata,
353
+ lpdata.bytesize)
354
+ end
355
+
356
+ def write_binary(regentry, data)
357
+ lpdata = API.encoding2bin(data)
358
+ check_err API.RegSetValueEx(@access_handle, regentry, nil, REG_BINARY,
359
+ lpdata, lpdata.bytesize)
360
+ end
361
+
362
+ def write_dword(regentry, data)
363
+ lpdata = LPDWORD.new
364
+ lpdata.value = data
365
+ check_err API.RegSetValueEx(@access_handle, regentry, nil, REG_DWORD, lpdata, 4)
366
+ end
367
+
368
+ def write_multi(regentry, data)
369
+ lpdata = API.encode_internal(data.join("\0"))
370
+ check_err API.RegSetValueEx(@access_handle, regentry, nil, REG_MULTI_SZ, lpdata, lpdata.bytesize)
371
+ end
372
+
373
+ def write_qword(regentry, data)
374
+ lpdata = API.defstruct("ULONG[2]").new
375
+ lpdata[0] = data & 0xffffffff
376
+ lpdata[1] = data >> 32
377
+ check_err API.RegSetValueEx(@access_handle, regentry, nil, REG_QWORD, lpdata, 8)
378
+ end
379
+
380
+ def check_err(err)
381
+ return if err == 0
382
+ raise RuntimeError, API.lasterror
383
+ end
384
+ end
385
+ end
386
+
387
+ #__END__
388
+ ################### testing ###################
389
+ module WR
390
+ r = Registry.create('HKCU/Software/YSLab/mytest2','wr'){|reg|
391
+ reg.delete("mytestStr")
392
+ reg["mytestStr"] ||= "46.06"
393
+ }
394
+
395
+ # Registry.open('HKCU/Software/YSLab/mytest2', 'wr'){|reg|
396
+ # p reg.created_new_key
397
+ #p reg.read("mytestArray")
398
+ # reg.write("mytestArray",["string1", "string2", "string3","string4", "1234"])
399
+ # reg.write("mytestStr", "46.03")
400
+ # reg.delete("mytestArray")
401
+ # reg.each_keys{|k| p k}
402
+ # } if false
403
+ #
404
+ # Registry.open('HKCU\\Software\\yslab','w'){|reg|
405
+ # reg.delete_key('mytest2')
406
+ # }
407
+ end if __FILE__ == $0
408
+
@@ -0,0 +1,1181 @@
1
+ module WR
2
+ require_relative './edit' unless defined?(Edit)
3
+
4
+ module RC
5
+ ES_SAVESEL = 0x00008000
6
+ ES_SUNKEN = 0x00004000
7
+ ES_DISABLENOSCROLL = 0x00002000
8
+ ES_SELECTIONBAR = 0x01000000
9
+ ES_NOOLEDRAGDROP = 0x00000008
10
+ ES_EX_NOCALLOLEINIT = 0x00000000
11
+ ES_VERTICAL = 0x00400000
12
+ ES_NOIME = 0x00080000
13
+ ES_SELFIME = 0x00040000
14
+
15
+ # EM_GETLIMITTEXT = WM_USER+37
16
+ # EM_POSFROMCHAR = WM_USER+38
17
+ # EM_CHARFROMPOS = WM_USER+39
18
+ # EM_SCROLLCARET = WM_USER+49
19
+
20
+ EM_CANPASTE = WM_USER+50
21
+ EM_DISPLAYBAND = WM_USER+51
22
+ EM_EXGETSEL = WM_USER+52
23
+ EM_EXLIMITTEXT = WM_USER+53
24
+ EM_EXLINEFROMCHAR = WM_USER+54
25
+ EM_EXSETSEL = WM_USER+55
26
+ EM_FINDTEXT = WM_USER+56
27
+ EM_FORMATRANGE = WM_USER+57
28
+ EM_GETCHARFORMAT = WM_USER+58
29
+ EM_GETEVENTMASK = WM_USER+59
30
+ EM_GETOLEINTERFACE = WM_USER+60
31
+ EM_GETPARAFORMAT = WM_USER+61
32
+ EM_GETSELTEXT = WM_USER+62
33
+ EM_HIDESELECTION = WM_USER+63
34
+ EM_PASTESPECIAL = WM_USER+64
35
+ EM_REQUESTRESIZE = WM_USER+65
36
+ EM_SELECTIONTYPE = WM_USER+66
37
+ EM_SETBKGNDCOLOR = WM_USER+67
38
+ EM_SETCHARFORMAT = WM_USER+68
39
+ EM_SETEVENTMASK = WM_USER+69
40
+ EM_SETOLECALLBACK = WM_USER+70
41
+ EM_SETPARAFORMAT = WM_USER+71
42
+ EM_SETTARGETDEVICE = WM_USER+72
43
+ EM_STREAMIN = WM_USER+73
44
+ EM_STREAMOUT = WM_USER+74
45
+ EM_GETTEXTRANGE = WM_USER+75
46
+ EM_FINDWORDBREAK = WM_USER+76
47
+ EM_SETOPTIONS = WM_USER+77
48
+ EM_GETOPTIONS = WM_USER+78
49
+ EM_FINDTEXTEX = WM_USER+79
50
+ EM_GETWORDBREAKPROCEX = WM_USER+80
51
+ EM_SETWORDBREAKPROCEX = WM_USER+81
52
+ EM_SETUNDOLIMIT = WM_USER+82
53
+ EM_REDO = WM_USER+84
54
+ EM_CANREDO = WM_USER+85
55
+ EM_GETUNDONAME = WM_USER+86
56
+ EM_GETREDONAME = WM_USER+87
57
+ EM_STOPGROUPTYPING = WM_USER+88
58
+ EM_SETTEXTMODE = WM_USER+89
59
+ EM_GETTEXTMODE = WM_USER+90
60
+ EM_AUTOURLDETECT = WM_USER+91
61
+ EM_GETAUTOURLDETECT = WM_USER+92
62
+ EM_SETPALETTE = WM_USER+93
63
+ EM_GETTEXTEX = WM_USER+94
64
+ EM_GETTEXTLENGTHEX = WM_USER+95
65
+ EM_SHOWSCROLLBAR = WM_USER+96
66
+ EM_SETTEXTEX = WM_USER+97
67
+
68
+ EM_SETPUNCTUATION = WM_USER+100
69
+ EM_GETPUNCTUATION = WM_USER+101
70
+ EM_SETWORDWRAPMODE = WM_USER+102
71
+ EM_GETWORDWRAPMODE = WM_USER+103
72
+ EM_SETIMECOLOR = WM_USER+104
73
+ EM_GETIMECOLOR = WM_USER+105
74
+ EM_SETIMEOPTIONS = WM_USER+106
75
+ EM_GETIMEOPTIONS = WM_USER+107
76
+ EM_CONVPOSITION = WM_USER+108
77
+ EM_SETLANGOPTIONS = WM_USER+120
78
+ EM_GETLANGOPTIONS = WM_USER+121
79
+ EM_GETIMECOMPMODE = WM_USER+122
80
+ EM_FINDTEXTW = WM_USER+123
81
+ EM_FINDTEXTEXW = WM_USER+124
82
+ EM_RECONVERSION = WM_USER+125
83
+ EM_SETIMEMODEBIAS = WM_USER+126
84
+ EM_GETIMEMODEBIAS = WM_USER+127
85
+
86
+ EM_SETBIDIOPTIONS = WM_USER+200
87
+ EM_GETBIDIOPTIONS = WM_USER+201
88
+ EM_SETTYPOGRAPHYOPTIONS = WM_USER+202
89
+ EM_GETTYPOGRAPHYOPTIONS = WM_USER+203
90
+ EM_SETEDITSTYLE = WM_USER+204
91
+ EM_GETEDITSTYLE = WM_USER+205
92
+
93
+ EM_OUTLINE = WM_USER+220
94
+
95
+ EM_GETSCROLLPOS = WM_USER+221
96
+ EM_SETSCROLLPOS = WM_USER+222
97
+
98
+ EM_SETFONTSIZE = WM_USER+223
99
+ EM_GETZOOM = WM_USER+224
100
+ EM_SETZOOM = WM_USER+225
101
+ EM_GETVIEWKIND = WM_USER+226
102
+ EM_SETVIEWKIND = WM_USER+227
103
+
104
+ EM_GETPAGE = WM_USER+228
105
+ EM_SETPAGE = WM_USER+229
106
+ EM_GETHYPHENATEINFO = WM_USER+230
107
+ EM_SETHYPHENATEINFO = WM_USER+231
108
+ EM_GETPAGEROTATE = WM_USER+235
109
+ EM_SETPAGEROTATE = WM_USER+236
110
+ EM_GETCTFMODEBIAS = WM_USER+237
111
+ EM_SETCTFMODEBIAS = WM_USER+238
112
+ EM_GETCTFOPENSTATUS = WM_USER+240
113
+ EM_SETCTFOPENSTATUS = WM_USER+241
114
+ EM_GETIMECOMPTEXT = WM_USER+242
115
+ EM_ISIME = WM_USER+243
116
+ EM_GETIMEPROPERTY = WM_USER+244
117
+
118
+ EM_GETQUERYRTFOBJ = WM_USER+269
119
+ EM_SETQUERYRTFOBJ = WM_USER+270
120
+
121
+ EN_MSGFILTER = 0x0700
122
+ EN_REQUESTRESIZE = 0x0701
123
+ EN_SELCHANGE = 0x0702
124
+ EN_DROPFILES = 0x0703
125
+ EN_PROTECTED = 0x0704
126
+ EN_CORRECTTEXT = 0x0705
127
+ EN_STOPNOUNDO = 0x0706
128
+ EN_IMECHANGE = 0x0707
129
+ EN_SAVECLIPBOARD = 0x0708
130
+ EN_OLEOPFAILED = 0x0709
131
+ EN_OBJECTPOSITIONS = 0x070a
132
+ EN_LINK = 0x070b
133
+ EN_DRAGDROPDONE = 0x070c
134
+ EN_PARAGRAPHEXPANDED = 0x070d
135
+ EN_PAGECHANGE = 0x070e
136
+ EN_LOWFIRTF = 0x070f
137
+ EN_ALIGNLTR = 0x0710
138
+ EN_ALIGNRTL = 0x0711
139
+
140
+ ENM_NONE = 0x00000000
141
+ ENM_CHANGE = 0x00000001
142
+ ENM_UPDATE = 0x00000002
143
+ ENM_SCROLL = 0x00000004
144
+ ENM_SCROLLEVENTS = 0x00000008
145
+ ENM_DRAGDROPDONE = 0x00000010
146
+ ENM_PARAGRAPHEXPANDED = 0x00000020
147
+ ENM_PAGECHANGE = 0x00000040
148
+ ENM_KEYEVENTS = 0x00010000
149
+ ENM_MOUSEEVENTS = 0x00020000
150
+ ENM_REQUESTRESIZE = 0x00040000
151
+ ENM_SELCHANGE = 0x00080000
152
+ ENM_DROPFILES = 0x00100000
153
+ ENM_PROTECTED = 0x00200000
154
+ ENM_CORRECTTEXT = 0x00400000
155
+ ENM_IMECHANGE = 0x00800000
156
+ ENM_LANGCHANGE = 0x01000000
157
+ ENM_OBJECTPOSITIONS = 0x02000000
158
+ ENM_LINK = 0x04000000
159
+ ENM_LOWFIRTF = 0x08000000
160
+
161
+ SES_EMULATESYSEDIT = 0x1
162
+ SES_BEEPONMAXTEXT = 0x2
163
+ SES_EXTENDBACKCOLOR = 0x4
164
+ SES_MAPCPS = 0x8
165
+ SES_EMULATE10 = 0x10
166
+ SES_USECRLF = 0x20
167
+ SES_USEAIMM = 0x40
168
+ SES_NOIME = 0x80
169
+ SES_ALLOWBEEPS = 0x100
170
+ SES_UPPERCASE = 0x200
171
+ SES_LOWERCASE = 0x400
172
+ SES_NOINPUTSEQUENCECHK = 0x800
173
+ SES_BIDI = 0x1000
174
+ SES_SCROLLONKILLFOCUS = 0x2000
175
+ SES_XLTCRCRLFTOCR = 0x4000
176
+ SES_DRAFTMODE = 0x8000
177
+ SES_USECTF = 0x10000
178
+ SES_HIDEGRIDLINES = 0x20000
179
+ SES_USEATFONT = 0x40000
180
+ SES_CUSTOMLOOK = 0x80000
181
+ SES_LBSCROLLNOTIFY = 0x100000
182
+ SES_CTFALLOWEMBED = 0x200000
183
+ SES_CTFALLOWSMARTTAG = 0x400000
184
+ SES_CTFALLOWPROOFING = 0x800000
185
+
186
+ IMF_AUTOKEYBOARD = 0x0001
187
+ IMF_AUTOFONT = 0x0002
188
+ IMF_IMECANCELCOMPLETE = 0x0004
189
+ IMF_IMEALWAYSSENDNOTIFY= 0x0008
190
+ IMF_AUTOFONTSIZEADJUST = 0x0010
191
+ IMF_UIFONTS = 0x0020
192
+ IMF_DUALFONT = 0x0080
193
+
194
+ ICM_NOTOPEN = 0x0000
195
+ ICM_LEVEL3 = 0x0001
196
+ ICM_LEVEL2 = 0x0002
197
+ ICM_LEVEL2_5 = 0x0003
198
+ ICM_LEVEL2_SUI = 0x0004
199
+ ICM_CTF = 0x0005
200
+
201
+ TM_PLAINTEXT = 1
202
+ TM_RICHTEXT = 2
203
+ TM_SINGLELEVELUNDO = 4
204
+ TM_MULTILEVELUNDO = 8
205
+ TM_SINGLECODEPAGE = 16
206
+ TM_MULTICODEPAGE = 32
207
+
208
+ CFM_BOLD = 0x00000001
209
+ CFM_ITALIC = 0x00000002
210
+ CFM_UNDERLINE = 0x00000004
211
+ CFM_STRIKEOUT = 0x00000008
212
+ CFM_PROTECTED = 0x00000010
213
+ CFM_LINK = 0x00000020
214
+ CFM_SIZE = 0x80000000
215
+ CFM_COLOR = 0x40000000
216
+ CFM_FACE = 0x20000000
217
+ CFM_OFFSET = 0x10000000
218
+ CFM_CHARSET = 0x08000000
219
+
220
+ CFM_SMALLCAPS = 0x00000040
221
+ CFM_ALLCAPS = 0x00000080
222
+ CFM_HIDDEN = 0x00000100
223
+ CFM_OUTLINE = 0x00000200
224
+ CFM_SHADOW = 0x00000400
225
+ CFM_EMBOSS = 0x00000800
226
+ CFM_IMPRINT = 0x00001000
227
+ CFM_DISABLED = 0x00002000
228
+ CFM_REVISED = 0x00004000
229
+
230
+ CFM_BACKCOLOR = 0x04000000
231
+ CFM_LCID = 0x02000000
232
+ CFM_UNDERLINETYPE = 0x00800000
233
+ CFM_WEIGHT = 0x00400000
234
+ CFM_SPACING = 0x00200000
235
+ CFM_KERNING = 0x00100000
236
+ CFM_STYLE = 0x00080000
237
+ CFM_ANIMATION = 0x00040000
238
+ CFM_REVAUTHOR = 0x00008000
239
+
240
+ CFE_BOLD = 0x00000001
241
+ CFE_ITALIC = 0x00000002
242
+ CFE_UNDERLINE = 0x00000004
243
+ CFE_STRIKEOUT = 0x00000008
244
+ CFE_PROTECTED = 0x00000010
245
+ CFE_LINK = 0x00000020
246
+ CFE_AUTOCOLOR = 0x40000000
247
+ CFE_SMALLCAPS = CFM_SMALLCAPS
248
+ CFE_ALLCAPS = CFM_ALLCAPS
249
+ CFE_HIDDEN = CFM_HIDDEN
250
+ CFE_OUTLINE = CFM_OUTLINE
251
+ CFE_SHADOW = CFM_SHADOW
252
+ CFE_EMBOSS = CFM_EMBOSS
253
+ CFE_IMPRINT = CFM_IMPRINT
254
+ CFE_DISABLED = CFM_DISABLED
255
+ CFE_REVISED = CFM_REVISED
256
+
257
+ CFE_SUBSCRIPT = 0x00010000
258
+ CFE_SUPERSCRIPT = 0x00020000
259
+ CFE_AUTOBACKCOLOR = CFM_BACKCOLOR
260
+
261
+ CFM_SUBSCRIPT = CFE_SUBSCRIPT | CFE_SUPERSCRIPT
262
+ CFM_SUPERSCRIPT = CFM_SUBSCRIPT
263
+
264
+ CFM_EFFECTS = CFM_BOLD | CFM_ITALIC | CFM_UNDERLINE | CFM_STRIKEOUT | CFM_PROTECTED | CFM_LINK
265
+ CFM_ALL = CFM_EFFECTS | CFM_SIZE | CFM_FACE | CFM_OFFSET | CFM_CHARSET
266
+ CFM_EFFECTS2 = CFM_EFFECTS | CFM_DISABLED | CFM_SMALLCAPS | CFM_ALLCAPS | CFM_HIDDEN |
267
+ CFM_OUTLINE | CFM_SHADOW | CFM_EMBOSS | CFM_IMPRINT | CFM_DISABLED |
268
+ CFM_REVISED | CFM_SUBSCRIPT | CFM_SUPERSCRIPT | CFM_BACKCOLOR
269
+ CFM_ALL2 = CFM_ALL | CFM_EFFECTS2 | CFM_BACKCOLOR | CFM_LCID | CFM_UNDERLINETYPE |
270
+ CFM_WEIGHT | CFM_REVAUTHOR | CFM_SPACING | CFM_KERNING | CFM_STYLE | CFM_ANIMATION
271
+
272
+ CFU_UNDERLINENONE = 0
273
+ CFU_UNDERLINE = 1
274
+ CFU_UNDERLINEWORD = 2
275
+ CFU_UNDERLINEDOUBLE = 3
276
+ CFU_UNDERLINEDOTTED = 4
277
+ CFU_UNDERLINEDASH = 5
278
+ CFU_UNDERLINEDASHDOT = 6
279
+ CFU_UNDERLINEDASHDOTDOT = 7
280
+ CFU_UNDERLINEWAVE = 8
281
+ CFU_UNDERLINETHICK = 9
282
+ CFU_UNDERLINEHAIRLINE = 10
283
+ CFU_UNDERLINEDOUBLEWAVE = 11
284
+ CFU_UNDERLINEHEAVYWAVE = 12
285
+ CFU_UNDERLINELONGDASH = 13
286
+ CFU_UNDERLINETHICKDASH = 14
287
+ CFU_UNDERLINETHICKDASHDOT = 15
288
+ CFU_UNDERLINETHICKDASHDOTDOT = 16
289
+ CFU_UNDERLINETHICKDOTTED = 17
290
+ CFU_UNDERLINETHICKLONGDASH = 18
291
+ CFU_INVERT = 0xFE
292
+ CFU_CF1UNDERLINE = 0xFF
293
+
294
+ yHeightCharPtsMost = 1638
295
+
296
+ SCF_SELECTION = 0x0001
297
+ SCF_WORD = 0x0002
298
+ SCF_DEFAULT = 0x0000
299
+ SCF_ALL = 0x0004 # not valid with SCF_SELECTION or SCF_WORD
300
+ SCF_USEUIRULES = 0x0008
301
+ SCF_ASSOCIATEFONT = 0x0010
302
+ SCF_NOKBUPDATE = 0x0020
303
+ SCF_ASSOCIATEFONT2 = 0x0040
304
+
305
+ PFA_LEFT = 1
306
+ PFA_RIGHT = 2
307
+ PFA_CENTER = 3
308
+ PFA_JUSTIFY = 4
309
+ PFA_FULL_INTERWORD = 4
310
+ PFA_FULL_INTERLETTER = 5
311
+ PFA_FULL_SCALED = 6
312
+ PFA_FULL_GLYPHS = 7
313
+ PFA_SNAP_GRID = 8
314
+
315
+ PFM_STARTINDENT = 0x00000001
316
+ PFM_RIGHTINDENT = 0x00000002
317
+ PFM_OFFSET = 0x00000004
318
+ PFM_ALIGNMENT = 0x00000008
319
+ PFM_TABSTOPS = 0x00000010
320
+ PFM_NUMBERING = 0x00000020
321
+ PFM_OFFSETINDENT = 0x80000000
322
+
323
+ PFM_SPACEBEFORE = 0x00000040
324
+ PFM_SPACEAFTER = 0x00000080
325
+ PFM_LINESPACING = 0x00000100
326
+ PFM_STYLE = 0x00000400
327
+ PFM_BORDER = 0x00000800
328
+ PFM_SHADING = 0x00001000
329
+ PFM_NUMBERINGSTYLE = 0x00002000
330
+ PFM_NUMBERINGTAB = 0x00004000
331
+ PFM_NUMBERINGSTART = 0x00008000
332
+
333
+ PFM_RTLPARA = 0x00010000
334
+ PFM_KEEP = 0x00020000
335
+ PFM_KEEPNEXT = 0x00040000
336
+ PFM_PAGEBREAKBEFORE = 0x00080000
337
+ PFM_NOLINENUMBER = 0x00100000
338
+ PFM_NOWIDOWCONTROL = 0x00200000
339
+ PFM_DONOTHYPHEN = 0x00400000
340
+ PFM_SIDEBYSIDE = 0x00800000
341
+ PFM_TABLE = 0x40000000
342
+ PFM_TEXTWRAPPINGBREAK = 0x20000000
343
+ PFM_TABLEROWDELIMITER = 0x10000000
344
+
345
+ PFM_COLLAPSED = 0x01000000
346
+ PFM_OUTLINELEVEL = 0x02000000
347
+ PFM_BOX = 0x04000000
348
+ PFM_RESERVED2 = 0x08000000
349
+
350
+ SF_TEXT = 0x0001
351
+ SF_RTF = 0x0002
352
+ SF_RTFNOOBJS = 0x0003
353
+ SF_TEXTIZED = 0x0004
354
+ SF_UNICODE = 0x0010
355
+ SF_USECODEPAGE = 0x0020
356
+ SF_NCRFORNONASCII = 0x0040
357
+
358
+ ST_DEFAULT = 0
359
+ ST_KEEPUNDO = 1
360
+ ST_SELECTION = 2
361
+ ST_NEWCHARS = 4
362
+
363
+ GT_DEFAULT = 0
364
+ GT_USECRLF = 1
365
+ GT_SELECTION = 2
366
+ GT_RAWTEXT = 4
367
+ GT_NOHIDDENTEXT = 8
368
+
369
+ GTL_DEFAULT = 0
370
+ GTL_USECRLF = 1
371
+ GTL_PRECISE = 2
372
+ GTL_CLOSE = 4
373
+ GTL_NUMCHARS = 8
374
+ GTL_NUMBYTES = 16
375
+
376
+ UID_UNKNOWN = 0
377
+ UID_TYPING = 1
378
+ UID_DELETE = 2
379
+ UID_DRAGDROP = 3
380
+ UID_CUT = 4
381
+ UID_PASTE = 5
382
+ UID_AUTOCORRECT = 6
383
+
384
+ WBF_WORDWRAP = 0x010
385
+ WBF_WORDBREAK = 0x020
386
+ WBF_OVERFLOW = 0x040
387
+ WBF_LEVEL1 = 0x080
388
+ WBF_LEVEL2 = 0x100
389
+ WBF_CUSTOM = 0x200
390
+
391
+ CREATE_ALWAYS = 2
392
+ OPEN_EXISTING = 3
393
+ GENERIC_READ = 0x80000000
394
+ GENERIC_WRITE = 0x40000000
395
+ FILE_ATTRIBUTE_NORMAL = 0x00000080
396
+ FILE_FLAG_WRITE_THROUGH = 0x80000000
397
+
398
+ end
399
+
400
+ # This control enables the user to enter, edit, print, and save text.
401
+ # The text can be assigned character and paragraph formatting.
402
+ # <br>See also <a href="https://docs.microsoft.com/en-us/windows/desktop/Controls/
403
+ #window-controls"> Windows Control section of Microsoft Docs.</a>
404
+ class Richedit < Edit
405
+ # API.loadlib 'riched20.dll'
406
+ API.loadlib 'MsftEdit.dll'
407
+
408
+ RICHEDIT_CLASSA = "RichEdit20A"
409
+ RICHEDIT_CLASSW = "RichEdit50W"
410
+ RICHEDIT_CLASS = RWin::UNICODE ? RICHEDIT_CLASSW : RICHEDIT_CLASSA
411
+
412
+ MAX_TAB_STOPS = 32
413
+ DEFAULT_TABSPACES = 4
414
+ DEFAULTTABS = (1..MAX_TAB_STOPS).inject([]){|r, i| r << i*DEFAULT_TABSPACES}
415
+
416
+ API::TypeAliases['LCID'] = 'U'
417
+ CHARFORMAT = API.defstruct "
418
+ UINT cbSize;
419
+ DWORD dwMask;
420
+ DWORD dwEffects;
421
+ LONG yHeight;
422
+ LONG yOffset;
423
+ COLORREF crTextColor;
424
+ BYTE bCharSet;
425
+ BYTE bPitchAndFamily;
426
+ TCHAR szFaceName[#{LF_FACESIZE}];"
427
+
428
+ CHARFORMAT2 = API.defstruct "
429
+ UINT cbSize;
430
+ DWORD dwMask;
431
+ DWORD dwEffects;
432
+ LONG yHeight;
433
+ LONG yOffset;
434
+ COLORREF crTextColor;
435
+ BYTE bCharSet;
436
+ BYTE bPitchAndFamily;
437
+ TCHAR szFaceName[#{LF_FACESIZE}];
438
+ WORD wWeight;
439
+ SHORT sSpacing;
440
+ COLORREF crBackColor;
441
+ LCID lcid;
442
+ DWORD dwReserved;
443
+ SHORT sStyle;
444
+ WORD wKerning;
445
+ BYTE bUnderlineType;
446
+ BYTE bAnimation;
447
+ BYTE bRevAuthor;
448
+ BYTE bReserved1;"
449
+
450
+ PARAFORMAT = API.defstruct "
451
+ UINT cbSize;
452
+ DWORD dwMask;
453
+ WORD wNumbering;
454
+ WORD wReserved;
455
+ LONG dxStartIndent;
456
+ LONG dxRightIndent;
457
+ LONG dxOffset;
458
+ WORD wAlignment;
459
+ SHORT cTabCount;
460
+ LONG rgxTabs[#{MAX_TAB_STOPS}];"
461
+
462
+ PARAFORMAT2 = API.defstruct "
463
+ UINT cbSize;
464
+ DWORD dwMask;
465
+ WORD wNumbering;
466
+ WORD wReserved;
467
+ LONG dxStartIndent;
468
+ LONG dxRightIndent;
469
+ LONG dxOffset;
470
+ WORD wAlignment;
471
+ SHORT cTabCount;
472
+ LONG rgxTabs[#{MAX_TAB_STOPS}];
473
+ LONG dySpaceBefore;
474
+ LONG dySpaceAfter;
475
+ LONG dyLineSpacing;
476
+ SHORT sStyle;
477
+ BYTE bLineSpacingRule;
478
+ BYTE bOutlineLevel;
479
+ WORD wShadingWeight;
480
+ WORD wShadingStyle;
481
+ WORD wNumberingStart;
482
+ WORD wNumberingStyle;
483
+ WORD wNumberingTab;
484
+ WORD wBorderSpace;
485
+ WORD wBorderWidth;
486
+ WORD wBorders;"
487
+
488
+ CHARRANGE = API.defstruct "
489
+ LONG cpMin;
490
+ LONG cpMax;"
491
+
492
+ TEXTRANGE = API.defstruct "
493
+ CHARRANGE chrg;
494
+ LPTSTR lpstrText"
495
+
496
+ FINDTEXT = API.defstruct "
497
+ CHARRANGE chrg;
498
+ LPTSTR lpstrText;"
499
+
500
+ FINDTEXTEX = API.defstruct "
501
+ CHARRANGE chrg;
502
+ LPCTSTR lpstrText;
503
+ CHARRANGE chrgText;"
504
+
505
+ FORMATRANGE = API.defstruct "
506
+ HDC hdc;
507
+ HDC hdcTarget;
508
+ RECT rc;
509
+ RECT rcPage;
510
+ CHARRANGE chrg;"
511
+
512
+ MSGFILTER = API.defstruct "
513
+ NMHDR nmhdr;
514
+ UINT msg;
515
+ WPARAM wParam;
516
+ LPARAM lParam;"
517
+
518
+ REQRESIZE = API.defstruct "
519
+ NMHDR nmhdr;
520
+ RECT rc;"
521
+
522
+ SELCHANGE = API.defstruct "
523
+ NMHDR nmhdr;
524
+ CHARRANGE chrg;
525
+ WORD seltyp;"
526
+
527
+ ENDROPFILES = API.defstruct "
528
+ NMHDR nmhdr;
529
+ HANDLE hDrop;
530
+ LONG cp;
531
+ BOOL fProtected;"
532
+
533
+ ENPROTECTED = API.defstruct "
534
+ NMHDR nmhdr;
535
+ UINT msg;
536
+ WPARAM wParam;
537
+ LPARAM lParam;
538
+ CHARRANGE chrg;"
539
+
540
+ ENCORRECTTEXT = API.defstruct "
541
+ NMHDR nmhdr;
542
+ CHARRANGE chrg;
543
+ WORD seltyp;"
544
+
545
+ ENSAVECLIPBOARD = API.defstruct "
546
+ NMHDR nmhdr;
547
+ LONG cObjectCount;
548
+ LONG cch;"
549
+
550
+ API.typealias('HRESULT', 'HANDLE')
551
+ ENOLEOPFAILED = API.defstruct "
552
+ NMHDR nmhdr;
553
+ LONG iob;
554
+ LONG lOper;
555
+ HRESULT hr;"
556
+
557
+ OBJECTPOSITIONS = API.defstruct "
558
+ NMHDR nmhdr;
559
+ LONG cObjectCount;
560
+ LONG *pcpPositions;"
561
+
562
+ ENLINK = API.defstruct "
563
+ NMHDR nmhdr;
564
+ UINT msg;
565
+ WPARAM wParam;
566
+ LPARAM lParam;
567
+ CHARRANGE chrg;"
568
+
569
+ ENLOWFIRTF = API.defstruct "
570
+ NMHDR nmhdr;
571
+ CHAR *szControl;"
572
+
573
+ API.typealias('EDITSTREAMCALLBACK', 'ULONG')
574
+ EDITSTREAM = API.defstruct "
575
+ DWORD dwCookie;
576
+ DWORD dwError;
577
+ EDITSTREAMCALLBACK pfnCallback;"
578
+
579
+ SETTEXTEX = API.defstruct "
580
+ DWORD flags;
581
+ UINT codepage;"
582
+
583
+ GETTEXTEX = API.defstruct "
584
+ DWORD cb;
585
+ DWORD flags;
586
+ UINT codepage;
587
+ LPCSTR lpDefaultChar;
588
+ int *lpUsedDefChar;"
589
+
590
+ GETTEXTLENGTHEX = API.defstruct "
591
+ DWORD flags;
592
+ UINT codepage;"
593
+
594
+ CN_GENERIC = 0
595
+ CN_TEXTCHANGED = 1
596
+ CN_NEWUNDO = 2
597
+ CN_NEWREDO = 4
598
+
599
+ CHANGENOTIFY = API.defstruct "
600
+ DWORD dwChangeType;
601
+ void *pvCookieData;"
602
+
603
+ CFEffects = {
604
+ :bold => CFE_BOLD,
605
+ :italic => CFE_ITALIC,
606
+ :underline => CFE_UNDERLINE,
607
+ :strikeout => CFE_STRIKEOUT,
608
+ :protected => CFE_PROTECTED,
609
+ :link => CFE_LINK
610
+ }
611
+
612
+ PFAlignments = {
613
+ :left => PFA_LEFT,
614
+ :center => PFA_CENTER,
615
+ :right => PFA_RIGHT,
616
+ :justify => PFA_JUSTIFY,
617
+ :full_interword => PFA_FULL_INTERWORD,
618
+ :full_interletter => PFA_FULL_INTERLETTER,
619
+ :full_scaled => PFA_FULL_SCALED,
620
+ :full_glyphs => PFA_FULL_GLYPHS,
621
+ :snap_grid => PFA_SNAP_GRID
622
+ }
623
+
624
+ class Effects
625
+ def initialize(*args)
626
+ args = args[0] if args[0].is_a?(Array)
627
+ @effects = 0
628
+ args.each{|i| @effects |= i.is_a?(Symbol) ? CFEffects[arg].to_i : i.to_i}
629
+ end
630
+
631
+ def |(arg)
632
+ @effects |= arg.is_a?(Symbol) ? CFEffects[arg].to_i : arg.to_i
633
+ self
634
+ end
635
+
636
+ def &(arg)
637
+ @effects &= arg.is_a?(Symbol) ? CFEffects[arg].to_i : arg.to_i
638
+ self
639
+ end
640
+
641
+ def to_i()
642
+ @effects
643
+ end
644
+ end
645
+
646
+ class Format # wrapper of CHARFORMAT2, PARAFORMAT2
647
+ include RC
648
+ attr_reader :charformat, :paraformat
649
+
650
+ def initialize()
651
+ # @seltype = seltype # SCF_SELECTION, SCF_WORD, SCF_DEFAULT, SCF_ALL ...
652
+ @charformat = CHARFORMAT2[CHARFORMAT2::Size]
653
+ @paraformat = PARAFORMAT2[PARAFORMAT2::Size]
654
+ end
655
+
656
+ ###### charformat ######
657
+
658
+ def facename()
659
+ @charformat.szFaceName.to_s
660
+ end
661
+ def facename=(str)
662
+ if str.to_s == ''
663
+ @charformat.dwMask &= ~CFM_FACE
664
+ @charformat.szFaceName = nil
665
+ else
666
+ @charformat.dwMask |= CFM_FACE
667
+ @charformat.szFaceName = str
668
+ end
669
+ end
670
+
671
+ def height()
672
+ @charformat.yHeight
673
+ end
674
+ def height=(h)
675
+ @charformat.dwMask |= CFM_SIZE
676
+ @charformat.yHeight = h
677
+ end
678
+
679
+ def color
680
+ @charformat.crTextColor
681
+ end
682
+ def color=(*args)
683
+ txtclr, bkclr = args[0]
684
+ if txtclr
685
+ @charformat.dwMask |= CFM_COLOR
686
+ @charformat.crTextColor = txtclr
687
+ if bkclr
688
+ @charformat.dwMask |= CFM_BACKCOLOR
689
+ @charformat.crBackColor = bkclr
690
+ end
691
+ else
692
+ @charformat.dwMask &= ~CFM_COLOR
693
+ @charformat.dwMask &= ~CFM_BACKCOLOR
694
+ @charformat.crTextColor = 0
695
+ @charformat.crBackColor = 0
696
+ end
697
+ end
698
+
699
+ def effects()
700
+ @charformat.dwEffects
701
+ end
702
+ def effects=(*args)
703
+ args = args[0] if args[0].is_a?(Array)
704
+ effects = 0
705
+ args.each{|i| effects |= i.is_a?(Symbol) ? CFEffects[i].to_i : i.to_i }
706
+ if effects == 0
707
+ @charformat.dwMask |= CFM_EFFECTS
708
+ @charformat.dwEffects = 0
709
+ else
710
+ @charformat.dwMask |= CFM_EFFECTS
711
+ @charformat.dwEffects = effects
712
+ end
713
+ end
714
+
715
+ def style()
716
+ @charformat.sStyle
717
+ end
718
+ def style=(ss)
719
+ @charformat.dwMask |= CFM_STYLE
720
+ @charformat.sStyle = ss
721
+ end
722
+
723
+ ###### paraformat ######
724
+
725
+ def alignment()
726
+ @paraformat.wAlignment
727
+ end
728
+ def alignment=(al)
729
+ al = PFAlignments[al] if al.is_a?(Symbol)
730
+ @paraformat.dwMask = PFM_ALIGNMENT
731
+ @paraformat.wAlignment = al
732
+ end
733
+
734
+ def tabstops()
735
+ @paraformat.rgxTabs.to_a
736
+ end
737
+ def tabstops=(*args)
738
+ tabs = args[0] if args[0].is_a?(Array)
739
+ @paraformat.dwMask = PFM_TABSTOPS
740
+ @paraformat.rgxTabs = tabs
741
+ end
742
+
743
+ ##### sets, gets ######
744
+
745
+ def get(owner, mask, seltype=SCF_SELECTION)
746
+ @charformat.clear(CHARFORMAT2::Size, mask)
747
+ owner.SendMessage(EM_GETCHARFORMAT, seltype, @charformat)
748
+ self
749
+ end
750
+ def set(owner, seltype=SCF_SELECTION)
751
+ owner.SendMessage(EM_SETCHARFORMAT, seltype, @charformat) if @charformat.dwMask > 0
752
+ owner.SendMessage(EM_SETPARAFORMAT, 0, @paraformat) if @paraformat.dwMask > 0
753
+ @charformat.clear(CHARFORMAT2::Size)
754
+ @paraformat.clear(PARAFORMAT2::Size)
755
+ end
756
+ end
757
+
758
+ class Selection #< Edit::Selection
759
+ include RC
760
+
761
+ attr_reader :seltype
762
+
763
+ def initialize(onr)
764
+ @owner = onr
765
+ @seltype = SCF_SELECTION
766
+ @format = Format.new()
767
+ end
768
+
769
+ def seltype=(type)
770
+ @seltype = type
771
+ end
772
+
773
+ def format()
774
+ @format
775
+ end
776
+ def format=(*args)
777
+ @format.charformat.dwMask = 0
778
+ args = args[0] if args[0].is_a?(Array)
779
+ if args[0].is_a?(Richedit::Format)
780
+ @format = args.shift
781
+ end
782
+ effects = []
783
+ color = []
784
+ while i = args.shift
785
+ if i.is_a?(String)
786
+ @format.facename = i
787
+ elsif i.is_a?(Symbol)
788
+ effects << i
789
+ elsif i < 0
790
+ @format.height = i
791
+ else
792
+ color << i
793
+ end
794
+ end
795
+ @format.effects = effects
796
+ @format.color = color
797
+ @format.set(@owner, @seltype)
798
+ end
799
+
800
+ def text()
801
+ selstart, selend = self.get
802
+ buff = TCHAR[selend-selstart+1]
803
+ @owner.SendMessage(EM_GETSELTEXT, 0, buff)
804
+ buff.to_s.tr("\r", "\n")
805
+ end
806
+ def text=(txt)
807
+ @owner.SendMessage(EM_REPLACESEL, 1, txt) #API.adjust_internal_lf_code(txt))
808
+ end
809
+
810
+ def color()
811
+ @format.get(@owner, CFM_COLOR).color
812
+ end
813
+ def color=(clr)
814
+ @format.color = clr
815
+ @format.set(@owner, @seltype)
816
+ end
817
+
818
+ def effects()
819
+ @format.effects
820
+ end
821
+ def effects=(*args)
822
+ @format.effects = args[0]
823
+ @format.set(@owner, @seltype)
824
+ end
825
+
826
+ def hieght()
827
+ @format.height
828
+ end
829
+ def height=(h)
830
+ @format.height = h
831
+ @format.set(@owner, @seltype)
832
+ end
833
+
834
+ def alignment()
835
+ @format.alignment
836
+ end
837
+ def alignment=(arg)
838
+ @format.alignment = arg
839
+ @format.set(@owner)
840
+ end
841
+
842
+ def style()
843
+ @format.get(@owner, CFM_STYLE).style
844
+ end
845
+ def style=(ss)
846
+ @format.style = ss
847
+ @format.set(@owner)
848
+ end
849
+
850
+ def selstart()
851
+ chrng = CHARRANGE.new
852
+ @owner.SendMessage(EM_EXGETSEL, 0, chrng)
853
+ chrng.cpMin
854
+ end
855
+ def selend()
856
+ chrng = CHARRANGE.new
857
+ @owner.SendMessage(EM_EXGETSEL, 0, chrng)
858
+ chrng.cpMax
859
+ end
860
+
861
+ def get()
862
+ chrng = CHARRANGE.new
863
+ @owner.SendMessage(EM_EXGETSEL, 0, chrng)
864
+ [chrng.cpMin, chrng.cpMax]
865
+ end
866
+ alias to_a get
867
+ def set(selstart, selend=selstart)
868
+ chrng = CHARRANGE[selstart, selend]
869
+ @owner.SendMessage(EM_EXSETSEL, 0, chrng) == 0 ? nil : self
870
+ end
871
+
872
+ end # class
873
+
874
+ ##################### Main ####################
875
+
876
+ PreDefinedEvents = {
877
+ :msgfilter => [WM_NOTIFY, EN_MSGFILTER, 'xs', MSGFILTER],
878
+ :requestresize => [WM_NOTIFY, EN_REQUESTRESIZE, 'xs', REQRESIZE],
879
+ :selchange => [WM_NOTIFY, EN_SELCHANGE, 'xs', SELCHANGE],
880
+ :dropfiles => [WM_NOTIFY, EN_DROPFILES, 'xs', ENDROPFILES],
881
+ :protected => [WM_NOTIFY, EN_PROTECTED, 'xs', ENPROTECTED],
882
+ :correcttext => [WM_NOTIFY, EN_CORRECTTEXT, 'xs', ENCORRECTTEXT],
883
+ :stopnoundo => [WM_NOTIFY, EN_STOPNOUNDO, 'xs', NMHDR],
884
+ :imechange => [WM_COMMAND, EN_IMECHANGE, 'hi'],
885
+ :saveclipboard => [WM_NOTIFY, EN_SAVECLIPBOARD, 'xs', ENSAVECLIPBOARD],
886
+ :oleopfailed => [WM_NOTIFY, EN_OLEOPFAILED, 'xs', ENOLEOPFAILED],
887
+ :objectpositions => [WM_NOTIFY, EN_OBJECTPOSITIONS, 'xs', OBJECTPOSITIONS],
888
+ :link => [WM_NOTIFY, EN_LINK, 'xs', ENLINK],
889
+ :dragdropdone => [WM_NOTIFY, EN_DRAGDROPDONE, 'xs', NMHDR],
890
+ :paragraphexpanded => [WM_NOTIFY, EN_PARAGRAPHEXPANDED, 'xs', NMHDR],
891
+ :pagechange => [WM_NOTIFY, EN_PAGECHANGE], # not defined?
892
+ :lowfirtf => [WM_NOTIFY, EN_LOWFIRTF, 'xs', ENLOWFIRTF],
893
+ :alignltr => [WM_COMMAND, EN_ALIGNLTR, 'hi'],
894
+ :alignrtl => [WM_COMMAND, EN_ALIGNRTL, 'hi'],
895
+ :change => [WM_NOTIFY, EN_CHANGE, 'xs', CHANGENOTIFY],
896
+ # :change => [WM_COMMAND, EN_CHANGE, 'hi'],
897
+ :setfocus => [WM_COMMAND, EN_SETFOCUS, 'hi'],
898
+ :killfocus => [WM_COMMAND, EN_KILLFOCUS, 'hi'],
899
+ :update => [WM_COMMAND, EN_UPDATE, 'hi'],
900
+ :errspace => [WM_COMMAND, EN_ERRSPACE, 'hi'],
901
+ :maxtext => [WM_COMMAND, EN_MAXTEXT, 'hi'],
902
+ :hscroll => [WM_COMMAND, EN_HSCROLL, 'hi'],
903
+ :vscroll => [WM_COMMAND, EN_VSCROLL, 'hi']
904
+ }
905
+ DefaultEvents = [
906
+ :change, # ???_change(CHANGENOTIFY)
907
+ :update # ???_update(idcmd, code, hwnd)
908
+ ]
909
+
910
+ def initialize(*args)
911
+ super
912
+ @_classname = RICHEDIT_CLASS
913
+ self.style |= ES_MULTILINE
914
+ @_acceptable_events = PreDefinedEvents.dup
915
+ end
916
+ #
917
+ def create()
918
+ super
919
+ @_parent.set_msgtranslator(WM_NOTIFY) unless @_parent.get_msgtranslator(WM_NOTIFY)
920
+ # SendMessage(EM_SETLANGOPTIONS, 0, 0)
921
+ @selection = Richedit::Selection.new(self)
922
+ self.limittext = @_limittext if @_limittext
923
+ self.eventmask = @_eventmask if @_eventmask
924
+ end
925
+
926
+ # Gets the current text limit for this edit control.
927
+ def limittext()
928
+ alive? ? SendMessage(EM_GETLIMITTEXT, 0, 0) : @_limittext
929
+ end
930
+
931
+ # Sets the text limit of this edit control.
932
+ def limittext=(lim)
933
+ if alive?
934
+ SendMessage(EM_EXLIMITTEXT, 0, lim)
935
+ else
936
+ @_limittext = lim
937
+ end
938
+ end
939
+
940
+ # Retrieves the event mask for this rich edit control.
941
+ def eventmask()
942
+ alive? ? SendMessage(EM_GETEVENTMASK, 0, 0) : @_eventmask
943
+ end
944
+ # Sets the event mask for this rich edit control.
945
+ def eventmask=(mask)
946
+ alive? ? SendMessage(EM_SETEVENTMASK, 0, mask) : @_eventmask = mask
947
+ end
948
+ # Sets the event mask for this rich edit control. <br>
949
+ # Returns previous event mask
950
+ def seteventmask(mask)
951
+ SendMessage(EM_SETEVENTMASK, 0, mask)
952
+ end
953
+
954
+ # Obtains the current scroll position of this edit control.
955
+ def scrollpos()
956
+ pt = POINT.new
957
+ SendMessage(EM_GETSCROLLPOS, 0, pt)
958
+ [pt.x, pt.y]
959
+ end
960
+ # Tells this rich edit control to scroll to a particular point.
961
+ def scrollpos=(*args)
962
+ x, y = args[0].is_a?(Array) ? args[0] : [0, args[0]]
963
+ pt = POINT[x, y]
964
+ SendMessage(EM_SETSCROLLPOS, 0, pt)
965
+ end
966
+ # Scrolls this edit control to first position of document.
967
+ def scrollhome()
968
+ SendMessage(EM_SETSCROLLPOS, 0, POINT.new)
969
+ end
970
+
971
+ # Gets the starting and ending character positions of the current selection.
972
+ def selection()
973
+ @selection
974
+ end
975
+
976
+ # selection=(starting[, ending])
977
+ # Selects a range of characters in an edit control.
978
+ def selection=(*args)
979
+ selstart, selend = args[0].is_a?(Array) ? args[0] : [args[0], args[0]]
980
+ @selection.set(selstart, selend)
981
+ end
982
+
983
+
984
+ # Retreives the range of a word of current selection.
985
+ def word()
986
+ @selection.seltype = SCF_SELECTION | SCF_WORD
987
+ selection
988
+ end
989
+
990
+ # Retreives the entire selection of this rich edit control.
991
+ def all()
992
+ @selection.seltype = SCF_ALL
993
+ selection
994
+ end
995
+
996
+ # []=(position, length=1, text)
997
+ # Inserts and replaces at the specified <i>position</i> and <i>length</i> by the <i>text</i> in this edit control.
998
+ def []=(*args) #; dpp args
999
+ idx = args.shift
1000
+ len = args[0].is_a?(Integer) ? args.shift : 1
1001
+ args = args[0] if args[0].is_a?(Array)
1002
+ @selection.set(idx, idx + len)
1003
+ args.each{|i|
1004
+ if i.is_a?(String)
1005
+ @selection.text = i
1006
+ elsif i.is_a?(Integer)
1007
+ @selection.color = i
1008
+ elsif i.is_a?(Symbol)
1009
+ @selection.effects = i
1010
+ elsif i.is_a?(Format)
1011
+ end
1012
+ }
1013
+ end
1014
+
1015
+ if RWin::UNICODE
1016
+ # Gets a text length of this edit control.
1017
+ def textlength()
1018
+ gtlen = GETTEXTLENGTHEX[GT_DEFAULT, CP_UNICODE]
1019
+ SendMessage(EM_GETTEXTLENGTHEX, gtlen, 0)
1020
+ end
1021
+ else
1022
+ # Gets a text length of this edit control.
1023
+ def textlength()
1024
+ SenMmessage(WM_GETTEXTLENGTH, 0, 0)
1025
+ end
1026
+ end
1027
+
1028
+ # Retrieves the type of the next undo action, if any. <br>
1029
+ # Retruns an integer as UNDONAMEID.
1030
+ def getundoname()
1031
+ SendMessage(EM_GETUNDONAME, 0, 0)
1032
+ end
1033
+ # Retrieves the type of the next redo action, if any.
1034
+ # Retruns an integer as UNDONAMEID.
1035
+ def getredoname()
1036
+ SendMessage(EM_GETREDONAME, 0, 0)
1037
+ end
1038
+
1039
+ # Sets the maximum number of actions that can stored in the undo queue.
1040
+ def setundolimit(lim=100)
1041
+ SendMessage(EM_SETUNDOLIMIT, lim, 0)
1042
+ end
1043
+
1044
+ # Retreives a line number of specified position in this edit control.
1045
+ def pos2line(pos)
1046
+ SendMessage(EM_EXLINEFROMCHAR, 0, pos)
1047
+ end
1048
+
1049
+ # Retreives a first position of specified line number in this edit control.
1050
+ def line2pos(lin)
1051
+ SendMessage(EM_LINEINDEX, lin, 0)
1052
+ end
1053
+
1054
+ # Retrieves a specified range of characters from this rich edit control.
1055
+ def textrange(from, to)
1056
+ lpstr = TCHAR[to - from + 1]
1057
+ txtrng = TEXTRANGE[CHARRANGE[from, to], lpstr]
1058
+ SendMessage(EM_GETTEXTRANGE, 0, txtrng)
1059
+ txtrng.lpstrText.to_s
1060
+ end
1061
+
1062
+ # Retreives a position of specified coordinate(x, y) in this edit control.
1063
+ def point2pos(x, y)
1064
+ SendMessage(EM_CHARFROMPOS, 0, POINT[x, y])
1065
+ end
1066
+ alias hittest point2pos
1067
+
1068
+ # Retreives a line number of specified coordinate(x, y) in this edit control.
1069
+ def point2line(x, y)
1070
+ pos2line(point2pos(x, y))
1071
+ end
1072
+
1073
+ # Scrolls the text to specified line and column.
1074
+ def linescroll(ln)
1075
+ SendMessage(EM_LINESCROLL, 0, ln)
1076
+ end
1077
+
1078
+ # Counts num of lines in this edit control.
1079
+ def countlines()
1080
+ SendMessage(EM_GETLINECOUNT, 0, 0)
1081
+ end
1082
+
1083
+ # Gets the length of a line of specified position.
1084
+ def linelength(pos)
1085
+ SendMessage(EM_LINELENGTH, pos, 0)
1086
+ end
1087
+
1088
+ # Sets initial font for this edit control. This is for font-inheritance.
1089
+ def font=(fnt)
1090
+ @__font = fnt.respond_to?(:font) ? fnt.font : fnt
1091
+ super
1092
+ end
1093
+ # Gets initial font for this edit control.
1094
+ def font()
1095
+ @__font
1096
+ end
1097
+
1098
+ # Clears all documents in this edit control.
1099
+ def clear()
1100
+ self.text = ''
1101
+ charformat = CHARFORMAT2[CHARFORMAT2::Size, CFM_ALL2]
1102
+ chrng = CHARRANGE[0, 0]
1103
+ SendMessage(EM_EXSETSEL, 0, chrng)
1104
+ end
1105
+
1106
+ API.loadlib 'kernel32.dll'
1107
+ API.defun 'CreateFile(LPCTSTR lpFileName,
1108
+ DWORD dwDesiredAccess,
1109
+ DWORD dwShareMode,
1110
+ LPSECURITY_ATTRIBUTES lpSecurityAttributes,
1111
+ DWORD dwCreationDisposition,
1112
+ DWORD dwFlagsAndAttributes,
1113
+ HANDLE hTemplateFile)'
1114
+
1115
+ API.defun 'CloseHandle(HANDLE handle)'
1116
+
1117
+ API.defun 'WriteFile( HANDLE hFile,
1118
+ LPCVOID lpBuffer,
1119
+ DWORD nNumberOfBytesToWrite,
1120
+ LPDWORD lpNumberOfBytesWritten,
1121
+ LPOVERLAPPED lpOverlapped)'
1122
+
1123
+ API.defun 'ReadFile( HANDLE hFile,
1124
+ LPVOID lpBuffer,
1125
+ DWORD nNumberOfBytesToRead,
1126
+ LPDWORD lpNumberOfBytesRead,
1127
+ LPOVERLAPPED lpOverlapped)'
1128
+
1129
+ # Saves this rich-edit control to the <i>path</i> with specified format.
1130
+ def saveto(path, uformat=SF_RTF)
1131
+ editstreamcallback = lambda{|hFile, pbBuf, cb, pcb|
1132
+ API.WriteFile(hFile, pbBuf, cb, pcb, 0)
1133
+ return 0
1134
+ }
1135
+ hfile = API.createFile(path, GENERIC_WRITE, 0, 0, CREATE_ALWAYS,
1136
+ FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH, 0)
1137
+ # hfile = API.createFile(path, 0x40000000, 0, 0, 2, 0x80000080, 0)
1138
+ raise "Failed to open file:`#{path}'" if hfile == 0
1139
+ begin
1140
+ editstream = EDITSTREAM.new
1141
+ editstream.dwCookie = hfile
1142
+ editstream.pfnCallback = API.bindCallbackProc(editstreamcallback)
1143
+ SendMessage(EM_STREAMOUT, uformat, editstream)
1144
+ ensure
1145
+ API.closeHandle(hfile)
1146
+ API.releaseCallbackProc(editstreamcallback)
1147
+ end
1148
+ end
1149
+
1150
+
1151
+ # Loads from specified <i>poath</i> into this rich-edit control with specified format.<br>
1152
+ # All existing documents will be cleared on loading.
1153
+ def loadfrom(path, uformat=SF_RTF)
1154
+ editstreamcallback = lambda{|hFile, pbBuf, cb, pcb| # dpp [hFile, pbBuf, cb, pcb]
1155
+ API.ReadFile(hFile, pbBuf, cb, pcb, 0)
1156
+ return 0
1157
+ }
1158
+ hfile = API.createFile(path, GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)
1159
+ # hfile = API.createFile(path, 0x80000000, 0, 0, 3, 0x00000080, 0)
1160
+ raise "Failed to open file:`#{path}'" if hfile == 0
1161
+ begin
1162
+ editstream = EDITSTREAM.new
1163
+ editstream.dwCookie = hfile
1164
+ editstream.pfnCallback = API.bindCallbackProc(editstreamcallback)
1165
+ SendMessage(EM_STREAMIN, uformat, editstream)
1166
+ ensure
1167
+ API.closeHandle(hfile)
1168
+ API.releaseCallbackProc(editstreamcallback)
1169
+ end
1170
+ end
1171
+
1172
+ protected
1173
+ def _apply_options(arg)
1174
+ if st=WinStyles[arg]
1175
+ self.style |= st
1176
+ return nil
1177
+ end
1178
+ super
1179
+ end
1180
+ end # class
1181
+ end