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,281 @@
1
+ /*
2
+ # Project WRB was forked from Project VisualuRuby(temp-name).
3
+ # Author of this project: BANJO Koyu <banjokoyu at gmail.com>
4
+ # The URL of this project: https://bitbucket.org/wrb/
5
+ #
6
+ # This is a ext-library part of WRB.
7
+ */
8
+
9
+ #include "rwin.h"
10
+ ULONG_PTR
11
+ rw_call_std_func_0(ULONG_PTR* arg){
12
+ return ((FARPROC)arg[0])();
13
+ }
14
+ ULONG_PTR
15
+ rw_call_std_func_1(ULONG_PTR* arg){
16
+ return ((FARPROC)arg[0])(arg[1]);
17
+ }
18
+ ULONG_PTR
19
+ rw_call_std_func_2(ULONG_PTR* arg){
20
+ return ((FARPROC)arg[0])(arg[1], arg[2]);
21
+ }
22
+ ULONG_PTR
23
+ rw_call_std_func_3(ULONG_PTR* arg){
24
+ return ((FARPROC)arg[0])(arg[1], arg[2], arg[3]);
25
+ }
26
+ ULONG_PTR
27
+ rw_call_std_func_4(ULONG_PTR* arg){
28
+ return ((FARPROC)arg[0])(arg[1], arg[2], arg[3], arg[4]);
29
+ }
30
+ ULONG_PTR
31
+ rw_call_std_func_5(ULONG_PTR* arg){
32
+ return ((FARPROC)arg[0])(arg[1], arg[2], arg[3], arg[4], arg[5]);
33
+ }
34
+ ULONG_PTR
35
+ rw_call_std_func_6(ULONG_PTR* arg){
36
+ return ((FARPROC)arg[0])(arg[1], arg[2], arg[3], arg[4], arg[5], arg[6]);
37
+ }
38
+ ULONG_PTR
39
+ rw_call_std_func_7(ULONG_PTR* arg){
40
+ return ((FARPROC)arg[0])(arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7]);
41
+ }
42
+ ULONG_PTR
43
+ rw_call_std_func_8(ULONG_PTR* arg){
44
+ return ((FARPROC)arg[0])(arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7], arg[8]);
45
+ }
46
+ ULONG_PTR
47
+ rw_call_std_func_9(ULONG_PTR* arg){
48
+ return ((FARPROC)arg[0])(arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7], arg[8], arg[9]);
49
+ }
50
+ ULONG_PTR
51
+ rw_call_std_func_10(ULONG_PTR* arg){
52
+ return ((FARPROC)arg[0])(arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7], arg[8], arg[9], arg[10]);
53
+ }
54
+ ULONG_PTR
55
+ rw_call_std_func_11(ULONG_PTR* arg){
56
+ return ((FARPROC)arg[0])(arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7], arg[8], arg[9], arg[10], arg[11]);
57
+ }
58
+ ULONG_PTR
59
+ rw_call_std_func_12(ULONG_PTR* arg){
60
+ return ((FARPROC)arg[0])(arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7], arg[8], arg[9], arg[10], arg[11], arg[12]);
61
+ }
62
+
63
+ #ifdef RWIN_USEMULTITHREAD
64
+
65
+ ULONG_PTR
66
+ rw_call_without_gvl_0(DWORD thread_id, FARPROC winproc){
67
+ if(thread_id == GetCurrentThreadId()) {
68
+ return winproc();
69
+ }else{
70
+ ULONG_PTR stdcdata[1]; stdcdata[0] = (ULONG_PTR)winproc;
71
+ return CALL_NON_GVL_FUNC(rw_call_std_func_0, stdcdata);
72
+ }
73
+ }
74
+ ULONG_PTR
75
+ rw_call_without_gvl_1(DWORD thread_id, FARPROC winproc, ULONG_PTR arg1){
76
+ if(thread_id == GetCurrentThreadId()) {
77
+ return winproc(arg1);
78
+ }else{
79
+ ULONG_PTR stdcdata[2]; stdcdata[0] = (ULONG_PTR)winproc;
80
+ stdcdata[1] = arg1;
81
+ return CALL_NON_GVL_FUNC(rw_call_std_func_1, stdcdata);
82
+ }
83
+ }
84
+ ULONG_PTR
85
+ rw_call_without_gvl_2(DWORD thread_id, FARPROC winproc, ULONG_PTR arg1, ULONG_PTR arg2){
86
+ if(thread_id == GetCurrentThreadId()) {
87
+ return winproc(arg1, arg2);
88
+ }else{
89
+ ULONG_PTR stdcdata[3]; stdcdata[0] = (ULONG_PTR)winproc;
90
+ stdcdata[1] = arg1; stdcdata[2] = arg2;
91
+ return CALL_NON_GVL_FUNC(rw_call_std_func_2, stdcdata);
92
+ }
93
+ }
94
+ ULONG_PTR
95
+ rw_call_without_gvl_3(DWORD thread_id, FARPROC winproc, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3){
96
+ if(thread_id == GetCurrentThreadId()) {
97
+ return winproc(arg1, arg2, arg3);
98
+ }else{
99
+ ULONG_PTR stdcdata[4]; stdcdata[0] = (ULONG_PTR)winproc;
100
+ stdcdata[1] = arg1; stdcdata[2] = arg2;
101
+ stdcdata[3] = arg3;
102
+ return CALL_NON_GVL_FUNC(rw_call_std_func_3, stdcdata);
103
+ }
104
+ }
105
+ ULONG_PTR
106
+ rw_call_without_gvl_4(DWORD thread_id, FARPROC winproc, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, ULONG_PTR arg4){
107
+ if(thread_id == GetCurrentThreadId()) {
108
+ return winproc(arg1, arg2, arg3, arg4);
109
+ }else{
110
+ ULONG_PTR stdcdata[5]; stdcdata[0] = (ULONG_PTR)winproc;
111
+ stdcdata[1] = arg1; stdcdata[2] = arg2;
112
+ stdcdata[3] = arg3; stdcdata[4] = arg4;
113
+ return CALL_NON_GVL_FUNC(rw_call_std_func_4, stdcdata);
114
+ }
115
+ }
116
+ ULONG_PTR
117
+ rw_call_without_gvl_5(DWORD thread_id, FARPROC winproc, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, ULONG_PTR arg4, ULONG_PTR arg5){
118
+ if(thread_id == GetCurrentThreadId()) {
119
+ return winproc(arg1, arg2, arg3, arg4, arg5);
120
+ }else{
121
+ ULONG_PTR stdcdata[6]; stdcdata[0] = (ULONG_PTR)winproc;
122
+ stdcdata[1] = arg1; stdcdata[2] = arg2;
123
+ stdcdata[3] = arg3; stdcdata[4] = arg4;
124
+ stdcdata[5] = arg5;
125
+ return CALL_NON_GVL_FUNC(rw_call_std_func_5, stdcdata);
126
+ }
127
+ }
128
+ ULONG_PTR
129
+ rw_call_without_gvl_6(DWORD thread_id, FARPROC winproc, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, ULONG_PTR arg4, ULONG_PTR arg5, ULONG_PTR arg6){
130
+ if(thread_id == GetCurrentThreadId()) {
131
+ return winproc(arg1, arg2, arg3, arg4, arg5, arg6);
132
+ }else{
133
+ ULONG_PTR stdcdata[7]; stdcdata[0] = (ULONG_PTR)winproc;
134
+ stdcdata[1] = arg1; stdcdata[2] = arg2;
135
+ stdcdata[3] = arg3; stdcdata[4] = arg4;
136
+ stdcdata[5] = arg5; stdcdata[6] = arg6;
137
+ return CALL_NON_GVL_FUNC(rw_call_std_func_6, stdcdata);
138
+ }
139
+ }
140
+ ULONG_PTR
141
+ rw_call_without_gvl_7(DWORD thread_id, FARPROC winproc, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, ULONG_PTR arg4, ULONG_PTR arg5, ULONG_PTR arg6, ULONG_PTR arg7){
142
+ if(thread_id == GetCurrentThreadId()) {
143
+ return winproc(arg1, arg2, arg3, arg4, arg5, arg6, arg7);
144
+ }else{
145
+ ULONG_PTR stdcdata[8]; stdcdata[0] = (ULONG_PTR)winproc;
146
+ stdcdata[1] = arg1; stdcdata[2] = arg2;
147
+ stdcdata[3] = arg3; stdcdata[4] = arg4;
148
+ stdcdata[5] = arg5; stdcdata[6] = arg6;
149
+ stdcdata[7] = arg7;
150
+ return CALL_NON_GVL_FUNC(rw_call_std_func_7, stdcdata);
151
+ }
152
+ }
153
+ ULONG_PTR
154
+ rw_call_without_gvl_8(DWORD thread_id, FARPROC winproc, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, ULONG_PTR arg4, ULONG_PTR arg5, ULONG_PTR arg6, ULONG_PTR arg7, ULONG_PTR arg8){
155
+ if(thread_id == GetCurrentThreadId()) {
156
+ return winproc(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
157
+ }else{
158
+ ULONG_PTR stdcdata[9]; stdcdata[0] = (ULONG_PTR)winproc;
159
+ stdcdata[1] = arg1; stdcdata[2] = arg2;
160
+ stdcdata[3] = arg3; stdcdata[4] = arg4;
161
+ stdcdata[5] = arg5; stdcdata[6] = arg6;
162
+ stdcdata[7] = arg7; stdcdata[8] = arg8;
163
+ return CALL_NON_GVL_FUNC(rw_call_std_func_8, stdcdata);
164
+ }
165
+ }
166
+ ULONG_PTR
167
+ rw_call_without_gvl_9(DWORD thread_id, FARPROC winproc, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, ULONG_PTR arg4, ULONG_PTR arg5, ULONG_PTR arg6, ULONG_PTR arg7, ULONG_PTR arg8, ULONG_PTR arg9){
168
+ if(thread_id == GetCurrentThreadId()) {
169
+ return winproc(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
170
+ }else{
171
+ ULONG_PTR stdcdata[10]; stdcdata[0] = (ULONG_PTR)winproc;
172
+ stdcdata[1] = arg1; stdcdata[2] = arg2;
173
+ stdcdata[3] = arg3; stdcdata[4] = arg4;
174
+ stdcdata[5] = arg5; stdcdata[6] = arg6;
175
+ stdcdata[7] = arg7; stdcdata[8] = arg8;
176
+ stdcdata[9] = arg9;
177
+ return CALL_NON_GVL_FUNC(rw_call_std_func_9, stdcdata);
178
+ }
179
+ }
180
+ ULONG_PTR
181
+ rw_call_without_gvl_10(DWORD thread_id, FARPROC winproc, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, ULONG_PTR arg4, ULONG_PTR arg5, ULONG_PTR arg6, ULONG_PTR arg7, ULONG_PTR arg8, ULONG_PTR arg9, ULONG_PTR arg10){
182
+ if(thread_id == GetCurrentThreadId()) {
183
+ return winproc(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10);
184
+ }else{
185
+ ULONG_PTR stdcdata[11]; stdcdata[0] = (ULONG_PTR)winproc;
186
+ stdcdata[1] = arg1; stdcdata[2] = arg2;
187
+ stdcdata[3] = arg3; stdcdata[4] = arg4;
188
+ stdcdata[5] = arg5; stdcdata[6] = arg6;
189
+ stdcdata[7] = arg7; stdcdata[8] = arg8;
190
+ stdcdata[9] = arg9; stdcdata[10] = arg10;
191
+ return CALL_NON_GVL_FUNC(rw_call_std_func_10, stdcdata);
192
+ }
193
+ }
194
+ ULONG_PTR
195
+ rw_call_without_gvl_11(DWORD thread_id, FARPROC winproc, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, ULONG_PTR arg4, ULONG_PTR arg5, ULONG_PTR arg6, ULONG_PTR arg7, ULONG_PTR arg8, ULONG_PTR arg9, ULONG_PTR arg10, ULONG_PTR arg11){
196
+ if(thread_id == GetCurrentThreadId()) {
197
+ return winproc(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11);
198
+ }else{
199
+ ULONG_PTR stdcdata[12]; stdcdata[0] = (ULONG_PTR)winproc;
200
+ stdcdata[1] = arg1; stdcdata[2] = arg2;
201
+ stdcdata[3] = arg3; stdcdata[4] = arg4;
202
+ stdcdata[5] = arg5; stdcdata[6] = arg6;
203
+ stdcdata[7] = arg7; stdcdata[8] = arg8;
204
+ stdcdata[9] = arg9; stdcdata[10] = arg10;
205
+ stdcdata[11] = arg11;
206
+ return CALL_NON_GVL_FUNC(rw_call_std_func_11, stdcdata);
207
+ }
208
+ }
209
+ ULONG_PTR
210
+ rw_call_without_gvl_12(DWORD thread_id, FARPROC winproc, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, ULONG_PTR arg4, ULONG_PTR arg5, ULONG_PTR arg6, ULONG_PTR arg7, ULONG_PTR arg8, ULONG_PTR arg9, ULONG_PTR arg10, ULONG_PTR arg11, ULONG_PTR arg12){
211
+ if(thread_id == GetCurrentThreadId()) {
212
+ return winproc(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12);
213
+ }else{
214
+ ULONG_PTR stdcdata[13]; stdcdata[0] = (ULONG_PTR)winproc;
215
+ stdcdata[1] = arg1; stdcdata[2] = arg2;
216
+ stdcdata[3] = arg3; stdcdata[4] = arg4;
217
+ stdcdata[5] = arg5; stdcdata[6] = arg6;
218
+ stdcdata[7] = arg7; stdcdata[8] = arg8;
219
+ stdcdata[9] = arg9; stdcdata[10] = arg10;
220
+ stdcdata[11] = arg11; stdcdata[12] = arg12;
221
+ return CALL_NON_GVL_FUNC(rw_call_std_func_12, stdcdata);
222
+ }
223
+ }
224
+
225
+ #else
226
+
227
+ ULONG_PTR
228
+ rw_call_without_gvl_0(DWORD thread_id, FARPROC winproc){
229
+ return winproc();
230
+ }
231
+ ULONG_PTR
232
+ rw_call_without_gvl_1(DWORD thread_id, FARPROC winproc, ULONG_PTR arg1){
233
+ return winproc(arg1);
234
+ }
235
+ ULONG_PTR
236
+ rw_call_without_gvl_2(DWORD thread_id, FARPROC winproc, ULONG_PTR arg1, ULONG_PTR arg2){
237
+ return winproc(arg1, arg2);
238
+ }
239
+ ULONG_PTR
240
+ rw_call_without_gvl_3(DWORD thread_id, FARPROC winproc, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3){
241
+ return winproc(arg1, arg2, arg3);
242
+ }
243
+
244
+ ULONG_PTR
245
+ rw_call_without_gvl_4(DWORD thread_id, FARPROC winproc, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, ULONG_PTR arg4){
246
+ return winproc(arg1, arg2, arg3, arg4);
247
+ }
248
+ ULONG_PTR
249
+ rw_call_without_gvl_5(DWORD thread_id, FARPROC winproc, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, ULONG_PTR arg4, ULONG_PTR arg5){
250
+ return winproc(arg1, arg2, arg3, arg4, arg5);
251
+ }
252
+ ULONG_PTR
253
+ rw_call_without_gvl_6(DWORD thread_id, FARPROC winproc, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, ULONG_PTR arg4, ULONG_PTR arg5, ULONG_PTR arg6){
254
+ return winproc(arg1, arg2, arg3, arg4, arg5, arg6);
255
+ }
256
+ ULONG_PTR
257
+ rw_call_without_gvl_7(DWORD thread_id, FARPROC winproc, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, ULONG_PTR arg4, ULONG_PTR arg5, ULONG_PTR arg6, ULONG_PTR arg7){
258
+ return winproc(arg1, arg2, arg3, arg4, arg5, arg6, arg7);
259
+ }
260
+ ULONG_PTR
261
+ rw_call_without_gvl_8(DWORD thread_id, FARPROC winproc, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, ULONG_PTR arg4, ULONG_PTR arg5, ULONG_PTR arg6, ULONG_PTR arg7, ULONG_PTR arg8){
262
+ return winproc(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
263
+ }
264
+ ULONG_PTR
265
+ rw_call_without_gvl_9(DWORD thread_id, FARPROC winproc, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, ULONG_PTR arg4, ULONG_PTR arg5, ULONG_PTR arg6, ULONG_PTR arg7, ULONG_PTR arg8, ULONG_PTR arg9){
266
+ return winproc(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
267
+ }
268
+ ULONG_PTR
269
+ rw_call_without_gvl_10(DWORD thread_id, FARPROC winproc, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, ULONG_PTR arg4, ULONG_PTR arg5, ULONG_PTR arg6, ULONG_PTR arg7, ULONG_PTR arg8, ULONG_PTR arg9, ULONG_PTR arg10){
270
+ return winproc(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10);
271
+ }
272
+ ULONG_PTR
273
+ rw_call_without_gvl_11(DWORD thread_id, FARPROC winproc, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, ULONG_PTR arg4, ULONG_PTR arg5, ULONG_PTR arg6, ULONG_PTR arg7, ULONG_PTR arg8, ULONG_PTR arg9, ULONG_PTR arg10, ULONG_PTR arg11){
274
+ return winproc(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11);
275
+ }
276
+ ULONG_PTR
277
+ rw_call_without_gvl_12(DWORD thread_id, FARPROC winproc, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, ULONG_PTR arg4, ULONG_PTR arg5, ULONG_PTR arg6, ULONG_PTR arg7, ULONG_PTR arg8, ULONG_PTR arg9, ULONG_PTR arg10, ULONG_PTR arg11, ULONG_PTR arg12){
278
+ return winproc(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12);
279
+ }
280
+
281
+ #endif
@@ -0,0 +1,1936 @@
1
+ /*
2
+ # Project WRB was forked from Project VisualuRuby(temp-name).
3
+ # Author of this project: BANJO Koyu <banjokoyu at gmail.com>
4
+ # The URL of this project: https://bitbucket.org/wrb/
5
+ #
6
+ # This is a ext-library part of WRB.
7
+ */
8
+
9
+ #include "rwin.h"
10
+
11
+ VALUE cRwWindow;
12
+
13
+ /* TypedData */
14
+ void rw_win_free(void *ptr){
15
+ RwWindow *rw = ptr;
16
+ if (rw->hwnd) DestroyWindow(rw->hwnd);
17
+ if (rw->msgfilter) freeAAtree(rw->msgfilter);
18
+ if (rw->handler_ids) freeAAtree(rw->handler_ids);
19
+ if (rw->haccel) DestroyAcceleratorTable(rw->haccel);
20
+ free(rw);
21
+ }
22
+
23
+ static size_t
24
+ rwwin_memsize(const void *ptr){
25
+ return ptr ? sizeof(RwWindow) : 0;
26
+ }
27
+
28
+ const rb_data_type_t
29
+ rwwin_data_type = {
30
+ "Window", {NULL, rw_win_free, rwwin_memsize}, NULL, NULL
31
+ };
32
+
33
+ static VALUE
34
+ alloc_rw_window(VALUE klass){
35
+ RwWindow *rw;
36
+ VALUE obj;
37
+ obj = RwWindow_Data_Make_Struct(klass, rw);
38
+
39
+ rw->msgfilter = NULL;
40
+ rw->handler_ids = NULL;
41
+ rw->haccel = NULL;
42
+ return obj;
43
+ }
44
+
45
+ /* message handler for RWin::Window */
46
+
47
+ static RwBaseHandler*
48
+ create_basehandler(RwMsgHandler *handler, AAtree *senders){
49
+ RwBaseHandler* basehandler;
50
+ RW_MALLOC(basehandler, sizeof(RwBaseHandler));
51
+ basehandler->handler = handler;
52
+ basehandler->senders = senders;
53
+ return basehandler;
54
+ }
55
+
56
+ static void
57
+ free_msghandler(RwMsgHandler *handler){
58
+ if(handler->arg_template) free(handler->arg_template);
59
+ free(handler);
60
+ }
61
+
62
+ static RwMsgHandler*
63
+ alloc_msghandler(ID handler_id, VALUE v_klass, VALUE v_sendto){
64
+ RwMsgHandler *handler;
65
+ RW_CALLOC(handler, sizeof(RwMsgHandler));
66
+ handler->handler_id = handler_id;
67
+ handler->klass = v_klass;
68
+ handler->receiver = v_sendto;
69
+ handler->next = NULL;
70
+ return handler;
71
+ }
72
+
73
+ static RwMsgHandler*
74
+ create_msghandler(ID handler_id, VALUE v_template, VALUE v_klass, VALUE v_sendto){
75
+ RwMsgHandler *handler;
76
+ char *arg_template;
77
+ size_t len;
78
+
79
+ switch (TYPE(v_template)){
80
+ case T_NIL:
81
+ handler = alloc_msghandler(handler_id, v_klass, v_sendto);
82
+ handler->arg_template = NULL;
83
+ break;
84
+ case T_STRING:
85
+ handler = alloc_msghandler(handler_id, v_klass, v_sendto);
86
+ len = RSTRING_LEN(v_template);
87
+ if (len > 0) {
88
+ arg_template = malloc(len+1);
89
+ memcpy(arg_template, RSTRING_PTR(v_template), len);
90
+ arg_template[len] = 0;
91
+ handler->arg_template = arg_template;
92
+ }
93
+ break;
94
+ default:
95
+ rb_raise(rb_eArgError, "Template must be a String");
96
+ }
97
+ return handler;
98
+ }
99
+
100
+ static void
101
+ aa_destruct1(void* val){
102
+ if (val) freeAAtree((AAtree*)val);
103
+ }
104
+
105
+ static void
106
+ aa_destruct_handler(void* val){
107
+ RwMsgHandler *handler = val;
108
+ while(handler){
109
+ RwMsgHandler *hh = handler;
110
+ handler = handler->next;
111
+ free_msghandler(hh);
112
+ }
113
+ }
114
+
115
+ static void
116
+ aa_destruct_basehandler(void* val){
117
+ if (val) { /* delete all msgfilter */
118
+ RwBaseHandler *basehandler = val;
119
+ if (basehandler->senders) freeAAtree(basehandler->senders);
120
+ if (basehandler->handler) aa_destruct_handler(basehandler->handler);
121
+ }
122
+ }
123
+
124
+ static void
125
+ rw_msgreceiver_add(VALUE receiver, ID handler_id){
126
+ AAnode *idnode;
127
+ RwWindow *rcv;
128
+ RwWindow_Data_Get_Struct(receiver, rcv);
129
+ if (!rcv->handler_ids) rcv->handler_ids = newAAtree(NULL);
130
+ if (idnode=aaSearch(rcv->handler_ids, handler_id)){
131
+ idnode->num++;
132
+ } else {
133
+ aaInsert(rcv->handler_ids, handler_id, 0);
134
+ }
135
+ }
136
+
137
+ static RwMsgHandler*
138
+ rw_append_handler(RwMsgHandler *handler, RwMsgHandler *newhandler){
139
+ RwMsgHandler *next;
140
+ RwMsgHandler *root = handler;
141
+ ID handler_id = newhandler->handler_id;
142
+ VALUE receiver = newhandler->receiver;
143
+ if (!handler) return newhandler;
144
+ if(handler->handler_id==handler_id && handler->receiver==receiver){
145
+ rb_raise(rb_eRuntimeError, "`%s' is already defined.", rb_id2name(handler_id));
146
+ }
147
+ while(next = handler->next){
148
+ if (next->handler_id == handler_id && next->receiver==receiver){
149
+ rb_raise(rb_eRuntimeError, "`%s' is already defined in destination.",
150
+ rb_id2name(handler_id));
151
+ }
152
+ if(handler->next) handler = handler->next;
153
+ }
154
+ rw_msgreceiver_add(receiver, newhandler->handler_id);
155
+ handler->next = newhandler; /* append data at last */
156
+ return root;
157
+ }
158
+
159
+ static void
160
+ add_simple_filter(AAtree *msgfilter, unsigned msg, RwMsgHandler *newhandler){
161
+ AAnode *node = aaSearch(msgfilter, msg);
162
+ if (node){
163
+ if (node->val) {
164
+ node->val = rw_append_handler((RwMsgHandler*)(node->val), newhandler);
165
+ } else {
166
+ rw_msgreceiver_add(newhandler->receiver, newhandler->handler_id);
167
+ node->val = newhandler;
168
+ }
169
+ } else {
170
+ rw_msgreceiver_add(newhandler->receiver, newhandler->handler_id);
171
+ aaInsert(msgfilter, msg, newhandler);
172
+ }
173
+ }
174
+
175
+ static VALUE
176
+ rwwin_msgtranslator_set(int argc, VALUE *argv, VALUE self){
177
+ int msg;
178
+ ID callback_id;
179
+ RwBaseHandler *basehandler;
180
+ VALUE v_msg, v_callback, v_template;
181
+ RwMsgHandler *newhandler;
182
+
183
+ RwWindow *rw = DATA_PTR(self);
184
+ rb_scan_args(argc, argv, "12", &v_msg, &v_callback, &v_template);
185
+ msg = FIX2INT(v_msg);
186
+ callback_id = NIL_P(v_callback) ? Qfalse : rb_to_id(v_callback);
187
+ if(rw->msgfilter) {
188
+ AAnode *ndbase = aaSearch(rw->msgfilter, msg);
189
+ if (ndbase){ /* Node must be empty. */
190
+ rb_raise(rb_eRuntimeError, "Already defined handler for msg: %#x", msg);
191
+ } else {
192
+ newhandler = create_msghandler(callback_id, v_template, Qfalse, Qfalse);
193
+ basehandler = create_basehandler(newhandler, newAAtree(aa_destruct1));
194
+ aaInsert(rw->msgfilter, msg, basehandler);
195
+ }
196
+ } else {
197
+ newhandler = create_msghandler(callback_id, v_template, Qfalse, Qfalse);
198
+ basehandler = create_basehandler(newhandler, newAAtree(aa_destruct1));
199
+ rw->msgfilter = newAAtree(aa_destruct_basehandler);
200
+ aaInsert(rw->msgfilter, msg, basehandler);
201
+ }
202
+ return Qnil;
203
+ }
204
+
205
+ static VALUE
206
+ rwwin_msgtranslator_get(VALUE self, VALUE v_msg){
207
+ AAnode *node;
208
+ int msg = FIX2INT(v_msg);
209
+ RwWindow *rw = DATA_PTR(self);
210
+ if (!rw->msgfilter) return Qnil;
211
+ node = aaSearch(rw->msgfilter, msg);
212
+ if(node){
213
+ RwBaseHandler *basehandler = node->val;
214
+ if (basehandler->senders){
215
+ return INT2FIX(basehandler->handler->handler_id);
216
+ } else {
217
+ rb_raise(rb_eRuntimeError, "Already defined handler for msg: %#x", msg);
218
+ }
219
+ }
220
+ return Qnil;
221
+ }
222
+
223
+ static VALUE
224
+ rwwin_msgfilter_add(int argc, VALUE *argv, VALUE self){
225
+ RwBaseHandler *basehandler;
226
+ RwMsgHandler *newhandler;
227
+ unsigned msg, submsg;
228
+ ID handler_id;
229
+ int etc;
230
+ VALUE v_msg, v_submsg, v_etc, v_handler, v_template, v_sendto, v_klass;
231
+
232
+ RwWindow *rw = DATA_PTR(self);
233
+ v_sendto = self;
234
+ v_template = Qnil;
235
+ v_klass = Qnil;
236
+ while (NIL_P(argv[argc-1])){ /* reject last nil */
237
+ argc--;
238
+ }
239
+ if (rb_typeddata_is_kind_of(argv[argc-1], &rwwin_data_type)){
240
+ /* message forwarding (sends message to any target window) */
241
+ v_sendto = argv[argc-1];
242
+ argc -= 1;
243
+ }
244
+ if (NIL_P(argv[argc-1])) {
245
+ argc -= 1;
246
+ } else if (rb_obj_class(argv[argc-1])==rb_cClass &&
247
+ (rb_class_inherited_p(argv[argc-1], cRwAPIstruct)==Qtrue ||
248
+ rb_class_inherited_p(argv[argc-1], cRwCanvas)==Qtrue)){
249
+ /* lParam is CStruct or Canvas*/
250
+ v_klass = argv[argc-1];
251
+ argc -= 1;
252
+ }
253
+ if(argc > 3){ /* for WM_COMMAND / WM_NOTIFY (supports message which from Menu)*/
254
+ rb_scan_args(argc, argv, "41", &v_etc, &v_msg, &v_submsg, &v_handler, &v_template);
255
+ etc = NUM2INT(v_etc);
256
+ } else { /* for simple message forwarding*/
257
+ rb_scan_args(argc, argv, "21", &v_msg, &v_handler, &v_template);
258
+ v_submsg = Qnil;
259
+ etc = 0;
260
+ }
261
+
262
+ msg = NUM2UINT(v_msg);
263
+ if (!NIL_P(v_submsg)){
264
+ if(NIL_P(rwwin_msgtranslator_get(self, v_msg))){
265
+ rb_raise(rb_eRuntimeError, "Translator of message 0x%x is not defined", msg);
266
+ }
267
+ }
268
+ submsg = NIL_P(v_submsg) ? 0 : NUM2UINT(v_submsg);
269
+ handler_id = rb_to_id(v_handler);
270
+
271
+ if (!NIL_P(v_template)){ /* check template */
272
+ int len = RSTRING_LEN(v_template);
273
+ char* tmpl = RSTRING_PTR(v_template);
274
+ switch(tmpl[0]){
275
+ case 'h': case 'i': case 'x':
276
+ break;
277
+ case 'c':
278
+ if(msg!=WM_PAINT) rb_raise(rb_eRuntimeError, "Template 'c' is only for WM_PAINT");
279
+ if (NIL_P(v_klass)){
280
+ v_klass = cRwCanvas;
281
+ } else if(NIL_P(rb_class_inherited_p(cRwCanvas, v_klass))){
282
+ rb_raise(rb_eRuntimeError, "Need Canvas inherited class for template 'c'");
283
+ }
284
+ break;
285
+ case 's':
286
+ rb_raise(rb_eRuntimeError, "Template 's' is only for lParam");
287
+ default:
288
+ rb_raise(rb_eRuntimeError, "Unknown template `%c' for wParam", tmpl[0]);
289
+ }
290
+ if (len>1) switch(tmpl[1]){
291
+ case 'h': case 'i': case 'x':
292
+ break;
293
+ case 's':
294
+ if (NIL_P(v_klass) || NIL_P(rb_class_inherited_p(cRwAPIstruct, v_klass))){
295
+ rb_raise(rb_eRuntimeError, "Need CSruct inherited class for template 's'");
296
+ }
297
+ break;
298
+ default:
299
+ rb_raise(rb_eRuntimeError, "Unknown template `%c' for lParam", tmpl[1]);
300
+ }
301
+ }
302
+
303
+ newhandler = create_msghandler(handler_id, v_template, v_klass, v_sendto);
304
+ if (!etc){
305
+ if(rw->msgfilter) {
306
+ AAnode *node = aaSearch(rw->msgfilter, msg);
307
+ if (node){
308
+ basehandler = node->val;
309
+ if (basehandler->handler){
310
+ basehandler->handler = rw_append_handler(basehandler->handler, newhandler);
311
+ } else {
312
+ rw_msgreceiver_add(newhandler->receiver, newhandler->handler_id);
313
+ basehandler->handler = newhandler;
314
+ }
315
+ } else {
316
+ rw_msgreceiver_add(v_sendto, handler_id);
317
+ basehandler = create_basehandler(newhandler, NULL);
318
+ aaInsert(rw->msgfilter, msg, basehandler);
319
+ }
320
+ } else {
321
+ rw_msgreceiver_add(v_sendto, handler_id);
322
+ basehandler = create_basehandler(newhandler, NULL);
323
+ rw->msgfilter = newAAtree(aa_destruct_basehandler);
324
+ aaInsert(rw->msgfilter, msg, basehandler);
325
+ }
326
+ } else {
327
+ if(rw->msgfilter) {
328
+ AAnode *ndbase = aaSearch(rw->msgfilter, msg);
329
+ if (ndbase){
330
+ AAnode *ndsubfilter;
331
+ RwMsgHandler *subhandler;
332
+ subhandler = create_msghandler(handler_id, v_template, v_klass, v_sendto);
333
+ basehandler = ndbase->val;
334
+ ndsubfilter = aaSearch(basehandler->senders, etc);
335
+ if (ndsubfilter){
336
+ add_simple_filter(ndsubfilter->val, submsg, subhandler);
337
+ } else {
338
+ AAtree *subfilter = newAAtree(aa_destruct_handler);
339
+ rw_msgreceiver_add(v_sendto, handler_id);
340
+ aaInsert(basehandler->senders, etc, subfilter);
341
+ aaInsert(subfilter, submsg, subhandler);
342
+ }
343
+ } else {
344
+ rb_raise(rb_eRuntimeError, "Translator is not defined");
345
+ }
346
+ } else {
347
+ rb_raise(rb_eRuntimeError, "Translator is not defined");
348
+ }
349
+ }
350
+ return v_msg;
351
+ }
352
+
353
+ static AAtree*
354
+ delete_handler_ids(AAtree *tree, ID handler_id){
355
+ AAnode *nd = aaSearch(tree, handler_id);
356
+ if (nd) {
357
+ if(!nd->num) {
358
+ aaDelete(tree, handler_id);
359
+ } else {
360
+ nd->num--;
361
+ }
362
+ }
363
+ return tree;
364
+ }
365
+
366
+ static void*
367
+ delete_msghandler(RwWindow *rw, RwMsgHandler *handler, ID id, VALUE receiver){
368
+ RwMsgHandler *next;
369
+ RwMsgHandler *root = handler;
370
+ if(handler->handler_id == id){
371
+ if(rw->handler_ids) rw->handler_ids = delete_handler_ids(rw->handler_ids, id);
372
+ root = handler->next;
373
+ free_msghandler(handler);
374
+ } else {
375
+ while(next = handler->next){
376
+ if (next->handler_id == id && next->receiver==receiver){
377
+ rw->handler_ids = delete_handler_ids(rw->handler_ids, id);
378
+ handler->next = next->next;
379
+ free_msghandler(next);
380
+ break;
381
+ }
382
+ handler = handler->next;
383
+ }
384
+ }
385
+ return root;
386
+ }
387
+
388
+ /*
389
+ static void
390
+ aa_debug_callback(const AAnode *node, void *arg) {
391
+ fprintf(stderr, "%s key %d, val %d, lv %d\n", (char*)arg, node->key, (int)node->val, node->level);
392
+ }
393
+ */
394
+
395
+
396
+ static void
397
+ aa_delete_handler_id(const AAnode *nd, void *arg){
398
+ RwMsgHandler *handler = nd->val;
399
+ AAtree *tree = ((RwWindow*)arg)->handler_ids;// fprintf(stderr, "@439:tree=%x\n",tree);
400
+ if (!tree) return;
401
+ while(handler){
402
+ delete_handler_ids(tree, handler->handler_id);
403
+ handler = handler->next;
404
+ }
405
+ }
406
+
407
+ static void
408
+ aa_aa_delete_id_of_senders(const AAnode *nd, void *arg){
409
+ aaForeach(nd->val, aa_delete_handler_id, arg);
410
+ }
411
+
412
+ static VALUE
413
+ rwwin_msgfilter_delete(int argc, VALUE *argv, VALUE self){
414
+ VALUE v_sendto;
415
+ AAnode *node;
416
+ RwBaseHandler *bhandler;
417
+ RwWindow *rw = DATA_PTR(self);
418
+ if (!rw->msgfilter) return Qnil;
419
+ if (argc==1){ // Need to add a case when only one control was given.
420
+ int msg = NUM2INT(argv[0]);
421
+ if (node=aaSearch(rw->msgfilter, msg)){
422
+ RwBaseHandler *bhandler = node->val;
423
+ if(bhandler->handler){
424
+ RwMsgHandler *hd;
425
+ while(hd=bhandler->handler){
426
+ bhandler->handler = delete_msghandler(rw, bhandler->handler, hd->handler_id,
427
+ Qfalse);
428
+ rw->handler_ids = delete_handler_ids(rw->handler_ids, hd->handler_id);
429
+ }
430
+ }
431
+ if(bhandler->senders) aaForeach(bhandler->senders, aa_aa_delete_id_of_senders, rw);
432
+ aaDelete(rw->msgfilter, msg);
433
+ return Qtrue;
434
+ } else {
435
+ return Qnil;
436
+ }
437
+ }
438
+
439
+ if(argc > 1 && rb_typeddata_is_kind_of(argv[argc-1], &rwwin_data_type)){
440
+ v_sendto = Qnil;
441
+ argc--;
442
+ } else {
443
+ v_sendto = Qfalse;
444
+ }
445
+ if(argc==2){
446
+ if (TYPE(argv[1])==T_STRING){ /* msg, handler_name */
447
+ ID handler_id;
448
+ int msg = FIX2INT(argv[0]);
449
+ node = aaSearch(rw->msgfilter, msg);
450
+ if (!node || !(bhandler=node->val)) return Qnil;
451
+ if (!bhandler->handler) return Qnil;
452
+ handler_id = rb_to_id(argv[1]);
453
+ bhandler->handler = delete_msghandler(rw, bhandler->handler, handler_id, v_sendto);
454
+ if (!bhandler->handler && !bhandler->senders) aaDelete(rw->msgfilter, msg);
455
+ } else { /* idcmd, msg */
456
+ AAnode *nd;
457
+ int etc;
458
+ int msg = FIX2INT(argv[1]);
459
+ node = aaSearch(rw->msgfilter, msg);
460
+ if (!node) return Qnil;
461
+ bhandler = node->val;
462
+ etc = FIX2INT(argv[0]);
463
+ if(!bhandler->senders) return Qnil;
464
+ if(nd = aaSearch(bhandler->senders, etc)){
465
+ aaForeach(nd->val, aa_delete_handler_id, rw);
466
+ aaDelete(bhandler->senders, etc);
467
+ } else {
468
+ return Qfalse;
469
+ }
470
+ }
471
+ } else if(argc==3 || argc==4) { /* 3..4 */
472
+ AAnode *ndsubfilter;
473
+ AAnode *ndsubhandler;
474
+ int etc, submsg;
475
+ int msg = FIX2INT(argv[1]);
476
+ node = aaSearch(rw->msgfilter, msg);
477
+ if (!node) return Qnil;
478
+ bhandler = node->val;
479
+ if(!bhandler->senders){
480
+ rb_raise(rb_eArgError, "MsgTranslator of message:0x%x is not defined", msg);
481
+ }
482
+ etc = FIX2INT(argv[0]);
483
+ submsg = FIX2INT(argv[2]);
484
+ ndsubfilter = aaSearch(bhandler->senders, etc);
485
+ if(!ndsubfilter) return Qnil;
486
+ ndsubhandler = aaSearch(ndsubfilter->val, submsg);
487
+ if (!ndsubhandler || !ndsubhandler->val) return Qnil;
488
+ if(argc==3) {
489
+ aaForeach(ndsubfilter->val, aa_delete_handler_id, rw);
490
+ aaDelete(ndsubfilter->val, submsg);
491
+ } else { /* argc == 4 */
492
+ RwMsgHandler *subhandler = ndsubhandler->val;
493
+ ID sub_id = rb_to_id(argv[3]); //fprintf(stderr, "sub_id=%x\n", sub_id);
494
+ ndsubhandler->val = delete_msghandler(rw, subhandler, sub_id, v_sendto);
495
+ }
496
+ } else {
497
+ rb_raise(rb_eArgError, "argments must be 1..5");
498
+ }
499
+ return Qtrue;
500
+ }
501
+
502
+ static VALUE
503
+ search_msghandler(RwWindow *rw, RwMsgHandler *handler, ID id, VALUE receiver){
504
+ RwMsgHandler *next;
505
+ if(handler->handler_id == id) return Qtrue;
506
+ while(next = handler->next){
507
+ if (next->handler_id == id && next->receiver==receiver) return Qtrue;
508
+ handler = handler->next;
509
+ }
510
+ return Qfalse;
511
+ }
512
+
513
+ static VALUE
514
+ rwwin_msgfilter_exist_p(int argc, VALUE *argv, VALUE self){
515
+ int msg, etc;
516
+ VALUE v_sendto;
517
+ AAnode *node;
518
+ RwBaseHandler *bhandler;
519
+ RwWindow *rw = DATA_PTR(self);
520
+ if (!rw->msgfilter) return Qfalse;
521
+ if(argc > 1 && rb_typeddata_is_kind_of(argv[argc-1], &rwwin_data_type)){
522
+ v_sendto = Qfalse;
523
+ argc--;
524
+ } else {
525
+ v_sendto = Qfalse;
526
+ }
527
+ if (argc==1){
528
+ msg = FIX2INT(argv[0]);
529
+ return aaSearch(rw->msgfilter, msg) ? Qtrue : Qfalse;
530
+ }else if(argc==2){
531
+ if (TYPE(argv[1])==T_STRING){ /* msg, handler_name */
532
+ ID handler_id;
533
+ msg = FIX2INT(argv[0]);
534
+ node = aaSearch(rw->msgfilter, msg);
535
+ if (!node || !node->val) return Qfalse;
536
+ bhandler = node->val;
537
+ if (!bhandler->handler) return Qfalse;
538
+ handler_id = rb_to_id(argv[1]);
539
+ return search_msghandler(rw, bhandler->handler, handler_id, v_sendto);
540
+ } else { /* idcmd, msg */
541
+ msg = FIX2INT(argv[1]);
542
+ node = aaSearch(rw->msgfilter, msg);
543
+ if (!node) return Qfalse;
544
+ bhandler = node->val; //fprintf(stderr, "@%d\n", __LINE__);
545
+ if (!bhandler->senders) return Qfalse; // fprintf(stderr, "@%d, %xll\n", __LINE__, (ULONG_PTR)bhandler->senders);
546
+ etc = FIX2INT(argv[0]);
547
+ return aaSearch(bhandler->senders, etc) ? Qtrue : Qfalse;
548
+ }
549
+ } else if(argc==3 || argc==4) { /* 3..4 */
550
+ AAnode *ndsubfilter;
551
+ AAnode *ndsubhandler;
552
+ int submsg;
553
+
554
+ msg = FIX2INT(argv[1]);
555
+ node = aaSearch(rw->msgfilter, msg);
556
+ if (!node) return Qfalse;
557
+ bhandler = node->val;
558
+ if(!bhandler->handler||!bhandler->senders) return Qfalse;
559
+ etc = FIX2INT(argv[0]);
560
+ submsg = FIX2INT(argv[2]);
561
+ ndsubfilter = aaSearch(bhandler->senders, etc);
562
+ if(!ndsubfilter) return Qfalse;
563
+ ndsubhandler = aaSearch(ndsubfilter->val, submsg);
564
+ if (!ndsubhandler || !ndsubhandler->val) return Qfalse;
565
+ if(argc==3) {
566
+ return Qtrue;
567
+ } else { /* argc == 4 */
568
+ RwMsgHandler *subhandler = ndsubhandler->val;
569
+ ID sub_id = rb_to_id(argv[3]);
570
+ return search_msghandler(rw, subhandler, sub_id, v_sendto);
571
+ }
572
+ } else {
573
+ rb_raise(rb_eArgError, "argments must be 1..5");
574
+ }
575
+ return Qfalse;
576
+ }
577
+
578
+ void
579
+ aa_callback_each_msgfilter(const AAnode *node, void *arg){
580
+ VALUE ar = (VALUE)arg;
581
+ rb_ary_push(ar, INT2NUM(node->key));
582
+ }
583
+
584
+ static VALUE
585
+ rwwin_msgfilter_getfilters(VALUE self){
586
+ RwWindow *rw = DATA_PTR(self);
587
+ VALUE ary = rb_ary_new();
588
+ aaForeach(rw->msgfilter, aa_callback_each_msgfilter, (void*)ary);
589
+ return ary;
590
+ }
591
+
592
+ /* prototyping */
593
+ LRESULT CALLBACK RwSubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData);
594
+
595
+ static VALUE
596
+ rwwin_create(int argc,VALUE* argv, VALUE self){
597
+ TCHAR *classname, *caption;
598
+ RwWindow *rw = DATA_PTR(self);
599
+ HWND hparent = NULL;
600
+
601
+ if(TYPE(argv[0])==T_STRING) {
602
+ classname = rw_str2tchar(argv[0]);
603
+ } else{
604
+ rb_raise(rb_eArgError, "1st argument must be class name(String)");
605
+ }
606
+ if(TYPE(argv[1])==T_STRING) {
607
+ caption = rw_str2tchar(argv[1]);
608
+ } else{
609
+ rb_raise(rb_eArgError, "2nd argument must be caption(String)");
610
+ }
611
+ if (!NIL_P(argv[6])){
612
+ RwWindow *rwparent;
613
+ RwWindow_Data_Get_Struct(argv[6], rwparent);
614
+ hparent = rwparent->hwnd;
615
+ }
616
+ rw->hwnd = CreateWindowEx(NUM2UINT(argv[9]), /* dwExStyle */
617
+ classname,
618
+ caption,
619
+ NUM2UINT(argv[8]), /* dwStyle */
620
+ NUM2INT(argv[2]), /* x */
621
+ NUM2INT(argv[3]), /* y */
622
+ NUM2INT(argv[4]), /* w */
623
+ NUM2INT(argv[5]), /* h */
624
+ hparent, /* hParent */
625
+ NIL_P(argv[7]) ? 0 : (HMENU)NUM2ULONG_PTR(argv[7]), /* hMenu */
626
+ hInstance,
627
+ NULL);
628
+ if(!rw->hwnd){
629
+ rb_raise(rb_eRuntimeError, "failed to create window(%s)", RSTRING_PTR(argv[0]));
630
+ }
631
+ rw->nthread_id = GetCurrentThreadId();
632
+ if(hparent){
633
+ Register_childwin(rw->hwnd, self);
634
+ if(GetClassLong(rw->hwnd, GCW_ATOM)==RwClassAtom){
635
+ int id = NIL_P(argv[7]) ? 0 : FIX2INT(argv[7]);
636
+ SetWindowSubclass(rw->hwnd, RwSubclassProc, (UINT_PTR)id, (DWORD_PTR)self);
637
+ }
638
+ } else {
639
+ Register_win(rw->hwnd, self);
640
+ if (GetActiveWindow()==rw->hwnd) activewin = rw;
641
+ }
642
+ return self;
643
+ }
644
+
645
+ static VALUE
646
+ rwwin1_new_from_handle(VALUE klass, VALUE v_handle){
647
+ RwWindow *rw;
648
+ VALUE obj;
649
+ HANDLE handle = (HANDLE)NUM2ULONG_PTR(v_handle);
650
+ if(!GetParent(handle)) rb_raise(rb_eArgError,
651
+ "Handle %#x is not child window", (int)(ULONG_PTR)handle);
652
+
653
+ obj = RwWindow_Data_Make_Struct(klass, rw);
654
+ rw->hwnd = handle;
655
+ rw->msgfilter = NULL;
656
+ rw->handler_ids = NULL;
657
+ rw->haccel = NULL;
658
+ Register_childwin(rw->hwnd, obj);
659
+ return obj;
660
+ }
661
+
662
+ /* Event handling routines */
663
+ static VALUE
664
+ rw_method_missing(int argc, VALUE *argv, VALUE self){
665
+ ID method_id = rb_to_id(argv[0]);
666
+ RwWindow *rw = DATA_PTR(self);
667
+ if(rw->handler_ids && aaSearch(rw->handler_ids, method_id)) return Qnil;
668
+ rb_call_super(argc, argv);
669
+ return Qnil;
670
+ }
671
+
672
+ /* Keyborad accelarators */
673
+ static VALUE
674
+ rw_set_accelerator(VALUE self, VALUE v_acceltable){
675
+ int len, i;
676
+ HACCEL haccel = NULL;
677
+ ACCEL *paccel = NULL;
678
+ RwWindow *rw = DATA_PTR(self);
679
+ if (NIL_P(v_acceltable)){
680
+ if(rw->haccel) DestroyAcceleratorTable(rw->haccel);
681
+ rw->haccel = NULL;
682
+ return Qnil;
683
+ }
684
+ if(TYPE(v_acceltable)!=T_ARRAY) rb_raise(rb_eArgError, "Argument must be an Array.");
685
+ len = RARRAY_LEN(v_acceltable);
686
+ if(rw->haccel) DestroyAcceleratorTable(rw->haccel);
687
+ RW_MALLOC(paccel, len*sizeof(ACCEL));
688
+ for(i=0; i<len; i++){
689
+ VALUE v_accel = rb_ary_entry(v_acceltable, i);
690
+ paccel[i].fVirt = FIX2INT(rb_ary_entry(v_accel, 0));
691
+ paccel[i].key = FIX2INT(rb_ary_entry(v_accel, 1));
692
+ paccel[i].cmd = FIX2INT(rb_ary_entry(v_accel, 2));
693
+ }
694
+ haccel = CreateAcceleratorTable(paccel, len);
695
+ if(!haccel) rb_raise(rb_eRuntimeError, "CreateAcceleratorTable faled.");
696
+ rw->haccel = haccel;
697
+ free(paccel);
698
+ return INT2FIX(len);
699
+ }
700
+
701
+ /* Error handling routines */
702
+ void
703
+ rw_abort_program(int state){
704
+ VALUE bt, bt0, msg;
705
+ VALUE e = rb_errinfo();
706
+ char btbuff[4096] = "";
707
+ int i, len;
708
+
709
+ bt = rb_funcall(e, rb_intern("backtrace"), 0);
710
+ msg = rb_funcall(e, rb_intern("message"), 0);
711
+ bt0 = rb_ary_shift(bt);
712
+ len = RARRAY_LEN(bt);
713
+
714
+ for(i=0; i<len; i++){
715
+ VALUE btn = rb_ary_entry(bt, i);
716
+ char* btstr = StringValuePtr(btn);
717
+ strcat(btbuff, "from: ");
718
+ strcat(btbuff, btstr);
719
+ strcat(btbuff, "\n");
720
+ }
721
+
722
+ if(IS_GUIAPP){
723
+ char buff[4096];
724
+ sprintf(buff, "message: %s\n\nat: %s\n%s",
725
+ StringValuePtr(msg), StringValuePtr(bt0), btbuff);
726
+ MessageBoxA(NULL, buff, rb_obj_classname(e), 16);
727
+ PostQuitMessage(state);
728
+ } else {
729
+ fprintf(stderr, "Error occurred during message handling\n%s: %s (%s)\nfrom: %s",
730
+ StringValuePtr(bt0), StringValuePtr(msg), rb_obj_classname(e), btbuff);
731
+ PostQuitMessage(state);
732
+ }
733
+ }
734
+
735
+ static VALUE
736
+ rw_funcall_0(VALUE args){
737
+ VALUE *parg = (VALUE*)args;
738
+ return rb_funcall(parg[0], parg[1], 0);
739
+ }
740
+
741
+ static VALUE
742
+ rw_funcall_1(VALUE args){
743
+ VALUE *parg = (VALUE*)args;
744
+ return rb_funcall(parg[0], parg[1], 1, parg[2]);
745
+ }
746
+
747
+ static VALUE
748
+ rw_funcall_n(VALUE args){
749
+ VALUE *parg = (VALUE*)args;
750
+ return rb_funcall2(parg[0], parg[1], parg[2], &parg[3]);
751
+ }
752
+
753
+ void
754
+ dispatch_wm_paint_handler(VALUE wobj, RwBaseHandler *basehandler, HDC hdc){
755
+ RwMsgHandler *handler = basehandler->handler;
756
+ while(handler){
757
+ int state = 0;
758
+ VALUE args[3];
759
+ args[0] = handler->receiver;
760
+ args[1] = handler->handler_id;
761
+ if (handler->arg_template) {
762
+ VALUE v_cv = Qfalse;
763
+ switch(handler->arg_template[0]){
764
+ case 'i':
765
+ args[2] = ULONG_PTR2NUM((ULONG_PTR)hdc);
766
+ break;
767
+ case 'c':
768
+ v_cv = rwcvs_new_from_hdc(handler->klass, hdc);
769
+ args[2] = v_cv;
770
+ break;
771
+ default:
772
+ rb_bug("Unkown template: `%c' for WM_PAINT", handler->arg_template[0]);
773
+ }
774
+ rb_protect(rw_funcall_1, (VALUE)args, &state);
775
+ #if !USE_RGENGC
776
+ if(v_gr) rb_gc_force_recycle(v_gr);
777
+ #endif
778
+ } else {
779
+ rb_protect(rw_funcall_0, (VALUE)args, &state);
780
+ }
781
+ if (state) rw_abort_program(state);
782
+ handler = handler->next;
783
+ }
784
+ }
785
+
786
+ static int
787
+ setwparam2args(WPARAM wParam, char* template, VALUE* nargs, VALUE* args){
788
+ if(!*template) return 0;
789
+ switch(*template){
790
+ case 'h': /* arg is [(signed)LOWORD, (signed)HIWORD]*/
791
+ *nargs += 2;
792
+ args[0] = INT2FIX((short)LOWORD(wParam));
793
+ args[1] = INT2FIX((short)HIWORD(wParam));
794
+ return 2;
795
+ case 'i': /* arg is INT */
796
+ *nargs += 1;
797
+ *args = ULONG_PTR2NUM(wParam);
798
+ return 1;
799
+ case 'x': /* skip */
800
+ return 0;
801
+ default:
802
+ rb_bug("unknown template: `%c' for wParam", *template);
803
+ return 0;
804
+ }
805
+ }
806
+
807
+ static int
808
+ setlparam2args(LPARAM lParam, char* template, VALUE* nargs, VALUE* args){
809
+ if(!*template) return 0;
810
+ switch(*template){
811
+ case 'h': /* arg is [(signed)LOWORD, (signed)HIWORD]*/
812
+ *nargs += 2;
813
+ args[0] = INT2FIX((short)LOWORD(lParam));
814
+ args[1] = INT2FIX((short)HIWORD(lParam));
815
+ return 2;
816
+ case 'i': /* arg is INT */
817
+ *nargs += 1;
818
+ *args = LONG_PTR2NUM(lParam);
819
+ return 1;
820
+ case 's': /* arg is CStruct */
821
+ *nargs += 1;
822
+ return -1;
823
+ case 'x': /* skip */
824
+ return 0;
825
+ default:
826
+ rb_bug("unknown template: `%c' for lParam", *template);
827
+ return 0;
828
+ }
829
+ }
830
+
831
+ static RwMsgHandler*
832
+ rw_translate_msg(VALUE callto, RwBaseHandler *basehandler, UINT msg, WPARAM *wParam, LPARAM *lParam){
833
+ VALUE retval = Qnil;
834
+ VALUE args[4];
835
+ RwMsgHandler *handler = basehandler->handler;
836
+ if(basehandler->senders){
837
+ int state;
838
+ unsigned idfrom, subfilter;
839
+ AAnode *node, *subnode;
840
+ RwMsgHandler *subhandler = NULL;
841
+ ID callback_id = handler->handler_id;
842
+ if (!callback_id){
843
+ switch(msg){
844
+ case WM_COMMAND:
845
+ case WM_TIMER:
846
+ idfrom = LOWORD(*wParam);
847
+ if(*lParam){ /* from controls */
848
+ subfilter = HIWORD(*wParam);
849
+ } else { /* from menu */
850
+ subfilter = HIWORD(*wParam) & 0xfffe; /* mask LSB */
851
+ }
852
+ node = aaSearch(basehandler->senders, idfrom);
853
+ if(node){
854
+ subnode = aaSearch((AAtree*)(node->val), subfilter);
855
+ if (subnode) subhandler = subnode->val;
856
+ }
857
+ return subhandler;
858
+ case WM_NOTIFY:
859
+ idfrom = ((NMHDR*)*lParam)->idFrom;
860
+ subfilter = ((NMHDR*)*lParam)->code;
861
+ node = aaSearch(basehandler->senders, idfrom);
862
+ if(node){
863
+ subnode = aaSearch((AAtree*)(node->val), subfilter);
864
+ if (subnode) subhandler = subnode->val;
865
+ }
866
+ return subhandler;
867
+ }
868
+ } else {
869
+ char *template = handler->arg_template;
870
+ args[0] = callto;
871
+ args[1] = callback_id;
872
+ args[2] = 0;
873
+ if (template){
874
+ int n = setwparam2args(*wParam, template, &args[2], &args[3]);
875
+ n = setlparam2args(*lParam, ++template, &args[2], &args[3+n]);
876
+ }
877
+ retval = rb_protect(rw_funcall_n, (VALUE)args, &state);
878
+ if (state) rw_abort_program(state);
879
+ if (TYPE(retval) == T_ARRAY){
880
+ VALUE v_idfrom, v_subfilter, v_wParam, v_lParam;
881
+ if (NIL_P(v_idfrom = rb_ary_entry(retval, 0))) return NULL;
882
+ idfrom = FIX2INT(v_idfrom);
883
+ if (NIL_P(v_subfilter = rb_ary_entry(retval, 1))) return NULL;
884
+ subfilter = FIX2INT(v_subfilter);
885
+ if (! NIL_P(v_wParam = rb_ary_entry(retval, 2))) *wParam = NUM2INT(v_wParam);
886
+ if (! NIL_P(v_lParam = rb_ary_entry(retval, 3))) *lParam = NUM2INT(v_lParam);
887
+ node = aaSearch(basehandler->senders, idfrom);
888
+ if(node){
889
+ subnode = aaSearch((AAtree*)(node->val), subfilter);
890
+ if (subnode) subhandler = subnode->val;
891
+ }
892
+ }
893
+ }
894
+ return subhandler;
895
+ }
896
+ return handler;
897
+ }
898
+
899
+ static int
900
+ dispatch_handler(VALUE wobj, RwBaseHandler *basehandler, UINT msg, WPARAM wParam, LPARAM lParam){
901
+ VALUE ret = Qnil;
902
+ RwMsgHandler *handler = rw_translate_msg(wobj, basehandler, msg, &wParam, &lParam);
903
+ while (handler){
904
+ int n = 0;
905
+ int is_struct = 0;
906
+ int state = 0;
907
+ VALUE args[8];
908
+ char *template = handler->arg_template;
909
+ args[0] = handler->receiver;
910
+ args[1] = handler->handler_id;
911
+ args[2] = 0;
912
+ if (template){
913
+ n = setwparam2args(wParam, template, &args[2], &args[3]);
914
+ is_struct = setlparam2args(lParam, ++template, &args[2], &args[3+n]);
915
+ }
916
+ if (is_struct==-1){ /* lParam to CStruct */
917
+ VALUE obj;
918
+ if (handler->klass==Qnil) rb_raise(rb_eRuntimeError, "No CStruct given");
919
+ obj = cstruct_wrapptr(handler->klass, (char*)lParam, 0);
920
+ args[3+n] = obj;
921
+ ret = rb_protect(rw_funcall_n, (VALUE)args, &state);
922
+ #if !USE_RGENGC
923
+ rb_gc_force_recycle(obj);
924
+ #endif
925
+ } else {
926
+ ret = rb_protect(rw_funcall_n, (VALUE)args, &state);
927
+ }
928
+ if (state) rw_abort_program(state);
929
+ if (ret == cRwCancelDefWndProc){
930
+ return 1;
931
+ } else if (rb_typeddata_is_kind_of(ret, &rw_candefwndprc_d_type)){
932
+ RwCancelDefWindowProc *rcp;
933
+ TypedData_Get_Struct(ret, RwCancelDefWindowProc, &rw_candefwndprc_d_type, rcp);
934
+ if (rcp->retval){
935
+ return rcp->retval;
936
+ }
937
+ }
938
+ handler = handler->next;
939
+ }
940
+ return 0;
941
+ }
942
+
943
+ LRESULT
944
+ do_wm_default(VALUE wobj, UINT *msg, WPARAM *wParam, LPARAM *lParam){
945
+ RwWindow *rw = DATA_PTR(wobj);
946
+ LRESULT r = 0;
947
+ if(rw->msgfilter){
948
+ AAnode *node = aaSearch(rw->msgfilter, *msg);
949
+ if (node){
950
+ RwBaseHandler *basehandler = node->val;
951
+ if(basehandler){
952
+ r = dispatch_handler(wobj, basehandler, *msg, *wParam, *lParam);
953
+ }
954
+ }
955
+ }
956
+ return r;
957
+ }
958
+
959
+ //void
960
+ //aa_callback_test(const AAnode *node, void *arg){
961
+ // fprintf(stderr, "[key=%#x, val=%#x], ", (int)node->key, (int)node->val);
962
+ //}
963
+
964
+ static void
965
+ aa_callback_finalize_resoure(const AAnode *node, void *arg){
966
+ VALUE obj = (VALUE)node->val;
967
+ if(rb_typeddata_is_kind_of(obj, &rwimage_data_type)){
968
+ RwImage *rp;
969
+ RwImage_Data_Get_Struct(obj, rp);
970
+ if(rp->himage) GdipDisposeImage(rp->himage);
971
+ rp->himage = 0;
972
+ }
973
+ }
974
+
975
+ static void
976
+ rwwin_finalize(){
977
+ aaForeach(rsclist, aa_callback_finalize_resoure, NULL);
978
+ rwgdiplus_shutdown();
979
+ // PostQuitMessage(0);
980
+ }
981
+
982
+
983
+ LRESULT CALLBACK
984
+ RwWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){
985
+ if(GetClassLong(hWnd, GCW_ATOM)==RwClassAtom){
986
+ VALUE wobj = Get_win(hWnd);
987
+ if(wobj){
988
+ RwWindow *rw = DATA_PTR(wobj);
989
+ if (uMsg==WM_PAINT){
990
+ if (rw->msgfilter) {
991
+ AAnode *nd = aaSearch(rw->msgfilter, WM_PAINT);
992
+ if (nd) {
993
+ PAINTSTRUCT ps;
994
+ RwBaseHandler *basehandler = nd->val;
995
+ HDC hdc = BeginPaint(rw->hwnd, &ps);
996
+ dispatch_wm_paint_handler(wobj, basehandler, hdc);
997
+ EndPaint(rw->hwnd, &ps);
998
+ return 0;
999
+ }
1000
+ }
1001
+ return DefWindowProc(hWnd, uMsg, wParam, lParam);
1002
+ } else {
1003
+ LRESULT ret;
1004
+ if (uMsg==WM_ACTIVATE) activewin = LOWORD(wParam) ? DATA_PTR(wobj) : NULL;
1005
+ ret=do_wm_default(wobj, &uMsg, &wParam, &lParam);
1006
+ if (ret){
1007
+ return ret;
1008
+ }
1009
+ }
1010
+ }
1011
+ switch (uMsg) {
1012
+ case WM_CREATE:
1013
+ return 0;
1014
+ case WM_CLOSE:
1015
+ DestroyWindow(hWnd);
1016
+ break;
1017
+ case WM_DESTROY:
1018
+ if(wobj){
1019
+ RwWindow *rw = (RwWindow*)DATA_PTR(wobj);
1020
+ if(!GetParent(hWnd)) {
1021
+ Unregister_win(hWnd);
1022
+ if(aaCount(winlist)==0) {
1023
+ rwwin_finalize();
1024
+ PostQuitMessage(wParam);
1025
+ return 0;
1026
+ }
1027
+ } else {
1028
+ Unregister_childwin(hWnd);
1029
+ }
1030
+ rw->hwnd = NULL;
1031
+ }
1032
+ return 0;
1033
+ }
1034
+ }
1035
+ return DefWindowProc(hWnd, uMsg, wParam, lParam);
1036
+ }
1037
+
1038
+ LRESULT CALLBACK RwSubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData){
1039
+ VALUE wobj = (VALUE)dwRefData;
1040
+ RwWindow *rw = (RwWindow*)DATA_PTR(wobj);
1041
+ if (uMsg==WM_PAINT){
1042
+ if (rw->msgfilter) {
1043
+ AAnode *nd = aaSearch(rw->msgfilter, WM_PAINT);
1044
+ if (nd) {
1045
+ PAINTSTRUCT ps;
1046
+ RwBaseHandler *basehandler = nd->val;
1047
+ HDC hdc = BeginPaint(rw->hwnd, &ps);
1048
+ dispatch_wm_paint_handler(wobj, basehandler, hdc);
1049
+ EndPaint(rw->hwnd, &ps);
1050
+ return 0;
1051
+ }
1052
+ }
1053
+ } else {
1054
+ LONG_PTR ret = do_wm_default(wobj, &uMsg, &wParam, &lParam);
1055
+ if (ret) return ret; /* cancel default wndproc */
1056
+ if(uMsg==WM_DESTROY){
1057
+ Unregister_childwin(hWnd);
1058
+ rw->hwnd = NULL;
1059
+ }
1060
+ }
1061
+ return DefSubclassProc(hWnd, uMsg, wParam, lParam);
1062
+ }
1063
+
1064
+ static VALUE
1065
+ rwwin_close(VALUE self){
1066
+ int r; //AAnode *nd;
1067
+ RwWindow *rw = DATA_PTR(self);
1068
+ RwCheckWindow(rw);
1069
+ r = DestroyWindow(rw->hwnd);
1070
+ if(rw->hwnd){ /* for child windows (Not received WM_DESTROY) */
1071
+ Unregister_childwin(rw->hwnd);
1072
+ rw->hwnd = NULL;
1073
+ }
1074
+ return r ? Qtrue : Qfalse;
1075
+ }
1076
+
1077
+ static VALUE
1078
+ rwwin_gethandle(VALUE self){
1079
+ RwWindow *rw = DATA_PTR(self);
1080
+ RwCheckWindow(rw);
1081
+ return ULONG_PTR2NUM((ULONG_PTR)rw->hwnd);
1082
+ }
1083
+
1084
+ static VALUE
1085
+ rwwin_alive_p(VALUE self){
1086
+ RwWindow *rw = DATA_PTR(self);
1087
+ return rw->hwnd ? Qtrue : Qfalse;
1088
+ }
1089
+
1090
+ /*
1091
+ static void
1092
+ rw_move_core(HWND hwnd, POINT *pt){
1093
+ HWND hparent;
1094
+ if(hparent=GetParent(hwnd)) ClientToScreen(hparent, pt);
1095
+ }*/
1096
+
1097
+ static VALUE
1098
+ rwwin_move(int argc, VALUE * argv, VALUE self){
1099
+ RECT rc;
1100
+ int x, y, w, h;
1101
+ BOOL brepaint = TRUE;
1102
+ RwWindow *rw = DATA_PTR(self);
1103
+ RwCheckWindow(rw);
1104
+ switch(argc){
1105
+ case 5:
1106
+ if(argv[4]==Qfalse) brepaint = FALSE;
1107
+ case 4:
1108
+ x = FIX2INT(argv[0]);
1109
+ y = FIX2INT(argv[1]);
1110
+ w = FIX2INT(argv[2]);
1111
+ h = FIX2INT(argv[3]);
1112
+ break;
1113
+ case 3:
1114
+ if(argv[2]==Qfalse) brepaint = FALSE;
1115
+ case 2:
1116
+ x = FIX2INT(argv[0]);
1117
+ y = FIX2INT(argv[1]);
1118
+ GetWindowRect(rw->hwnd, &rc);
1119
+ w = rc.right - rc.left;
1120
+ h = rc.bottom - rc.top;
1121
+ break;
1122
+ default:
1123
+ rb_raise(rb_eArgError, "Num of arguments must be 2..5");
1124
+ }
1125
+ rw_call_without_gvl_6(rw->nthread_id, (FARPROC)MoveWindow, (ULONG_PTR)rw->hwnd, x, y, w, h, brepaint);
1126
+ return self;
1127
+ }
1128
+
1129
+ static VALUE
1130
+ rwwin_resize(VALUE self, VALUE v_w, VALUE v_h){
1131
+ RECT rc;
1132
+ POINT pos;
1133
+ RwWindow *rw = DATA_PTR(self);
1134
+ RwCheckWindow(rw);
1135
+ GetWindowRect(rw->hwnd, &rc);
1136
+ pos.x = rc.left;
1137
+ pos.y = rc.top;
1138
+ ScreenToClient(GetAncestor(rw->hwnd, GA_PARENT), &pos);
1139
+ rw_call_without_gvl_6(rw->nthread_id, (FARPROC)MoveWindow, (ULONG_PTR)rw->hwnd,
1140
+ pos.x, pos.y, FIX2INT(v_w), FIX2INT(v_h), TRUE);
1141
+ return self;
1142
+ }
1143
+
1144
+ static VALUE
1145
+ rwwin_refresh(int argc, VALUE *argv, VALUE self){
1146
+ RECT rect;
1147
+ RECT *prect;
1148
+ BOOL bErase;
1149
+ RwWindow *rw = DATA_PTR(self);
1150
+ RwCheckWindow(rw);
1151
+ if(argc<=1){
1152
+ prect = NULL;
1153
+ bErase = (argc==1 && argv[0]==Qfalse) ? FALSE : TRUE;
1154
+ } else if(argc<=5){
1155
+ rect.left = FIX2INT(argv[0]);
1156
+ rect.top = FIX2INT(argv[1]);
1157
+ rect.right = rect.left + FIX2INT(argv[2]);
1158
+ rect.bottom = rect.top + FIX2INT(argv[3]);
1159
+ prect = &rect;
1160
+ bErase = (argc==5 && argv[4]==Qfalse) ? FALSE : TRUE;
1161
+ } else{
1162
+ rb_raise(rb_eArgError, "invalid num of args: %d", argc);
1163
+ }
1164
+ InvalidateRect(rw->hwnd, prect, bErase);
1165
+ return self;
1166
+ }
1167
+
1168
+ static void
1169
+ rw_getclientpos_core(HWND hwnd, RECT *rc){
1170
+ HWND hparent;
1171
+ GetWindowRect(hwnd, rc);
1172
+ if(hparent=GetAncestor(hwnd, GA_PARENT)) ScreenToClient(hparent, (POINT*)rc);
1173
+ }
1174
+
1175
+ static VALUE
1176
+ rwwin_getscreenpos(VALUE self){
1177
+ RECT rc;
1178
+ RwWindow *rw = DATA_PTR(self);
1179
+ RwCheckWindow(rw);
1180
+ GetWindowRect(rw->hwnd, &rc);
1181
+ return rb_ary_new3(2, INT2FIX(rc.left), INT2FIX(rc.top));
1182
+ }
1183
+
1184
+ static VALUE
1185
+ rwwin_getclientpos(VALUE self){
1186
+ RECT rc;
1187
+ RwWindow *rw = DATA_PTR(self);
1188
+ RwCheckWindow(rw);
1189
+ rw_getclientpos_core(rw->hwnd, &rc);
1190
+ return rb_ary_new3(2, INT2FIX(rc.left), INT2FIX(rc.top));
1191
+ }
1192
+
1193
+ static VALUE
1194
+ rwwin_getwndsize(VALUE self){
1195
+ RECT rc;
1196
+ RwWindow *rw = DATA_PTR(self);
1197
+ RwCheckWindow(rw);
1198
+ GetWindowRect(rw->hwnd, &rc);
1199
+ return rb_ary_new3(2, INT2FIX(rc.right - rc.left), INT2FIX(rc.bottom - rc.top));
1200
+ }
1201
+
1202
+ static VALUE
1203
+ rwwin_getclientsize(VALUE self){
1204
+ RECT rc;
1205
+ RwWindow *rw = DATA_PTR(self);
1206
+ RwCheckWindow(rw);
1207
+ GetClientRect(rw->hwnd, &rc);
1208
+ return rb_ary_new3(2, INT2FIX(rc.right), INT2FIX(rc.bottom));
1209
+ }
1210
+
1211
+ static VALUE
1212
+ rwwin_setorder(VALUE self, VALUE v_wndafter){
1213
+ RwWindow *rwafter;
1214
+ HWND hwndafter;
1215
+ RwWindow *rw = DATA_PTR(self);
1216
+ RwCheckWindow(rw);
1217
+ switch(TYPE(v_wndafter)){
1218
+ case T_FIXNUM:
1219
+ case T_BIGNUM:
1220
+ hwndafter = (HWND)NUM2ULONG_PTR(v_wndafter);
1221
+ break;
1222
+ default:
1223
+ RwWindow_Data_Get_Struct(v_wndafter, rwafter);
1224
+ hwndafter = rwafter->hwnd;
1225
+ }
1226
+ SetWindowPos(rw->hwnd, hwndafter, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
1227
+ return self;
1228
+ }
1229
+
1230
+ static VALUE
1231
+ rwwin_getcursorpos(VALUE self){
1232
+ VALUE robj;
1233
+ POINT pt;
1234
+ RwWindow *rw = DATA_PTR(self);
1235
+ GetCursorPos(&pt);
1236
+ ScreenToClient(rw->hwnd, &pt);
1237
+ robj = rb_ary_new2(2);
1238
+ rb_ary_store(robj, 0, INT2NUM(pt.x));
1239
+ rb_ary_store(robj, 1, INT2NUM(pt.y));
1240
+ return robj;
1241
+ }
1242
+
1243
+ /* r/w attributes */
1244
+ static VALUE
1245
+ rwwin_getcaption(VALUE self){
1246
+ int len;
1247
+ TCHAR *buff;
1248
+ VALUE robj;
1249
+ RwWindow *rw = DATA_PTR(self);
1250
+ RwCheckWindow(rw);
1251
+ len = GetWindowTextLength(rw->hwnd);
1252
+ buff = malloc((len+1)*sizeof(TCHAR));
1253
+ GetWindowText(rw->hwnd, buff, len+1);
1254
+ robj = rw_encode_external(buff);
1255
+ free(buff);
1256
+ return robj;
1257
+ }
1258
+
1259
+ static VALUE
1260
+ rwwin_setcaption(VALUE self, VALUE str){
1261
+ RwWindow *rw = DATA_PTR(self);
1262
+ RwCheckWindow(rw);
1263
+ rw_call_without_gvl_2(rw->nthread_id, (FARPROC)SetWindowText, (ULONG_PTR)rw->hwnd,
1264
+ (ULONG_PTR)rw_str2tchar(StringValue(str)));
1265
+ return self;
1266
+ }
1267
+
1268
+ static VALUE
1269
+ rwwin_getvisible(VALUE self){
1270
+ int r;
1271
+ RwWindow *rw = DATA_PTR(self);
1272
+ RwCheckWindow(rw);
1273
+ r = rw_call_without_gvl_1(rw->nthread_id, (FARPROC)IsWindowVisible, (ULONG_PTR)rw->hwnd);
1274
+ return r ? Qtrue : Qnil;
1275
+ }
1276
+
1277
+ static VALUE
1278
+ rwwin_setvisible(VALUE self, VALUE v_flag){
1279
+ int swvisible;
1280
+ RwWindow *rw = DATA_PTR(self);
1281
+ RwCheckWindow(rw);
1282
+ switch(TYPE(v_flag)){
1283
+ case T_TRUE:
1284
+ swvisible = SW_SHOW;
1285
+ break;
1286
+ case T_FALSE:
1287
+ swvisible = SW_HIDE;
1288
+ break;
1289
+ case T_FIXNUM:
1290
+ case T_BIGNUM:
1291
+ swvisible = FIX2INT(v_flag);
1292
+ break;
1293
+ default:
1294
+ rb_raise(rb_eTypeError, "Argument must be true or false or Integer");
1295
+ }
1296
+ rw_call_without_gvl_2(rw->nthread_id, (FARPROC)ShowWindow, (ULONG_PTR)rw->hwnd, swvisible);
1297
+ return self;
1298
+ }
1299
+
1300
+ static VALUE
1301
+ rwwin_getidcmd(VALUE self){
1302
+ RwWindow *rw = DATA_PTR(self);
1303
+ RwCheckWindow(rw);
1304
+ return INT2FIX(GetWindowLongPtr(rw->hwnd, GWLP_ID));
1305
+ }
1306
+
1307
+ static VALUE
1308
+ rwwin_setidcmd(VALUE self, VALUE v_id){
1309
+ RwWindow *rw = DATA_PTR(self);
1310
+ RwCheckWindow(rw);
1311
+ SetWindowLongPtr(rw->hwnd, GWLP_ID, FIX2INT(v_id));
1312
+ return self;
1313
+ }
1314
+
1315
+ static VALUE
1316
+ rwwin_getparent(VALUE self){
1317
+ HWND hparent;
1318
+ RwWindow *rw = DATA_PTR(self);
1319
+ RwCheckWindow(rw);
1320
+ if(hparent = GetParent(rw->hwnd)){
1321
+ VALUE pw;
1322
+ if(!(pw = Get_win(hparent))) pw = Get_childwin(hparent);
1323
+ return pw ? pw : Qnil;
1324
+ }
1325
+ return Qnil;
1326
+ }
1327
+
1328
+ static VALUE
1329
+ rwwin_setparent(VALUE self, VALUE v_parent){
1330
+ HWND h_old;
1331
+ RwWindow *rp;
1332
+ RwWindow *rw = DATA_PTR(self);
1333
+ RwCheckWindow(rw);
1334
+ RwWindow_Data_Get_Struct(v_parent, rp);
1335
+ RwCheckWindow(rp);
1336
+ h_old = SetParent(rw->hwnd, rp->hwnd);
1337
+ if(h_old){
1338
+ VALUE pw;
1339
+ if(!(pw = Get_win(h_old))) pw = Get_childwin(h_old);
1340
+ return pw ? pw : Qnil;
1341
+ }else{
1342
+ return Qnil;
1343
+ }
1344
+ }
1345
+
1346
+ static VALUE
1347
+ rwwin_getx(VALUE self){
1348
+ RECT rc;
1349
+ RwWindow *rw = DATA_PTR(self);
1350
+ RwCheckWindow(rw);
1351
+ rw_getclientpos_core(rw->hwnd, &rc);
1352
+ return INT2FIX(rc.left);
1353
+ }
1354
+
1355
+ static VALUE
1356
+ rwwin_gety(VALUE self){
1357
+ RECT rc;
1358
+ RwWindow *rw = DATA_PTR(self);
1359
+ RwCheckWindow(rw);
1360
+ rw_getclientpos_core(rw->hwnd, &rc);
1361
+ return INT2FIX(rc.top);
1362
+ }
1363
+
1364
+ static VALUE
1365
+ rwwin_getw(VALUE self){
1366
+ RECT rc;
1367
+ RwWindow *rw = DATA_PTR(self);
1368
+ RwCheckWindow(rw);
1369
+ GetWindowRect(rw->hwnd, &rc);
1370
+ return INT2FIX(rc.right - rc.left);
1371
+ }
1372
+
1373
+ static VALUE
1374
+ rwwin_geth(VALUE self){
1375
+ RECT rc;
1376
+ RwWindow *rw = DATA_PTR(self);
1377
+ RwCheckWindow(rw);
1378
+ GetWindowRect(rw->hwnd, &rc);
1379
+ return INT2FIX(rc.bottom - rc.top);
1380
+ }
1381
+
1382
+ static void
1383
+ rw_setxy_core(HWND hwnd, POINT *pt, int *w, int *h){
1384
+ RECT rc;
1385
+ GetWindowRect(hwnd, &rc);
1386
+ *w = rc.right - rc.left;
1387
+ *h = rc.bottom - rc.top;
1388
+ pt->x = rc.left;
1389
+ pt->y = rc.top;
1390
+ ScreenToClient(GetAncestor(hwnd, GA_PARENT), pt);
1391
+ }
1392
+
1393
+ static VALUE
1394
+ rwwin_setx(VALUE self, VALUE v_x){
1395
+ int w, h;
1396
+ POINT pt;
1397
+ RwWindow *rw = DATA_PTR(self);
1398
+ RwCheckWindow(rw);
1399
+ rw_setxy_core(rw->hwnd, &pt, &w, &h);
1400
+ rw_call_without_gvl_6(rw->nthread_id, (FARPROC)MoveWindow, (ULONG_PTR)rw->hwnd,
1401
+ FIX2INT(v_x), pt.y, w, h, FALSE);
1402
+ return v_x;
1403
+ }
1404
+
1405
+ static VALUE
1406
+ rwwin_sety(VALUE self, VALUE v_y){
1407
+ int w, h;
1408
+ POINT pt;
1409
+ RwWindow *rw = DATA_PTR(self);
1410
+ RwCheckWindow(rw);
1411
+ rw_setxy_core(rw->hwnd, &pt, &w, &h);
1412
+ rw_call_without_gvl_6(rw->nthread_id, (FARPROC)MoveWindow, (ULONG_PTR)rw->hwnd,
1413
+ pt.x, FIX2INT(v_y), w, h, FALSE);
1414
+ return v_y;
1415
+ }
1416
+
1417
+ static VALUE
1418
+ rwwin_setw(VALUE self, VALUE v_w){
1419
+ int w, h;
1420
+ POINT pt;
1421
+ RwWindow *rw = DATA_PTR(self);
1422
+ RwCheckWindow(rw);
1423
+ rw_setxy_core(rw->hwnd, &pt, &w, &h);
1424
+ rw_call_without_gvl_6(rw->nthread_id, (FARPROC)MoveWindow, (ULONG_PTR)rw->hwnd,
1425
+ pt.x, pt.y, FIX2INT(v_w), h, FALSE);
1426
+ return v_w;
1427
+ }
1428
+
1429
+ static VALUE
1430
+ rwwin_seth(VALUE self, VALUE v_h){
1431
+ int w, h;
1432
+ POINT pt;
1433
+ RwWindow *rw = DATA_PTR(self);
1434
+ RwCheckWindow(rw);
1435
+ rw_setxy_core(rw->hwnd, &pt, &w, &h);
1436
+ rw_call_without_gvl_6(rw->nthread_id, (FARPROC)MoveWindow, (ULONG_PTR)rw->hwnd,
1437
+ pt.x, pt.y, w, FIX2INT(v_h), FALSE);
1438
+ return v_h;
1439
+ }
1440
+
1441
+ static VALUE
1442
+ rwwin_setsubclass(VALUE self){
1443
+ int id;
1444
+ RwWindow *rw = DATA_PTR(self);
1445
+ RwCheckWindow(rw);
1446
+ id = GetWindowLongPtr(rw->hwnd, GWLP_ID);
1447
+ SetWindowSubclass(rw->hwnd, RwSubclassProc, (UINT_PTR)id, (DWORD_PTR)self);
1448
+ return self;
1449
+ }
1450
+
1451
+ static VALUE
1452
+ rwwin_removesubclass(VALUE self){
1453
+ int id;
1454
+ RwWindow *rw = DATA_PTR(self);
1455
+ RwCheckWindow(rw);
1456
+ id = GetWindowLongPtr(rw->hwnd, GWLP_ID);
1457
+ RemoveWindowSubclass(rw->hwnd, RwSubclassProc, (UINT_PTR)id);
1458
+ return self;
1459
+ }
1460
+
1461
+ static ULONG_PTR
1462
+ rw_get_param(VALUE v_param){
1463
+ switch(TYPE(v_param)) {
1464
+ case T_FIXNUM:
1465
+ case T_BIGNUM:
1466
+ return NUM2ULONG_PTR(v_param);
1467
+ case T_DATA:
1468
+ if (rb_typeddata_is_kind_of(v_param, &cstruct_data_type)){
1469
+ CStructData *cs;
1470
+ CStruct_Data_Get_Struct(v_param, cs);
1471
+ return (ULONG_PTR)cs->dtstr + cs->dtoffset;
1472
+ }
1473
+ case T_STRING:
1474
+ if(rb_enc_get_index(v_param)) {
1475
+ return (ULONG_PTR)rw_str2tchar(v_param);
1476
+ } else {
1477
+ return (ULONG_PTR)RSTRING_PTR(v_param);
1478
+ }
1479
+ default:
1480
+ rb_raise(rb_eTypeError, "Invalid type:%s", rb_class2name(rb_class_of(v_param)));
1481
+ }
1482
+ }
1483
+
1484
+ static VALUE
1485
+ rwwin_setfocus(VALUE self){
1486
+ RwWindow *rw = DATA_PTR(self);
1487
+ RwCheckWindow(rw);
1488
+ return SetFocus(rw->hwnd) ? self : Qnil;
1489
+ }
1490
+
1491
+ static VALUE
1492
+ rwwin_setredraw(int argc, VALUE *argv, VALUE self){
1493
+ VALUE v_flag ;//, v_l, v_t, v_r, v_b;
1494
+ int flag;
1495
+ RECT rc;
1496
+ RECT *prc = NULL;
1497
+ RwWindow *rw = DATA_PTR(self);
1498
+ switch(argc){
1499
+ case 0:
1500
+ flag = RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN;
1501
+ break;
1502
+ case 1:
1503
+ v_flag = argv[0];
1504
+ if (!v_flag) {
1505
+ flag = FALSE;
1506
+ } else {
1507
+ flag = (v_flag==Qtrue) ? RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN :\
1508
+ FIX2INT(v_flag);
1509
+ }
1510
+ break;
1511
+ case 4:
1512
+ rc.left = FIX2INT(argv[0]);
1513
+ rc.top = FIX2INT(argv[1]);
1514
+ rc.right = FIX2INT(argv[2]);
1515
+ rc.bottom = FIX2INT(argv[3]);
1516
+ prc = &rc;
1517
+ flag = RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN;
1518
+ break;
1519
+ case 5:
1520
+ rc.left = FIX2INT(argv[0]);
1521
+ rc.top = FIX2INT(argv[1]);
1522
+ rc.right = FIX2INT(argv[2]);
1523
+ rc.bottom = FIX2INT(argv[3]);
1524
+ prc = &rc;
1525
+ flag = (argv[4]==Qtrue) ? RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN :\
1526
+ FIX2INT(argv[4]);
1527
+ break;
1528
+ default:
1529
+ rb_raise(rb_eArgError, "Num of arguments must be 0, 1, 4 or 5");
1530
+ }
1531
+ SendMessage(rw->hwnd, WM_SETREDRAW, flag, 0);
1532
+ if(flag) RedrawWindow(rw->hwnd, prc, NULL, flag);
1533
+ return self;
1534
+ }
1535
+
1536
+
1537
+
1538
+
1539
+ static VALUE
1540
+ rwwin_sendmessage(VALUE self, VALUE v_msg, VALUE v_wparam, VALUE v_lparam){
1541
+ int r;
1542
+ RwWindow *rw = DATA_PTR(self);
1543
+ RwCheckWindow(rw);
1544
+ r = rw_call_without_gvl_4(rw->nthread_id, (FARPROC)SendMessage, (ULONG_PTR)rw->hwnd,
1545
+ NUM2UINT(v_msg), rw_get_param(v_wparam), rw_get_param(v_lparam));
1546
+ return INT2NUM(r);
1547
+ }
1548
+
1549
+ static VALUE
1550
+ rwwin_postmessage(VALUE self, VALUE v_msg, VALUE v_wparam, VALUE v_lparam){
1551
+ int r;
1552
+ RwWindow *rw = DATA_PTR(self);
1553
+ RwCheckWindow(rw);
1554
+ r = rw_call_without_gvl_4(rw->nthread_id, (FARPROC)PostMessage, (ULONG_PTR)rw->hwnd,
1555
+ NUM2UINT(v_msg), rw_get_param(v_wparam), rw_get_param(v_lparam));
1556
+ return r ? Qtrue : Qnil;
1557
+ }
1558
+
1559
+ static VALUE
1560
+ rwwin_getwndlong(VALUE self, VALUE v_idx){
1561
+ RwWindow *rw = DATA_PTR(self);
1562
+ RwCheckWindow(rw);
1563
+ return INT2NUM(GetWindowLongPtr(rw->hwnd, FIX2INT(v_idx)));
1564
+ }
1565
+
1566
+ static VALUE
1567
+ rwwin_setwndlong(VALUE self, VALUE v_idx, VALUE v_arg){
1568
+ RwWindow *rw = DATA_PTR(self);
1569
+ RwCheckWindow(rw);
1570
+ if (SetWindowLongPtr(rw->hwnd, FIX2INT(v_idx), NUM2INT(v_arg))) {
1571
+ rw_call_without_gvl_7(rw->nthread_id, (FARPROC)SetWindowPos, (ULONG_PTR)rw->hwnd, 0, 0,
1572
+ 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
1573
+ return Qtrue;
1574
+ }
1575
+ return Qfalse;
1576
+ }
1577
+
1578
+ static VALUE
1579
+ rwwin_setwndpos(VALUE self, VALUE v_insert_after, VALUE v_x, VALUE v_y, VALUE v_w, VALUE v_h, VALUE v_flags){
1580
+ int r, insert_after;
1581
+ RwWindow *rw = DATA_PTR(self);
1582
+ RwCheckWindow(rw);
1583
+ if(rb_typeddata_is_kind_of(v_insert_after, &rwwin_data_type)){
1584
+ RwWindow *wn;
1585
+ RwWindow_Data_Get_Struct(self, wn);
1586
+ RwCheckWindow(wn);
1587
+ insert_after = (ULONG_PTR)wn->hwnd;
1588
+ } else {
1589
+ insert_after = NUM2INT(v_insert_after);
1590
+ }
1591
+ r = rw_call_without_gvl_7(rw->nthread_id, (FARPROC)SetWindowPos, (ULONG_PTR)rw->hwnd,
1592
+ insert_after, FIX2INT(v_x), FIX2INT(v_y), FIX2INT(v_w),
1593
+ FIX2INT(v_h), NUM2INT(v_flags));
1594
+ return r ? Qtrue : Qnil;
1595
+ }
1596
+
1597
+ static VALUE
1598
+ rwwin_getwindowrect(VALUE self){
1599
+ RECT rc;
1600
+ RwWindow *rw = DATA_PTR(self);
1601
+ RwCheckWindow(rw);
1602
+ if(GetWindowRect(rw->hwnd, &rc)){
1603
+ CStructData *cs;
1604
+ VALUE v_rect = api_cstruct_new(ccsRECT);
1605
+ CStruct_Data_Get_Struct(v_rect, cs);
1606
+ memcpy(cs->dtstr, &rc, sizeof(RECT)); /* cs->dtoffset is always 0 */
1607
+ return v_rect;
1608
+ } else {
1609
+ return Qfalse;
1610
+ }
1611
+ }
1612
+
1613
+ static VALUE
1614
+ rwwin_setcapture(VALUE self){
1615
+ HWND hWnd;
1616
+ VALUE wobj;
1617
+ RwWindow *rw = DATA_PTR(self);
1618
+ RwCheckWindow(rw);
1619
+ hWnd = SetCapture(rw->hwnd);
1620
+ if(!(wobj = Get_win(hWnd))) wobj = Get_childwin(hWnd);
1621
+ return wobj || Qnil; /* return previous captured window */
1622
+ }
1623
+
1624
+ static VALUE
1625
+ rwwin_releasecapture(VALUE self){
1626
+ int r = ReleaseCapture();
1627
+ return r ? Qtrue : Qfalse;
1628
+ }
1629
+
1630
+ static VALUE
1631
+ rwwin_showwindow(VALUE self, VALUE v_flag){
1632
+ RwWindow *rw = DATA_PTR(self);
1633
+ RwCheckWindow(rw);
1634
+ rw_call_without_gvl_2(rw->nthread_id, (FARPROC)ShowWindow, (ULONG_PTR)rw->hwnd,
1635
+ FIX2INT(v_flag));
1636
+ return self;
1637
+ }
1638
+
1639
+ static VALUE
1640
+ rwwin_registerhotkey(VALUE self, VALUE v_id, VALUE v_modifiers, VALUE v_vkey){
1641
+ int r;
1642
+ RwWindow *rw = DATA_PTR(self);
1643
+ RwCheckWindow(rw);
1644
+ r = RegisterHotKey(rw->hwnd, NUM2INT(v_id), NUM2UINT(v_modifiers), NUM2UINT(v_vkey));
1645
+ return r ? Qtrue : Qfalse;
1646
+ }
1647
+
1648
+ static VALUE
1649
+ rwwin_unregisterhotkey(VALUE self, VALUE v_id){
1650
+ int r;
1651
+ RwWindow *rw = DATA_PTR(self);
1652
+ RwCheckWindow(rw);
1653
+ r = UnregisterHotKey(rw->hwnd, NUM2INT(v_id));
1654
+ return r ? Qtrue : Qfalse;
1655
+ }
1656
+
1657
+ static VALUE
1658
+ rwwin_client2screen(VALUE self, VALUE v_x, VALUE v_y){
1659
+ VALUE robj;
1660
+ POINT pt;
1661
+ RwWindow *rw = DATA_PTR(self);
1662
+ pt.x = NUM2INT(v_x);
1663
+ pt.y = NUM2INT(v_y);
1664
+ ClientToScreen(rw->hwnd, &pt);
1665
+ robj = rb_ary_new2(2);
1666
+ rb_ary_store(robj, 0, INT2NUM(pt.x));
1667
+ rb_ary_store(robj, 1, INT2NUM(pt.y));
1668
+ return robj;
1669
+ }
1670
+
1671
+ static VALUE
1672
+ rwwin_screen2client(VALUE self, VALUE v_x, VALUE v_y){
1673
+ VALUE robj;
1674
+ POINT pt;
1675
+ RwWindow *rw = DATA_PTR(self);
1676
+ pt.x = NUM2INT(v_x);
1677
+ pt.y = NUM2INT(v_y);
1678
+ ScreenToClient(rw->hwnd, &pt);
1679
+ robj = rb_ary_new2(2);
1680
+ rb_ary_store(robj, 0, INT2NUM(pt.x));
1681
+ rb_ary_store(robj, 1, INT2NUM(pt.y));
1682
+ return robj;
1683
+ }
1684
+
1685
+ void
1686
+ rw_init_RwWindow(){
1687
+ cRwWindow = rb_define_class_under(mRwin, "Window", rb_cData);
1688
+ rb_define_alloc_func(cRwWindow, alloc_rw_window);
1689
+ rb_define_singleton_method(cRwWindow, "new_from_handle", rwwin1_new_from_handle, 1);
1690
+
1691
+ rb_define_method(cRwWindow, "register_event", rwwin_msgfilter_add, -1);
1692
+ rb_define_method(cRwWindow, "unregister_event", rwwin_msgfilter_delete, -1);
1693
+ rb_define_method(cRwWindow, "event_registered?", rwwin_msgfilter_exist_p, -1);
1694
+ rb_define_method(cRwWindow, "registered_messages", rwwin_msgfilter_getfilters, 0);
1695
+ rb_define_method(cRwWindow, "set_msgtranslator", rwwin_msgtranslator_set, -1);
1696
+ rb_define_method(cRwWindow, "get_msgtranslator", rwwin_msgtranslator_get, 1);
1697
+ rb_define_method(cRwWindow, "method_missing", rw_method_missing, -1);
1698
+ rb_define_method(cRwWindow, "set_accelerator", rw_set_accelerator, 1);
1699
+
1700
+
1701
+ rb_define_method(cRwWindow, "create", rwwin_create, -1);
1702
+ rb_define_method(cRwWindow, "close", rwwin_close, 0);
1703
+ rb_define_method(cRwWindow, "_hwnd", rwwin_gethandle, 0);
1704
+ rb_define_method(cRwWindow, "alive?", rwwin_alive_p, 0);
1705
+ rb_define_method(cRwWindow, "move", rwwin_move, -1);
1706
+ rb_define_method(cRwWindow, "resize", rwwin_resize, 2);
1707
+ rb_define_method(cRwWindow, "refresh", rwwin_refresh, -1);
1708
+ rb_define_method(cRwWindow, "redraw", rwwin_setredraw, -1);
1709
+ rb_define_method(cRwWindow, "screenpos", rwwin_getscreenpos, 0);
1710
+ rb_define_method(cRwWindow, "clientpos", rwwin_getclientpos, 0);
1711
+ rb_define_method(cRwWindow, "windowsize", rwwin_getwndsize, 0);
1712
+ rb_define_method(cRwWindow, "clientsize", rwwin_getclientsize, 0);
1713
+ rb_define_method(cRwWindow, "setorder", rwwin_setorder, 1);
1714
+ rb_define_method(cRwWindow, "cursorPos", rwwin_getcursorpos, 0);
1715
+
1716
+ /* r/w attributes */
1717
+ rb_define_method(cRwWindow, "caption",rwwin_getcaption, 0);
1718
+ rb_define_method(cRwWindow, "caption=",rwwin_setcaption, 1);
1719
+ rb_define_method(cRwWindow, "visible", rwwin_getvisible, 0);
1720
+ rb_define_method(cRwWindow, "visible=", rwwin_setvisible, 1);
1721
+ rb_define_method(cRwWindow, "idcmd", rwwin_getidcmd, 0);
1722
+ rb_define_method(cRwWindow, "idcmd=", rwwin_setidcmd, 1);
1723
+ rb_define_method(cRwWindow, "parent", rwwin_getparent, 0);
1724
+ rb_define_method(cRwWindow, "parent=", rwwin_setparent, 1);
1725
+ rb_define_method(cRwWindow, "x", rwwin_getx, 0);
1726
+ rb_define_method(cRwWindow, "y", rwwin_gety, 0);
1727
+ rb_define_method(cRwWindow, "w", rwwin_getw, 0);
1728
+ rb_define_method(cRwWindow, "h", rwwin_geth, 0);
1729
+ rb_define_method(cRwWindow, "x=", rwwin_setx, 1);
1730
+ rb_define_method(cRwWindow, "y=", rwwin_sety, 1);
1731
+ rb_define_method(cRwWindow, "w=", rwwin_setw, 1);
1732
+ rb_define_method(cRwWindow, "h=", rwwin_seth, 1);
1733
+
1734
+ /* hook functions */
1735
+ rb_define_method(cRwWindow, "SetWindowSubclass", rwwin_setsubclass, 0);
1736
+ rb_define_method(cRwWindow, "RemoveWindowSubclass", rwwin_removesubclass, 0);
1737
+
1738
+ /* API functions */
1739
+ rb_define_method(cRwWindow, "SetFocus", rwwin_setfocus, 0);
1740
+ rb_define_method(cRwWindow, "SendMessage", rwwin_sendmessage, 3);
1741
+ rb_define_method(cRwWindow, "PostMessage", rwwin_postmessage, 3);
1742
+ rb_define_method(cRwWindow, "GetWindowLong", rwwin_getwndlong, 1);
1743
+ rb_define_method(cRwWindow, "SetWindowLong", rwwin_setwndlong, 2);
1744
+ rb_define_method(cRwWindow, "SetWindowPos", rwwin_setwndpos, 6);
1745
+ rb_define_method(cRwWindow, "GetWindowRect", rwwin_getwindowrect, 0);
1746
+ rb_define_method(cRwWindow, "SetCapture", rwwin_setcapture, 0);
1747
+ rb_define_method(cRwWindow, "ReleaseCapture", rwwin_releasecapture, 0);
1748
+ rb_define_method(cRwWindow, "ShowWindow", rwwin_showwindow, 1);
1749
+ rb_define_method(cRwWindow, "RegisterHotKey", rwwin_registerhotkey, 3);
1750
+ rb_define_method(cRwWindow, "UnregisterHotKey", rwwin_unregisterhotkey, 1);
1751
+ rb_define_method(cRwWindow, "ClientToScreen", rwwin_client2screen, 2);
1752
+ rb_define_method(cRwWindow, "ScreenToClient", rwwin_screen2client, 2);
1753
+ }
1754
+
1755
+ /* RwDaialog */
1756
+ VALUE cRwDialog;
1757
+
1758
+ /* TypedData */
1759
+ void rw_dlg_free(void *ptr){
1760
+ RwDialog *rd =ptr;
1761
+ if (rd->rwwin.hwnd) DestroyWindow(rd->rwwin.hwnd);
1762
+ if (rd->rwwin.msgfilter) freeAAtree(rd->rwwin.msgfilter);
1763
+ if (rd->rwwin.handler_ids) freeAAtree(rd->rwwin.handler_ids);
1764
+ free(rd);
1765
+ }
1766
+
1767
+ static size_t
1768
+ rwdlg_memsize(const void *ptr){
1769
+ return ptr ? sizeof(RwDialog) : 0;
1770
+ }
1771
+
1772
+ const rb_data_type_t
1773
+ rwdlg_data_type = { /* parent is rwwin_data_type */
1774
+ "Dialog", {NULL, rw_dlg_free, rwdlg_memsize}, &rwwin_data_type, NULL
1775
+ };
1776
+
1777
+ static VALUE
1778
+ alloc_rw_dialog(VALUE klass){
1779
+ RwDialog *rd;
1780
+ VALUE obj;
1781
+ obj = RwDialog_Data_Make_Struct(klass, rd);
1782
+ rd->rwwin.msgfilter = NULL;
1783
+ rd->rwwin.handler_ids = NULL;
1784
+ return obj;
1785
+ }
1786
+
1787
+ INT_PTR CALLBACK
1788
+ RwDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){
1789
+ VALUE wobj;
1790
+ if(uMsg==WM_INITDIALOG){
1791
+ RwDialog *rd;
1792
+ VALUE dobj = lParam;
1793
+ RwDialog_Data_Get_Struct(dobj, rd);
1794
+ rd->rwwin.hwnd = hWnd;
1795
+ Register_win(hWnd, dobj);
1796
+ }
1797
+ if(wobj = Get_win(hWnd)){
1798
+ RwWindow *rw = DATA_PTR(wobj);
1799
+ if(uMsg == WM_PAINT){
1800
+ if (rw->msgfilter) {
1801
+ AAnode *nd = aaSearch(rw->msgfilter, WM_PAINT);
1802
+ if (nd) {
1803
+ PAINTSTRUCT ps;
1804
+ RwBaseHandler *basehandler = nd->val;
1805
+ HDC hdc = BeginPaint(rw->hwnd, &ps);
1806
+ dispatch_wm_paint_handler(wobj, basehandler, hdc);
1807
+ EndPaint(rw->hwnd, &ps);
1808
+ return 0;
1809
+ }
1810
+ }
1811
+ } else {
1812
+ LRESULT ret;
1813
+ if (uMsg==WM_ACTIVATE) activewin = LOWORD(wParam) ? rw : NULL;
1814
+ ret=do_wm_default(wobj, &uMsg, &wParam, &lParam);
1815
+ if (ret){
1816
+ SetWindowLongPtr(hWnd, DWLP_MSGRESULT, ret);
1817
+ return TRUE; /* skip default dlgdproc */
1818
+ }
1819
+ }
1820
+
1821
+ switch(uMsg){
1822
+ case WM_CLOSE:
1823
+ if(((RwDialog*)rw)->modal) {
1824
+ EndDialog(hWnd, Qfalse);
1825
+ if(aaCount(winlist)==0) rwwin_finalize();
1826
+ } else {
1827
+ DestroyWindow(hWnd);
1828
+ }
1829
+ return TRUE;
1830
+ case WM_DESTROY:
1831
+ rw->hwnd = NULL;
1832
+ Unregister_win(hWnd);
1833
+ if(aaCount(winlist)==0){
1834
+ rwwin_finalize();
1835
+ PostQuitMessage(wParam);
1836
+ return 0;
1837
+ }
1838
+ return TRUE;
1839
+ default:
1840
+ break;
1841
+ }
1842
+ }
1843
+ return 0;
1844
+ }
1845
+
1846
+ static VALUE
1847
+ rwdialog_create(int argc, VALUE *argv, VALUE self){
1848
+ DLGTEMPLATE *template;
1849
+ VALUE v_parent, v_modal, v_param;
1850
+ INT_PTR ret;
1851
+ HWND hparent = NULL;
1852
+ BOOL template_given = FALSE;
1853
+ RwDialog *rd = DATA_PTR(self);
1854
+
1855
+ if(rb_typeddata_is_kind_of(argv[2], &cstruct_data_type)) {
1856
+ VALUE v_template;
1857
+ CStructData *cs;
1858
+ rb_scan_args(argc, argv, "31", &v_parent, &v_modal, &v_template, &v_param);
1859
+ CStruct_Data_Get_Struct(v_template, cs);
1860
+ template_given = TRUE;
1861
+ template = (DLGTEMPLATE*)(cs->dtstr + cs->dtoffset);
1862
+ } else { /* create default template */
1863
+ VALUE v_style, v_exstyle;
1864
+ rb_scan_args(argc, argv, "23", &v_parent, &v_modal, &v_style, &v_exstyle, &v_param);
1865
+ RW_CALLOC(template, sizeof(DLGTEMPLATE) + 4);
1866
+ template->style = NIL_P(v_style) ?
1867
+ (WS_POPUP | WS_BORDER | WS_SYSMENU | WS_CAPTION | DS_MODALFRAME) : NUM2UINT(v_style);
1868
+ template->dwExtendedStyle = NIL_P(v_exstyle) ? 0 : NUM2UINT(v_exstyle);
1869
+ rd->param = v_param;
1870
+ }
1871
+
1872
+ rd->modal = (!NIL_P(v_modal) && v_modal) ? TRUE : FALSE;
1873
+ if(!NIL_P(v_parent)){
1874
+ RwWindow *rw;
1875
+ RwWindow_Data_Get_Struct(v_parent, rw);
1876
+ hparent = rw->hwnd;
1877
+ }
1878
+ if(rd->modal){
1879
+ ret = DialogBoxIndirectParam(hInstance, template, hparent, RwDlgProc, self);
1880
+ if (ret==-1) rb_raise(rb_eRuntimeError,"create modal dialog failed");
1881
+ } else {
1882
+ HWND hwnd;
1883
+ hwnd = CreateDialogIndirectParam(hInstance, template, hparent, RwDlgProc, self);
1884
+ if (!hwnd) rb_raise(rb_eRuntimeError,"create modeless dialog failed");
1885
+ ShowWindow(hwnd, TRUE);
1886
+ ret = Qnil;
1887
+ }
1888
+ if(!template_given) {
1889
+ free(template);
1890
+ }
1891
+ return (VALUE)ret;
1892
+ }
1893
+
1894
+ static VALUE
1895
+ rwdialog_close(int argc, VALUE *argv, VALUE self){
1896
+ VALUE v_ret;
1897
+ RwWindow *rw;
1898
+ RwDialog *rd = DATA_PTR(self);
1899
+ rw = (RwWindow*)rd;
1900
+ RwCheckWindow(rw);
1901
+ rb_scan_args(argc, argv, "01", &v_ret);
1902
+ if (rd->modal){ //fprintf(stderr, "@%d: v_ret=%lld\n", __LINE__, v_ret);
1903
+ // return rw_call_without_gvl_2(rw->nthread_id, (FARPROC)EndDialog, (ULONG_PTR)rw->hwnd,
1904
+ // (ULONG_PTR)v_ret);
1905
+ return EndDialog(rw->hwnd, (INT_PTR)v_ret);
1906
+ } else {
1907
+ DestroyWindow(((RwWindow*)rd)->hwnd);
1908
+ return 0;
1909
+ }
1910
+ }
1911
+
1912
+ static VALUE
1913
+ rwdialog_getparam(VALUE self){
1914
+ RwDialog *rd = DATA_PTR(self);
1915
+ RwCheckWindow((RwWindow*)rd);
1916
+ return rd->param;
1917
+ }
1918
+
1919
+ static void
1920
+ rw_init_RwDialog(){
1921
+ cRwDialog = rb_define_class_under(mRwin, "Dialog", cRwWindow);
1922
+ rb_define_alloc_func(cRwDialog, alloc_rw_dialog);
1923
+ rb_define_method(cRwDialog, "create", rwdialog_create, -1);
1924
+ rb_define_method(cRwDialog, "close", rwdialog_close, -1);
1925
+ rb_define_method(cRwDialog, "param", rwdialog_getparam, 0);
1926
+
1927
+ rb_undef_method(cRwDialog, "SetWindowSubclass");
1928
+ rb_undef_method(cRwDialog, "RemoveWindowSubclass");
1929
+ }
1930
+
1931
+ /* Initializing */
1932
+ void
1933
+ Init_rw_windows(){
1934
+ rw_init_RwWindow();
1935
+ rw_init_RwDialog();
1936
+ }