exerb 6.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (179) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +8 -0
  3. data/ChangeLog.ja.rd +305 -0
  4. data/README.en.txt +12 -0
  5. data/README.ja.html +143 -0
  6. data/README.ja.txt +6 -0
  7. data/README.md +50 -0
  8. data/Rakefile +205 -0
  9. data/bin/exerb +185 -0
  10. data/bin/mkexy +47 -0
  11. data/doc/LGPL +513 -0
  12. data/doc/class.ja.html +92 -0
  13. data/doc/command.ja.html +109 -0
  14. data/doc/core.ja.html +72 -0
  15. data/doc/example.ja.html +89 -0
  16. data/doc/faq.ja.html +59 -0
  17. data/doc/inside.ja.rd +404 -0
  18. data/doc/license.ja.html +62 -0
  19. data/doc/logo.gif +0 -0
  20. data/doc/misc.ja.html +72 -0
  21. data/doc/navi.gif +0 -0
  22. data/doc/recipe.ja.html +317 -0
  23. data/doc/style.css +187 -0
  24. data/doc/tutorial.ja.html +182 -0
  25. data/example/Makefile +54 -0
  26. data/example/cat_n.rb +14 -0
  27. data/example/exception.rb +9 -0
  28. data/example/ext/Win32API.so +0 -0
  29. data/example/ext/swin.so +0 -0
  30. data/example/msgbox.rb +14 -0
  31. data/example/rubytk.rb +22 -0
  32. data/example/runtime.ico +0 -0
  33. data/example/runtime.rb +19 -0
  34. data/example/vr/clipboard.rb +106 -0
  35. data/example/vr/compat/rubycompat.rb +18 -0
  36. data/example/vr/compat/vrcomctl.rb +12 -0
  37. data/example/vr/compat/vrcontrol.rb +50 -0
  38. data/example/vr/compat/vrmmedia.rb +24 -0
  39. data/example/vr/contrib/inifile.rb +116 -0
  40. data/example/vr/contrib/msgboxconst.rb +55 -0
  41. data/example/vr/contrib/toolbar.rb +371 -0
  42. data/example/vr/contrib/vrctlcolor.rb +110 -0
  43. data/example/vr/contrib/vrhotkey.rb +35 -0
  44. data/example/vr/contrib/vrlistviewex.rb +71 -0
  45. data/example/vr/contrib/vrstdscrollbar.rb +414 -0
  46. data/example/vr/contrib/vrwincomponent.rb +54 -0
  47. data/example/vr/dragdropformat.rb +209 -0
  48. data/example/vr/rscutil.rb +168 -0
  49. data/example/vr/sysmod.rb +249 -0
  50. data/example/vr/vractivex.rb +56 -0
  51. data/example/vr/vrclipboard.rb +53 -0
  52. data/example/vr/vrcomctl.rb +1819 -0
  53. data/example/vr/vrcontrol.rb +1374 -0
  54. data/example/vr/vrdde.rb +623 -0
  55. data/example/vr/vrddrop.rb +190 -0
  56. data/example/vr/vrdialog.rb +406 -0
  57. data/example/vr/vrhandler.rb +195 -0
  58. data/example/vr/vrlayout.old.rb +209 -0
  59. data/example/vr/vrlayout.rb +173 -0
  60. data/example/vr/vrlayout2.rb +340 -0
  61. data/example/vr/vrmargin.rb +141 -0
  62. data/example/vr/vrmgdlayout.rb +381 -0
  63. data/example/vr/vrmmedia.rb +287 -0
  64. data/example/vr/vrolednd.rb +192 -0
  65. data/example/vr/vrowndraw.rb +108 -0
  66. data/example/vr/vrrichedit.rb +366 -0
  67. data/example/vr/vrtimer.rb +148 -0
  68. data/example/vr/vrtooltip.rb +273 -0
  69. data/example/vr/vrtray.rb +143 -0
  70. data/example/vr/vrtvitem.rb +118 -0
  71. data/example/vr/vrtwopane.rb +223 -0
  72. data/example/vr/vruby.rb +1051 -0
  73. data/example/vr/winconst.rb +158 -0
  74. data/example/vruby.rb +38 -0
  75. data/exerb.gemspec +26 -0
  76. data/extconf.rb +7 -0
  77. data/lib/exerb/archive.rb +143 -0
  78. data/lib/exerb/config.rb +51 -0
  79. data/lib/exerb/error.rb +15 -0
  80. data/lib/exerb/executable.rb +68 -0
  81. data/lib/exerb/file_table.rb +189 -0
  82. data/lib/exerb/mkexy.rb +81 -0
  83. data/lib/exerb/name_table.rb +120 -0
  84. data/lib/exerb/recipe.rb +465 -0
  85. data/lib/exerb/resource.rb +190 -0
  86. data/lib/exerb/resource/base.rb +29 -0
  87. data/lib/exerb/resource/binary.rb +31 -0
  88. data/lib/exerb/resource/dialog.rb +30 -0
  89. data/lib/exerb/resource/group_icon.rb +85 -0
  90. data/lib/exerb/resource/icon.rb +52 -0
  91. data/lib/exerb/resource/version_info.rb +155 -0
  92. data/lib/exerb/resource_library.rb +120 -0
  93. data/lib/exerb/utility.rb +95 -0
  94. data/lib/exerb/utility2.rb +122 -0
  95. data/lib/exerb/version.rb +13 -0
  96. data/lib/exerb/win32/const/resource.rb +51 -0
  97. data/lib/exerb/win32/icon_file.rb +78 -0
  98. data/lib/exerb/win32/pe_file.rb +59 -0
  99. data/lib/exerb/win32/resource_directory.rb +105 -0
  100. data/lib/exerb/win32/resource_directory_root.rb +67 -0
  101. data/lib/exerb/win32/resource_entry.rb +98 -0
  102. data/lib/exerb/win32/struct/base.rb +43 -0
  103. data/lib/exerb/win32/struct/icon_dir_entry.rb +83 -0
  104. data/lib/exerb/win32/struct/icon_header.rb +43 -0
  105. data/lib/exerb/win32/struct/icon_res_entry.rb +48 -0
  106. data/lib/exerb/win32/struct/image_dos_header.rb +73 -0
  107. data/lib/exerb/win32/struct/image_file_header.rb +47 -0
  108. data/lib/exerb/win32/struct/image_nt_headers32.rb +53 -0
  109. data/lib/exerb/win32/struct/image_optional_header32.rb +107 -0
  110. data/lib/exerb/win32/struct/image_resource_data_entry.rb +45 -0
  111. data/lib/exerb/win32/struct/image_resource_directory.rb +47 -0
  112. data/lib/exerb/win32/struct/image_resource_directory_entry.rb +72 -0
  113. data/lib/exerb/win32/struct/image_section_header.rb +53 -0
  114. data/lib/exerb/win32/struct/version_info_block.rb +75 -0
  115. data/lib/exerb/win32/struct/vs_fixed_file_info.rb +62 -0
  116. data/src/exerb/cui.c +48 -0
  117. data/src/exerb/default.rb +1 -0
  118. data/src/exerb/exerb.c +877 -0
  119. data/src/exerb/exerb.h +92 -0
  120. data/src/exerb/gui.c +176 -0
  121. data/src/exerb/module.c +138 -0
  122. data/src/exerb/module.h +7 -0
  123. data/src/exerb/patch.c +27 -0
  124. data/src/exerb/resource.h +22 -0
  125. data/src/exerb/resource.rc +121 -0
  126. data/src/exerb/ruby.ico +0 -0
  127. data/src/exerb/utility.c +263 -0
  128. data/src/exerb/utility.h +33 -0
  129. data/test/alltests.rb +16 -0
  130. data/test/test-argv.rb +26 -0
  131. data/test/test-argv/test-argv.rb +9 -0
  132. data/test/test-argv/test-argv.ret +1 -0
  133. data/test/test-dollarzero.rb +26 -0
  134. data/test/test-dollarzero/test-dollarzero.rb +10 -0
  135. data/test/test-dollarzero/test-dollarzero.ret +2 -0
  136. data/test/test-dot.rb +26 -0
  137. data/test/test-dot/dot.dot.dot.rb +9 -0
  138. data/test/test-dot/dot.dot.rb +9 -0
  139. data/test/test-dot/test-dot.rb +13 -0
  140. data/test/test-dot/test-dot.ret +5 -0
  141. data/test/test-exitcode.rb +28 -0
  142. data/test/test-exitcode/test-exitcode.rb +9 -0
  143. data/test/test-kcode.rb +43 -0
  144. data/test/test-kcode/euc.rb +10 -0
  145. data/test/test-kcode/euc.ret +2 -0
  146. data/test/test-kcode/none.rb +10 -0
  147. data/test/test-kcode/none.ret +2 -0
  148. data/test/test-kcode/sjis.rb +10 -0
  149. data/test/test-kcode/sjis.ret +2 -0
  150. data/test/test-kcode/utf8.rb +10 -0
  151. data/test/test-kcode/utf8.ret +2 -0
  152. data/test/test-loadpath.rb +24 -0
  153. data/test/test-loadpath/test-loadpath.rb +9 -0
  154. data/test/test-nest.rb +18 -0
  155. data/test/test-nest/foo.rb +1 -0
  156. data/test/test-nest/foo/bar.rb +2 -0
  157. data/test/test-nest/foo/foo.rb +1 -0
  158. data/test/test-nest/test-nest.rb +1 -0
  159. data/test/test-nest/test-nest.ret +1 -0
  160. data/test/test-preload.rb +24 -0
  161. data/test/test-preload/test-preload.rb +9 -0
  162. data/test/test-regexp.rb +26 -0
  163. data/test/test-regexp/test-regexp.rb +23 -0
  164. data/test/test-regexp/test-regexp.ret +13 -0
  165. data/test/test-require1.rb +26 -0
  166. data/test/test-require1/require1.rb +9 -0
  167. data/test/test-require1/require2.rb +9 -0
  168. data/test/test-require1/require3.rb +9 -0
  169. data/test/test-require1/require4.rb +9 -0
  170. data/test/test-require1/require5.rb +9 -0
  171. data/test/test-require1/require6.rb +9 -0
  172. data/test/test-require1/test-require1.rb +41 -0
  173. data/test/test-require1/test-require1.ret +27 -0
  174. data/test/test-socket.rb +26 -0
  175. data/test/test-socket/test-socket.rb +7 -0
  176. data/test/test-socket/test-socket.ret +1 -0
  177. data/test/testcase.rb +66 -0
  178. data/vendor/mkexports.rb +167 -0
  179. metadata +352 -0
@@ -0,0 +1,118 @@
1
+ ###################################
2
+ #
3
+ # vrtvitem.rb
4
+ # Programmed by nyasu <nyasu@osk.3web.ne.jp>
5
+ # Copyright 2000-2005 Nishikawa,Yasuhiro
6
+ #
7
+ # More information at http://vruby.sourceforge.net/index.html
8
+ #
9
+ ###################################
10
+
11
+
12
+ VR_DIR="vr/" unless defined?(::VR_DIR)
13
+ require VR_DIR+'vrcomctl'
14
+
15
+ class VRTreeview
16
+
17
+ class VRTreeviewItem
18
+ =begin
19
+ == VRTreeview::VRTreeviewItem
20
+ Represents an item in Treeview.
21
+ This is just a referencing object so that only one treeview item entity
22
+ is referenced by many referencing objects.
23
+
24
+ === Class Methods
25
+ --- new(treeview,hitem,lparam=0)
26
+ You may not need this method in your script.
27
+
28
+ === Methods
29
+ --- insertChildFirst(text,lparam=0)
30
+ Adds a new child item with ((|text|)) and ((|lparam|)) for the first item.
31
+ --- insertChildLast(text,lparam=0)
32
+ Adds a new child item with ((|text|)) and ((|lparam|)) for the last item.
33
+ --- insertChildAfter(item,text,lparam=0)
34
+ Adds a new child item after ((|item|))
35
+ --- parent
36
+ Returns the parent item.
37
+ --- firstChild
38
+ Returns the first child item.
39
+ --- nextSibling
40
+ Returns the next sibling item of the treeview item.
41
+ --- eachChild
42
+ Yields each child items.
43
+ --- icon
44
+ --- icon=
45
+ Sets/Gets the icon for the treeview item.
46
+ --- text
47
+ --- text=
48
+ Sets/Gets the text for the treeview item.
49
+ --- lparam
50
+ --- lparam=
51
+ Sets/Gets the lparam for the treeview item.
52
+ --- state
53
+ --- state=
54
+ Sets/Gets the state for the treeview item.
55
+ =end
56
+
57
+
58
+ attr :treeview
59
+ attr :hitem
60
+ private
61
+ def initialize(tv,hitem,lparam=0)
62
+ @treeview = tv
63
+ @hitem=hitem
64
+ end
65
+
66
+ def _vr_addChild(it,text,lparam)
67
+ VRTreeviewItem.new(@treeview,@treeview.insertItem(@hitem,it,text,lparam))
68
+ end
69
+
70
+ public
71
+ def insertChildFirst(text,lparam=0)
72
+ _vr_addChild(WConst::TVI_FIRST,text,lparam)
73
+ end
74
+ def insertChildLast(text,lparam=0)
75
+ _vr_addChild(WConst::TVI_LAST,text,lparam)
76
+ end
77
+ def insertChildAfter(item,text,lparam=0)
78
+ _vr_addChild(item.hitem,text,lparam)
79
+ end
80
+ alias addChild insertChildLast
81
+
82
+ def parent
83
+ VRTreeviewItem.new( @treeview,@treeview.getParentOf(@hitem) )
84
+ end
85
+ def firstChild
86
+ VRTreeviewItem.new( @treeview,@treeview.getChildOf(@hitem) )
87
+ end
88
+ def nextSibling
89
+ VRTreeviewItem.new( @treeview,@treeview.getNextSiblingOf(@hitem) )
90
+ end
91
+
92
+ def eachChild
93
+ r = firstChild
94
+ while r.hitem do
95
+ yield r
96
+ r = r.nextSibling
97
+ end
98
+ end
99
+
100
+
101
+ ["Icon","LParam","Text","State"].each do |nm|
102
+ eval <<"EEOOFF"
103
+ def #{nm.downcase}
104
+ @treeview.getItem#{nm}Of(@hitem)
105
+ end
106
+ def #{nm.downcase}=(p)
107
+ @treeview.setItem#{nm}Of(@hitem,p)
108
+ end
109
+ EEOOFF
110
+ end
111
+
112
+ end
113
+
114
+ def rootItem
115
+ VRTreeviewItem.new(self,WConst::TVGN_ROOT)
116
+ end
117
+ end
118
+
@@ -0,0 +1,223 @@
1
+ ###################################
2
+ #
3
+ # vrtwopane.rb
4
+ # Programmed by nyasu <nyasu@osk.3web.ne.jp>
5
+ # Copyright 1999-2005 Nishikawa,Yasuhiro
6
+ #
7
+ # More information at http://vruby.sourceforge.net/index.html
8
+ #
9
+ ###################################
10
+
11
+ VR_DIR="vr/" unless defined?(::VR_DIR)
12
+ require VR_DIR+'vruby'
13
+ require VR_DIR+'vrhandler'
14
+ require 'Win32API'
15
+
16
+ =begin
17
+ = VisualuRuby(tmp) Multi-pane Window
18
+ =end
19
+
20
+
21
+ module VRTwoPane
22
+ =begin
23
+ == VRTwoPane
24
+ This module is a base module for VRVertTwoPane and VRHorizTwoPane.
25
+ The meanings of 'Upper' and 'Lower' depend on those modules.
26
+ === Methods
27
+ --- addPanedControl(type,name,caption,astyle)
28
+ Adds a new control. This can be called only twice. The first call adds
29
+ an upper/left control and the next call adds lower/right control.
30
+ The third call causes RuntimeError.
31
+
32
+ --- addControlUpper(type,name,caption,astyle)
33
+ ((*obsolete*)).
34
+ Adds new control on the window upperside or leftside.
35
+ The arguments are the same of VRParent#addControl.
36
+ --- addControlLower(type,name,caption,astyle)
37
+ ((*obsolete*)).
38
+ Adds new control on the window downside or rightside.
39
+ The arguments are the same of VRParent#addControl.
40
+ =end
41
+
42
+ # include VRMouseFeasible
43
+ include VRParent
44
+
45
+ attr :ratio,1
46
+ attr :separatorheight,1
47
+ attr :pane_1
48
+ attr :pane_2
49
+
50
+ SPLITTER_MOVEWINDOW=0
51
+ SPLITTER_DRAWLINE=1
52
+ PatBlt = Win32API.new("gdi32","PatBlt","IIIIII","I")
53
+
54
+ def twopaneinit
55
+ @_vr_paned_splitter_movingmethod = SPLITTER_DRAWLINE
56
+ @_vr_dragging=false
57
+ @pane_1 = @pane_2 = nil
58
+ @ratio=0.5
59
+ @separatorheight=6
60
+ @_vr_app=@screen.application
61
+ @_vr_acmethod=self.method(:addControlUpper) unless defined? @_vr_acmethod
62
+ addHandler WMsg::WM_LBUTTONUP, "vrseplbuttonup", MSGTYPE::ARGINTSINTSINT,nil
63
+ addHandler WMsg::WM_LBUTTONDOWN,"vrseplbuttondown",MSGTYPE::ARGINTSINTSINT,nil
64
+ addHandler WMsg::WM_SIZE, "vrpaneresize", MSGTYPE::ARGLINTINT,nil
65
+ addHandler WMsg::WM_MOUSEMOVE, "vrsepmousemove", MSGTYPE::ARGINTSINTSINT,nil
66
+ acceptEvents [
67
+ WMsg::WM_SIZE,WMsg::WM_LBUTTONUP,WMsg::WM_LBUTTONDOWN,WMsg::WM_MOUSEMOVE
68
+ ]
69
+ end
70
+ def vrinit
71
+ super
72
+ twopaneinit
73
+ end
74
+
75
+ def addControlUpper(type,name,caption,style=0)
76
+ @pane_1=addControl(type,name,caption,0,0,10,10,style)
77
+ @_vr_acmethod=self.method(:addControlLower)
78
+ end
79
+ def addControlLower(type,name,caption,style=0)
80
+ @pane_2=addControl(type,name,caption,0,20,10,10,style)
81
+ @_vr_acmethod=self.method(:addControlIllegal)
82
+ end
83
+ def addControlIllegal(*arg)
84
+ raise "added more than two child windows."
85
+ end
86
+
87
+ def addPanedControl(*args)
88
+ @_vr_acmethod.call(*args)
89
+ end
90
+
91
+ def self_vrseplbuttondown(shift,x,y)
92
+ setCapture
93
+ @_vr_dragging=true
94
+ @_vr_app.setCursor @_vr_dragcur
95
+ x,y,@_vr_w,@_vr_h = self.clientrect #attr w,h is the size when drag starts.
96
+ end
97
+
98
+ def self_vrseplbuttonup(shift,x,y)
99
+ releaseCapture
100
+ @_vr_dragging=false
101
+ splitterDragEnd(x,y)
102
+ end
103
+
104
+ def self_vrsepmousemove(shift,x,y)
105
+ @_vr_app.setCursor @_vr_dragcur
106
+ return unless @_vr_dragging
107
+ splitterDragging(x,y)
108
+ end
109
+
110
+ def self_vrpaneresize(w,h)
111
+ return unless @pane_1 and @pane_2
112
+ x,y,w,h = self.clientrect
113
+ resizepane(x,y,w,h,@ratio)
114
+ end
115
+
116
+ def splitterDragEnd(*arg) end
117
+ def splitterDragging(*arg) end
118
+ def resizepane(*arg) end
119
+ end
120
+ module VRVertTwoPane
121
+ =begin
122
+ == VRVertTwoPane
123
+ This module is a kind of VRTwoPane to separate the window vertically
124
+ and places the controls in the separeted area.
125
+ =end
126
+
127
+ include VRTwoPane
128
+
129
+ def vrinit
130
+ super
131
+ @_vr_dragcur = @_vr_app::SysCursors::SizeNS()
132
+ @_vr_splitter_last = nil
133
+ end
134
+
135
+ def splitterDragEnd(x,y)
136
+ sh=(@separatorheight/2).to_i
137
+ @_vr_splitter_last=nil
138
+ @pane_1.move 0,0,@_vr_w,y-sh
139
+ @pane_2.move 0,y+sh,@_vr_w,@_vr_h-y-sh
140
+ @ratio=y.to_f/@_vr_h
141
+ end
142
+
143
+ def splitterDragging(x,y)
144
+ sh=(@separatorheight/2).to_i
145
+ return if y+sh>@_vr_h || y<0
146
+ case(@_vr_paned_splitter_movingmethod)
147
+ when SPLITTER_MOVEWINDOW
148
+ @pane_1.move 0,0,@_vr_w,y-sh
149
+ @pane_2.move 0,y+sh,@_vr_w,@_vr_h-y-sh
150
+ when SPLITTER_DRAWLINE
151
+ dopaint do |hdc|
152
+ setBrush(RGB(0x255,0x255,0x255))
153
+ if @_vr_splitter_last then
154
+ PatBlt.call(hdc,*@_vr_splitter_last)
155
+ end
156
+ current=[0,y,@_vr_w,@separatorheight,0x5a0049] # PATINVERT
157
+ PatBlt.call(hdc,*current)
158
+ @_vr_splitter_last = current
159
+ end
160
+ end
161
+ end
162
+
163
+ def resizepane(x,y,w,h,ratio)
164
+ ys = (h*@ratio).to_i
165
+ sh=(@separatorheight/2).to_i
166
+ @pane_1.move 0,0,w,ys-sh
167
+ @pane_2.move 0,ys+sh,w,h-ys-sh
168
+ end
169
+ end
170
+
171
+ module VRHorizTwoPane
172
+ =begin
173
+ == VRHorizTwoPane
174
+ This module is a kind of VRTwoPane to separate the window horizontally
175
+ and places the controls in the separeted area.
176
+ =end
177
+ include VRTwoPane
178
+
179
+ def vrinit
180
+ super
181
+ @_vr_dragcur = @_vr_app::SysCursors::SizeWE()
182
+ @_vr_splitter_last = nil
183
+ end
184
+
185
+ def splitterDragEnd(x,y)
186
+ sh=(@separatorheight/2).to_i
187
+ @_vr_splitter_last=nil
188
+ @ratio=x.to_f/@_vr_w
189
+ @pane_1.move 0,0,x-sh,@_vr_h
190
+ @pane_2.move x+sh,0,@_vr_w-x-sh,@_vr_h
191
+ end
192
+
193
+ def splitterDragging(x,y)
194
+ sh=(@separatorheight/2).to_i
195
+ return if x+sh>@_vr_w || x<0
196
+ case(@_vr_paned_splitter_movingmethod)
197
+ when SPLITTER_MOVEWINDOW
198
+ @pane_1.move 0,0,x-sh,@_vr_h
199
+ @pane_2.move x+sh,0,@_vr_w-x-sh,@_vr_h
200
+ when SPLITTER_DRAWLINE
201
+ dopaint do |hdc|
202
+ setBrush(RGB(0x255,0x255,0x255))
203
+ if @_vr_splitter_last then
204
+ PatBlt.call(hdc,*@_vr_splitter_last)
205
+ end
206
+ current=[x,0,@separatorheight,@_vr_h,0x5a0049] # PATINVERT
207
+ PatBlt.call(hdc,*current)
208
+ @_vr_splitter_last = current
209
+ end
210
+ end
211
+
212
+
213
+ end
214
+
215
+ def resizepane(x,y,w,h,ratio)
216
+ xs = (w*ratio).to_i
217
+ sh=(@separatorheight/2).to_i
218
+ return if x+sh>w || x<0
219
+ @pane_1.move 0,0,xs-sh,h
220
+ @pane_2.move xs+sh,0,w-xs-sh,h
221
+ end
222
+ end
223
+
@@ -0,0 +1,1051 @@
1
+ ###################################
2
+ #
3
+ # vruby.rb
4
+ # Programmed by nyasu <nyasu@osk.3web.ne.jp>
5
+ # Copyright 1999-2005 Nishikawa,Yasuhiro
6
+ #
7
+ # More information at http://vruby.sourceforge.net/index.html
8
+ #
9
+ ###################################
10
+
11
+ =begin
12
+ = VisualuRuby(tmp) Main modules and classes
13
+ =end
14
+
15
+
16
+ SWIN_REQUIRED = "030817" unless defined?(SWIN_REQUIRED)
17
+ VR_COMPATIBILITY_LEVEL=3 unless defined?(VR_COMPATIBILITY_LEVEL)
18
+
19
+ require 'swin'
20
+
21
+ if SWin::VERSION < SWIN_REQUIRED then
22
+ raise StandardError,"\nswin.so (#{SWin::VERSION}) version too old. Need #{SWIN_REQUIRED} or later."
23
+ end
24
+
25
+ VR_DIR="vr/" unless defined?(::VR_DIR)
26
+ require VR_DIR+'compat/rubycompat'
27
+ require VR_DIR+'winconst'
28
+ require VR_DIR+'rscutil'
29
+
30
+ module MSGTYPE
31
+ =begin
32
+ == MSGTYPE
33
+ This is a module to collect constants of Windows message's argument type.
34
+ These constants decide an argument list for message handler.
35
+ The point is how to use lParam and wParam which are Integers.
36
+ === Constants
37
+ --- ARGNONE
38
+ No use of wParam and lParam. The handler don't have arguments.
39
+ --- ARGINT
40
+ lParam is the argument of handler.
41
+ The handler is defined as a type of self_handler(lParam)
42
+ --- ARGSTRUCT
43
+ lParam is a pointer to structured data. The handler's argument is decided
44
+ by that structure.
45
+ --- ARGSTRING
46
+ lParam is a char* pointer.
47
+ The handler is defined as a type of self_handler(String)
48
+ --- ARGWINT
49
+ wParam is for the argument of handler.
50
+ The handler is defined as a type of self_handler(wParam)
51
+ --- ARGLINT
52
+ Same as ARGINT
53
+ --- ARGINTINT
54
+ lParam and wParam are for the argument.
55
+ The handler is defined as a type of self_handler(wParam,lParam)
56
+ --- ARGINTINTINT
57
+ lParam and wParam are for the arguments, and lParam will be devided into
58
+ two integers of lo-word of lParam and hi-word of lParam.
59
+ The handler is defined as a type of self_handler(wParam,LO_lParam,HI_lParam)
60
+ --- ARGLINTINT
61
+ lParam is for the argument, and lParam will be devided into
62
+ two integers of lo-word of lParam and hi-word of lParam.
63
+ The handler is defined as a type of self_handler(LO_lParam,HI_lParam)
64
+ --- ARGINTSTRUCT
65
+ wParam and structured lParam is for the arguments.
66
+ The handler is defined as a type of self_handler(wParam, ...*struct...)
67
+ --- ARGINTSINTSINT
68
+ Almost same as ARGINTINTINT.
69
+ But that two lParam integers are dealed as signed integers.
70
+ --- ARGPASS
71
+ The argument is an instance of SWin::MSG.
72
+ The handler is define as a type of self_handler(msg).
73
+ =end
74
+
75
+ ARGNONE = 0 #arg none
76
+ ARGINT = 1 #arg lParam
77
+ ARGSTRUCT = 2 #arg lParam as struct
78
+ ARGSTRING = 3 #arg lParam as char*
79
+
80
+ ARGWINT = 8 #arg wParam
81
+ ARGLINT = 9 #arg lParam
82
+ ARGINTINT = 10 #arg wParam,lParam
83
+ ARGINTINTINT=11 #arg wParam,LO(lParam),HI(lParam)
84
+ ARGLINTINT = 12 #arg LO(lParam),HI(lParam)
85
+ ARGINTSTRUCT=13 #arg wParam, lParam as struct
86
+
87
+ ARGINTSINTSINT=14 #arg wParam,SignedLO(lParam),SignedHI(lParam)
88
+ ARGPASS = 16 #arg msg
89
+ end
90
+
91
+ $VRCONTROL_STARTID=1000
92
+
93
+ class VRWinComponent < SWin::Window
94
+ =begin
95
+ == VRWinComponent
96
+ Root of all window class.
97
+ === Methods
98
+ --- hide
99
+ Hides window (this calls SWin::Window#show(0)
100
+ --- winstyle
101
+ Returns an instance of the style utilizing class
102
+ --- exwinstyle
103
+ Returns an instance of the exstyle utilizing class
104
+ =end
105
+
106
+ attr :screen
107
+ attr :parent
108
+
109
+ module VRInitBlocker
110
+ def vrinit
111
+ extend VRInitBlocker.dup
112
+ end
113
+ end
114
+
115
+ def vrinit
116
+ extend VRWinComponent::VRInitBlocker
117
+ end
118
+
119
+ def _init() self.vrinit(); end
120
+
121
+ def setscreen(scr)
122
+ @screen=scr
123
+ end
124
+ def create
125
+ @created=true
126
+ super
127
+ self.vrinit
128
+ _vr_call_created
129
+ self
130
+ end
131
+
132
+ def _vr_call_created
133
+ self_created if respond_to?("self_created")
134
+ end
135
+
136
+ def hide
137
+ self.show 0
138
+ end
139
+
140
+ class Flags
141
+ CONSTMOD=WStyle
142
+
143
+ def initialize(win)
144
+ @win=win
145
+ end
146
+
147
+ def method_missing(msd,*arg)
148
+ msd=msd.to_s
149
+ f_setter = (msd[-1..-1]=="=")
150
+ flgname = if f_setter then msd[0..-2] else msd end.upcase
151
+ flgname.chop! if flgname[-1..-1]=="?"
152
+ mod = self.class::CONSTMOD
153
+ raise "No such flags(#{flgname})" unless mod.const_defined?(flgname)
154
+ flg=mod.const_get(flgname)
155
+ if f_setter then
156
+ setter(flg,arg[0])
157
+ else
158
+ getter(flg)
159
+ end
160
+ end
161
+
162
+ def setter(flagint,value)
163
+ f = integer_getter()
164
+ if value then
165
+ f |= flagint
166
+ else
167
+ f &= ~flagint
168
+ end
169
+ integer_setter(f)
170
+ end
171
+
172
+ def getter(flagint)
173
+ (integer_getter() & flagint)==flagint
174
+ end
175
+
176
+ def value() integer_getter; end
177
+ def value=(f) integer_setter(f); end
178
+ end
179
+
180
+ class WinStyle < Flags
181
+ private
182
+ def integer_getter()
183
+ @win.style
184
+ end
185
+ def integer_setter(f)
186
+ @win.style=f
187
+ end
188
+ end
189
+
190
+ class ExWinStyle < Flags
191
+ CONSTMOD=WExStyle
192
+ private
193
+ def integer_getter
194
+ @win.exstyle
195
+ end
196
+ def integer_setter(f)
197
+ @win.exstyle=f
198
+ end
199
+ end
200
+
201
+
202
+ def winstyle
203
+ WinStyle.new(self)
204
+ end
205
+
206
+ def exwinstyle
207
+ ExWinStyle.new(self)
208
+ end
209
+ end
210
+
211
+ module VRMessageHandler
212
+ =begin
213
+ == VRMessageHandler
214
+ This is a module to handle windows messages.
215
+ If you need to receive windows messages , this module is necessary.
216
+
217
+ === Methods
218
+ --- acceptEvents(ev_array)
219
+ Declares the windows messages to be handled.
220
+ ((|ev_array|)) is an array of the handled messages.
221
+ This method calls SWin::addEvent for each message.
222
+ --- addHandler(msg,handlername,argtype,argparsestr)
223
+ Defines the name and type of the message handler for ((|msg|)).
224
+ The handlername is composed with ((|handlername|)) and the arguments
225
+ are depend on ((|argtype|)) which is a constant in module MSGTYPE.
226
+ When the message come with structured lParam, it is necessary to be defined
227
+ ((|argparsestr|)) to devide it.
228
+ =end
229
+
230
+ PREHANDLERSTR="self_"
231
+
232
+ def msghandlerinit
233
+ @_vr_handlers={} unless defined?(@_vr_handlers)
234
+ self.hookwndproc unless self.hookedwndproc?
235
+
236
+ # for VRMessageParentRelayer
237
+ @_vr_msg_norelays=[] unless defined?(@_vr_msg_norelays)
238
+ end
239
+
240
+ def addNoRelayMessages(arg) # for VRMessageParentRelayer
241
+ @_vr_msg_norelays=[] unless defined?(@_vr_msg_norelays)
242
+ @_vr_msg_norelays += arg if arg and arg.size>0
243
+ end
244
+
245
+ def vrinit
246
+ super
247
+ msghandlerinit
248
+ end
249
+
250
+ def acceptEvents(ev_array)
251
+ ev_array.each do |ev|
252
+ addEvent ev
253
+ end
254
+ end
255
+
256
+ def addHandler(msg,handlername,handlertype,argparsestr)
257
+ @_vr_handlers={} unless defined?(@_vr_handlers)
258
+ @_vr_handlers[msg]=[] unless @_vr_handlers[msg]
259
+ @_vr_handlers[msg].push [
260
+ (PREHANDLERSTR+handlername).intern,handlertype,argparsestr
261
+ ]
262
+ end
263
+
264
+ def deleteHandler(msg,handlername)
265
+ return false unless defined?(@_vr_handlers) and @_vr_handlers[msg]
266
+ @_vr_handlers[msg].delete_if do |shandler|
267
+ shandler[0] == (PREHANDLERSTR+handlername).intern
268
+ end
269
+ end
270
+
271
+ class SKIP_DEFAULTHANDLER
272
+ attr :retval,1
273
+ def initialize(val)
274
+ @retval=val
275
+ end
276
+ def self.[](val=0)
277
+ self.new(val)
278
+ end
279
+ end
280
+
281
+ private
282
+
283
+ def msgarg2handlerarg(handlertype,msg,parsestr)
284
+ case handlertype
285
+ when MSGTYPE::ARGNONE
286
+ []
287
+ when MSGTYPE::ARGINT
288
+ [msg.lParam]
289
+ when MSGTYPE::ARGSTRUCT
290
+ @screen.application.cstruct2array(msg.lParam,parsestr)
291
+ when MSGTYPE::ARGSTRING
292
+ [@screen.application.pointer2string(msg.lParam)]
293
+ when MSGTYPE::ARGWINT
294
+ [msg.wParam]
295
+ when MSGTYPE::ARGLINT
296
+ [msg.lParam]
297
+ when MSGTYPE::ARGINTINT
298
+ [msg.wParam,msg.lParam]
299
+ when MSGTYPE::ARGINTINTINT
300
+ [msg.wParam,LOWORD(msg.lParam),HIWORD(msg.lParam)]
301
+ when MSGTYPE::ARGLINTINT
302
+ [LOWORD(msg.lParam),HIWORD(msg.lParam)]
303
+ when MSGTYPE::ARGINTSTRUCT
304
+ [msg.wParam, @screen.application.cstruct2array(msg.lParam,parsestr)]
305
+ when MSGTYPE::ARGINTSINTSINT
306
+ [msg.wParam,SIGNEDWORD(LOWORD(msg.lParam)),SIGNEDWORD(HIWORD(msg.lParam))]
307
+
308
+ when MSGTYPE::ARGPASS
309
+ [msg]
310
+ else
311
+ raise "Unknown MSGTYPE for #{msg.msg}"
312
+ false
313
+ end
314
+ end
315
+
316
+
317
+ def msghandler(msg)
318
+ r = nil
319
+ if msg.hWnd==self.hWnd then # FormEvent
320
+ if @_vr_handlers then # error occurs if the class is not adaptable.
321
+ @_vr_handlers[msg.msg].each do |shandler|
322
+ args=msgarg2handlerarg(shandler[1],msg,shandler[2])
323
+ if respond_to?(shandler[0])
324
+ r = __send__(shandler[0],*args)
325
+ end
326
+ end
327
+ end
328
+ else # other's WM event
329
+ end
330
+
331
+ # fire default handler?
332
+ if SKIP_DEFAULTHANDLER==r then
333
+ 1
334
+ elsif r.is_a?(SKIP_DEFAULTHANDLER) then
335
+ msg.retval=r.retval
336
+ else
337
+ nil
338
+ end
339
+ end
340
+
341
+ module VRArrayedComponent
342
+ attr :_vr_arrayednumber
343
+ def _vr_arrayednumber=(num)
344
+ if defined?(@_vr_arrayednumber) then
345
+ raise "set array number twice"
346
+ else
347
+ @_vr_arrayednumber=num
348
+ end
349
+ end
350
+ end
351
+
352
+ public
353
+ def controlmsg_dispatching(ct,methodname,*args)
354
+ mthdname = "#{ct.name}_#{methodname}"
355
+ if respond_to?(mthdname)
356
+ if ct.is_a?(VRArrayedComponent) then
357
+ __send__(mthdname,ct._vr_arrayednumber,*args)
358
+ else
359
+ __send__(mthdname,*args)
360
+ end
361
+ else
362
+ 0
363
+ end
364
+ end
365
+
366
+ def selfmsg_dispatching(methodname,*args)
367
+ smethod="self_#{methodname}".intern
368
+ if respond_to?(smethod) then
369
+ __send__(smethod,*args)
370
+ else
371
+ nil
372
+ end
373
+ end
374
+
375
+ end
376
+
377
+ module VRMessageParentRelayer
378
+ include VRMessageHandler
379
+
380
+ def messageparentrelayerinit
381
+ @_vr_messageparentrelayer=true
382
+ end
383
+
384
+
385
+ def vrinit
386
+ super
387
+ messageparentrelayerinit
388
+ end
389
+
390
+ def controlmsg_dispatching(ct,methodname,*args)
391
+ mthdname = "#{ct.name}_#{methodname}"
392
+ @parent.controlmsg_dispatching(self,mthdname,*args)
393
+ end
394
+
395
+ def selfmsg_dispatching(methodname,*args)
396
+ @parent.controlmsg_dispatching(self,methodname,*args)
397
+ end
398
+
399
+ def msghandler(msg) # almost same as VRMessageHandler#msghandler
400
+ if @_vr_msg_norelays.include?(msg.msg) then # no relays
401
+ return super
402
+ end
403
+
404
+ r = nil
405
+ if msg.hWnd==self.hWnd then # FormEvent
406
+ if @_vr_handlers then # error occurs if the class is not adaptable.
407
+ @_vr_handlers[msg.msg].each do |shandler|
408
+ args=msgarg2handlerarg(shandler[1],msg,shandler[2])
409
+ mthdname = "#{@name}_#{shandler[0]}"
410
+ if @parent.respond_to?(mthdname)
411
+ r = @parent.__send__(mthdname,*args)
412
+ end
413
+ end
414
+ end
415
+ else # other's WM event
416
+ end
417
+
418
+ # fire default handler?
419
+ if SKIP_DEFAULTHANDLER==r then
420
+ 1
421
+ elsif r.is_a?(SKIP_DEFAULTHANDLER) then
422
+ msg.retval=r.retval
423
+ else
424
+ nil
425
+ end
426
+ end
427
+ end
428
+
429
+
430
+ module VRParent
431
+ =begin
432
+ == VRParent
433
+ This module provides the features to be the parent of the child windows.
434
+
435
+ === Constants
436
+ --- DEFAULT_FONT
437
+ Each control created by addControl method is invoked setFont(font) method.
438
+ Default font of child controls can be set with this constants in the class.
439
+
440
+ === Method
441
+ --- addControl(ctype,name,caption, x=0,y=0,w=10,h=10, style=0)
442
+ Adds a child window(control) of ((|ctype|)) named ((|name|))
443
+ with ((|caption|)) at ( ((|x|)) , ((|y|)) ) whose width and height is
444
+ ( ((|w|)) , ((|h|)) ).
445
+ ((|ctype|)) is not an instance of the control-class but the class of
446
+ the child window.
447
+ ((|style|)) is additional styles for the childwindow such as WMsg::WS_BORDER.
448
+ You can set nil or "" for ((|name|)). "" is for nameless control,
449
+ and nil is for the control which is nothing to do with vruby's control
450
+ management.
451
+ --- addArrayedControl(index,ctype,name,caption,x=0,y=0,w=10,h=10,style=0)
452
+ Adds an indexed child window(control) of ((|ctype|)) named ((|name|)).
453
+ --- countControls
454
+ Returns the number of controls added on the window.
455
+ --- deleteControls(cntl)
456
+ Deletes a control ((|cntl|)) as VRControl.
457
+ --- clearControls
458
+ Deletes all controls on the window.
459
+ --- send_parent(cname,func)
460
+ Sends to parent an event from control. ((|cname|)) is controlname and
461
+ ((|func|)) is event handler name.
462
+ === Callback Methods(event handler)
463
+ --- construct
464
+ You can add controls and set menues for the window in this method.
465
+
466
+ === Event handlers
467
+ --- self_created
468
+ Fired when all of child windows is created.
469
+ =end
470
+
471
+ DEFAULT_FONT=nil
472
+
473
+ attr :screen
474
+
475
+ def newControlID
476
+ r=@_vr_cid + $VRCONTROL_STARTID
477
+ @_vr_cid+=1
478
+ return r
479
+ end
480
+
481
+ def registerControl(c,name,cid)
482
+ c.etc= cid
483
+ if name.is_a?(String) then
484
+ if name.length>0 then
485
+ atname = instance_eval("@" + name + " ||= nil")
486
+ raise "Already used name '#{name}'" unless atname.nil?
487
+ begin
488
+ instance_eval("@"+name+"=c") if name
489
+ rescue
490
+ end
491
+ end
492
+ c.name = name
493
+ @controls[cid]= c
494
+ end
495
+ c
496
+ end
497
+
498
+ def registerControlAsArrayed(num,c,name,cid)
499
+ instance_eval("@#{name}=[] unless defined? @#{name}")
500
+ if instance_eval("@#{name}[#{num}]")
501
+ raise "Already used number #{num} for #{name}"
502
+ end
503
+ begin
504
+ instance_eval("@#{name}")[num]=c
505
+ rescue
506
+ end
507
+ c.name=name
508
+ c.extend VRMessageHandler::VRArrayedComponent
509
+ c._vr_arrayednumber=num
510
+ c
511
+ end
512
+
513
+ def _vr_call_created() # to move the timing of self_created
514
+ construct
515
+ super
516
+ end
517
+
518
+ def parentinit(screen)
519
+ @screen=screen
520
+ @controls={}
521
+ @_vr_cid=0
522
+ end
523
+
524
+ def createControl(type,name,caption, x=0,y=0,w=10,h=10, style=0)
525
+ c=@screen.factory.newwindow(self,type)
526
+ # c.extend type
527
+ info = type.Controltype
528
+ c.classname= info[0] if info[0]
529
+ c.caption= caption
530
+ c.style=WStyle::WS_VISIBLECHILD | info[1] | style
531
+ c.exstyle = info[2] if info.size>2
532
+ c.move x,y,w,h
533
+ c
534
+ end
535
+
536
+ VR_ADDCONTROL_FEWARGS=false
537
+ def addControl(type,name,caption, x=10,y=10,w=10,h=10, style=0)
538
+ c = createControl(type,name,caption, x,y,w,h,style)
539
+ cid=newControlID
540
+ registerControl(c,name,cid)
541
+ c.parent=self
542
+ c.setscreen(screen)
543
+ c.parentinit(screen) if c.respond_to?("parentinit")
544
+ c.create
545
+ font = self.class::DEFAULT_FONT
546
+ c.setFont(font) if font.is_a?(SWin::Font)
547
+ c
548
+ end
549
+
550
+ def addArrayedControl(num,type,name,caption,x=0,y=0,w=10,h=10,style=0)
551
+ #p method(:addControl).arity
552
+ if self.class::VR_ADDCONTROL_FEWARGS then
553
+ c = addControl(type,"",caption,style)
554
+ else
555
+ c = addControl(type,"",caption,x,y,w,h,style)
556
+ end
557
+ registerControlAsArrayed(num,c,name,c.etc)
558
+ c
559
+ end
560
+
561
+ alias vr_addControlOriginal addControl
562
+
563
+ def countControls
564
+ @controls.size
565
+ end
566
+
567
+ def deleteControl(cntl)
568
+ if cntl.is_a?(VRMessageHandler::VRArrayedComponent)
569
+ if @controls[cntl.etc]==instance_eval("@#{cntl.name}")[cntl._vr_arrayednumber] then
570
+ instance_eval("@#{cntl.name}")[cntl._vr_arrayednumber]=nil
571
+ end
572
+ else
573
+ if @controls[cntl.etc]==instance_eval("@#{cntl.name}") then
574
+ instance_eval("@#{cntl.name}=nil")
575
+ end
576
+ end
577
+
578
+ @controls.delete(cntl.etc)
579
+ cntl.close if cntl.alive?
580
+ end
581
+
582
+ def clearControls
583
+ @controls.each do |key,cntl|
584
+ deleteControl(cntl)
585
+ end
586
+ @_vr_cid=0
587
+ end
588
+
589
+ def send_parent(cname,func)
590
+ defname=cname+"_"+func
591
+ funcname = self.name + "_" + defname
592
+ evalstr=
593
+ "def "+defname+"(*arg) " <<
594
+ "if parent.respond_to?('"+funcname+"') then " <<
595
+ "parent.__send__('"+funcname+"',*arg) " <<
596
+ "end " <<
597
+ "end"
598
+ instance_eval(evalstr)
599
+ end
600
+
601
+ # ###########################
602
+ #
603
+
604
+ def construct
605
+ # placeholder
606
+ end
607
+
608
+ end
609
+
610
+ module WMsg
611
+ WM_SETFONT = 0x0030
612
+ WM_GETFONT = 0x0031
613
+ end
614
+ class VRControl < VRWinComponent
615
+ =begin
616
+ == VRControl
617
+ Base class for controls.
618
+
619
+ === Methods
620
+ --- add_parentcall(funcname)
621
+ Makes event handlers to be passed through to its parent window.
622
+ For example, add_parentcall("btn1_clicked") provides a new event
623
+ ((| ????_btn1_clicked |)) on its parent window.
624
+ (???? is the name of the control).
625
+ --- call_parenthandler(handlername,*arg)
626
+ Calls event handler of parent window in ctrlname_handlername(*arg) style.
627
+ --- setFont(font,redraw=true)
628
+ Sets drawing font to ((|font|)). Control will be re-drawn if redraw flag.
629
+
630
+ =end
631
+
632
+ attr :handlers
633
+ attr :parent,1
634
+ attr :name,1
635
+
636
+ WINCLASSINFO = [nil,0]
637
+
638
+ def self.Controltype()
639
+ self::WINCLASSINFO
640
+ end
641
+
642
+ def add_parentcall(func)
643
+ funcname=@name+"_"+func
644
+ evalstr=
645
+ "def self_"+func+"(*arg) "+
646
+ "if parent.respond_to?('"+funcname+"') then "+
647
+ "parent.__send__('"+funcname+"',*arg) "+
648
+ "end "+
649
+ "end"
650
+ instance_eval(evalstr)
651
+ end
652
+
653
+ def setFont(font,redraw=true)
654
+ if self.dopaint then
655
+ super font
656
+ end
657
+ if font.is_a?(SWin::Font) then
658
+ self.properties["font"]=font
659
+ sendMessage WMsg::WM_SETFONT,font.hfont, ( (redraw)? 1 : 0 )
660
+ else
661
+ raise "#{font} is not a font."
662
+ end
663
+ end
664
+
665
+ def call_parenthandler(handlername,*arg)
666
+ @parent.controlmsg_dispatching(self,handlername,*arg)
667
+ end
668
+ end
669
+
670
+ module VRCommonDialog
671
+ =begin
672
+ == VRCommonDialog
673
+ Additional module for common dialogs.
674
+ You can omit the first argument of the method of SWin::CommonDialog
675
+ using this module.
676
+
677
+ === Methods
678
+ --- openFilenameDialog(*arg)
679
+ --- saveFilenameDialog(*arg)
680
+ --- chooseColorDialog(*arg)
681
+ --- chooseFontDialog(*arg)
682
+ --- selectDirectory(*arg)
683
+ =end
684
+
685
+ def openFilenameDialog(*arg)
686
+ SWin::CommonDialog::openFilename(self, *arg)
687
+ end
688
+ def saveFilenameDialog(*arg)
689
+ SWin::CommonDialog::saveFilename(self, *arg)
690
+ end
691
+ def chooseColorDialog(*arg)
692
+ SWin::CommonDialog::chooseColor(self, *arg)
693
+ end
694
+
695
+ DEFAULTFONT = [["System",19,0,300,135,0,0,2,128],135,0]
696
+ def chooseFontDialog(defaultvalue=nil)
697
+ sarg = if defaultvalue.is_a?(FontStruct) then
698
+ sarg = defaultvalue.spec
699
+ elsif defaultvalue
700
+ sarg = defaultvalue
701
+ else
702
+ sarg = DEFAULTFONT
703
+ end
704
+ r=SWin::CommonDialog::chooseFont(self, sarg)
705
+ if r then
706
+ FontStruct.new2(r)
707
+ else
708
+ r
709
+ end
710
+ end
711
+
712
+ def selectDirectory(*arg)
713
+ SWin::CommonDialog::selectDirectory self,*arg
714
+ end
715
+ end
716
+
717
+
718
+ class VRForm < VRWinComponent
719
+ =begin
720
+ == VRForm
721
+ This class is for top-level window and have the features of
722
+ ((<VRMessageHandler>)), ((<VRParent>)) and ((<VRCommonDialog>))
723
+
724
+ === Method
725
+ --- create
726
+ Creates the window.
727
+ =end
728
+
729
+ attr :handlers
730
+ VR_WINCLASS = nil
731
+
732
+ def self.winclass() nil end
733
+
734
+ include VRMessageHandler
735
+ include VRParent
736
+ include VRCommonDialog
737
+
738
+ # def create
739
+ # super
740
+ # self.vrinit
741
+ # self
742
+ # end
743
+
744
+
745
+ def forminit(screen,parent)
746
+ @_vr_handlers={}
747
+ parentinit(screen)
748
+ @parent=parent
749
+ end
750
+
751
+ end
752
+
753
+ class VRPanel < VRControl
754
+ =begin
755
+ == VRPanel
756
+ This means only child window that is useable like control.
757
+ =end
758
+
759
+ include VRParent
760
+ WINCLASSINFO = [nil,0]
761
+ end
762
+
763
+ module VRContainersSet
764
+ INITIALIZERS=[]
765
+ def containers_init
766
+ INITIALIZERS.each do |mtd|
767
+ self.__send__(mtd)
768
+ end
769
+ end
770
+ end
771
+
772
+
773
+ module VRDrawable
774
+ =begin
775
+ == VRDrawable
776
+ This module is for handling WM_PAINT message to paint the window.
777
+
778
+ === Event handler
779
+ --- self_paint
780
+ Fired when the window is required to re-paint by the system.
781
+ You can use GDI's methods of SWin::Window in this method.
782
+ =end
783
+
784
+ include VRMessageHandler
785
+ def drawableinit
786
+ addHandler(WMsg::WM_PAINT,"paint",MSGTYPE::ARGNONE,nil)
787
+ addEvent WMsg::WM_PAINT
788
+ end
789
+ def vrinit
790
+ super
791
+ drawableinit
792
+ end
793
+ end
794
+
795
+
796
+
797
+ module VRResizeSensitive
798
+ =begin
799
+ == VRResizeSensitive
800
+ This module is for capturing window resizing.
801
+
802
+ === Event handler
803
+ --- self_resize(w,h)
804
+ Fired when the window is resized.
805
+ The new width and height is ((|w|)) and ((|h|)).
806
+ =end
807
+
808
+ include VRMessageHandler
809
+
810
+ def resizeableinit
811
+ acceptEvents [ WMsg::WM_SIZE ]
812
+ addHandler(WMsg::WM_SIZE, "resize",MSGTYPE::ARGLINTINT,nil)
813
+ end
814
+ def vrinit
815
+ super
816
+ resizeableinit
817
+ end
818
+ end
819
+
820
+ VRResizeable = VRResizeSensitive
821
+
822
+ module VRUserMessageUseable
823
+ module ReservedMsg
824
+ WM_VR_OLEDND = 1
825
+ WM_VR_TRAYNOTIFY = 2
826
+ end
827
+
828
+ =begin
829
+ == VRUserMessageUseable
830
+ This module is for using user-defined Windows-system messages.
831
+
832
+ --- registerUserMessage(messageid,eventname,offset=0x100)
833
+ Registers an user-defined message whose eventname is ((|eventname|)).
834
+ On your Windows system, this message is assigned for
835
+ (WM_APP + messageid + offset).
836
+ Argument ((|offset|)) is only for vruby system use. Don't use it.
837
+
838
+ === EventHandler
839
+ --- self_<userdefinedname>(wparam,lparam)
840
+ Fired when the user-defined message is sent.
841
+ =end
842
+
843
+ include VRMessageHandler
844
+
845
+ def usermessageuseableinit
846
+ @_vr_usermessages={}
847
+ end
848
+ def vrinit
849
+ super
850
+ usermessageuseableinit
851
+ end
852
+
853
+ def registerUserMessage(messageid,eventname,offset=0x100)
854
+ msg = WMsg::WM_APP+messageid+offset
855
+ addEvent msg
856
+ addHandler(msg, eventname,MSGTYPE::ARGINTINT,nil)
857
+ @_vr_usermessages[eventname]=msg
858
+ end
859
+
860
+ def userMessage(eventname,wparam=0,lparam=0)
861
+ msg = @_vr_usermessages[eventname]
862
+ raise "No such an usermessage (#{eventname}" unless msg
863
+ postMessage msg,wparam.to_i,lparam.to_i
864
+ end
865
+
866
+ end
867
+
868
+ class VRScreen
869
+ =begin
870
+ == VRScreen
871
+ This class expresses the desktop screen.
872
+ Currently only ((<VRLocalScreen>)) defined in vruby, the instance of this
873
+ class, is available.
874
+
875
+ === Class Method
876
+ --- new(app,factory)
877
+ ((|app|)) as SWin::Application and ((|factory|)) as SWin::Factory.
878
+
879
+ === Methods
880
+ --- newform(parent=nil,style=nil,mod=VRForm)
881
+ Creates and initializes the top-level window which is the instance of
882
+ ((<VRForm>)) or its descendant.
883
+ The parent window is specified by ((|parent|)) and parent==nil means
884
+ that it has no parent window.
885
+ The window style is specified by ((|style|)) which can be ((|nil|)) for
886
+ default style.
887
+ ((|mod|)) can be a module which is to be added to ((<VRForm>)) or a class
888
+ which is a descendant of ((<VRForm>)).
889
+ --- showForm(mod,x,y,w,h)
890
+ Creates and shows the new top-level window using ((<newform>)).
891
+ The arguments ((|x|)),((|y|)),((|w|)),((|h|)) is omittable.
892
+ ((|mod|)) is the argument for ((<newform>))'s argument.
893
+ --- addIdleproc(f)
894
+ Adds a idling process executed while message loop runs.
895
+ ((|f|)) is an instance of Proc class.
896
+ --- messageloop(wflag=false)
897
+ Get into the system message loop. You need to call this method to
898
+ process windows messages.
899
+ While wflag is true, messageloop waits a message by WaitMessage() API.
900
+ This waiting will prevent other threads' processes and can suppress CPU load
901
+ average.
902
+ If wflag==false and your ruby's version is so high that Thread has 'list'
903
+ class-method, WaitMessage() API is used automatically by the case.
904
+ --- idling_messageloop
905
+ ((*obsolete*))
906
+ Almost same as ((<messageloop>)). The difference is that this method
907
+ yields when the messageloop is in idle state. You need to use this
908
+ method in iterator's style.
909
+ --- width
910
+ Width of the desktop.
911
+ --- height
912
+ Height of the desktop.
913
+ --- newFormClass(name,brush=nil,style=nil,icon=nil,cursor=nil)
914
+ Register a new window class to the system.
915
+ This method returns a form class with specified icon, color, cursor
916
+ and default window style.
917
+ =end
918
+
919
+ attr :screen
920
+ attr :application
921
+ attr :factory
922
+ attr :desktop
923
+ attr :idle_sleep_timer,1
924
+
925
+ WINDOWCHECK_INTERVAL=3
926
+
927
+ def initialize(frame,factory)
928
+ @application=frame
929
+ @factory=factory
930
+ @desktop=@application.getDesktop
931
+ @idle_sleep_timer = 0.01
932
+ @_vr_box=[] # pushed windows for avoiding destruction by GC
933
+ end
934
+
935
+ def newform(parent=nil,style=nil,mod=VRForm) # create top-level window
936
+ if mod.is_a?(Class) then
937
+ if mod.ancestors.index(VRForm) then
938
+ frm=@factory.newwindow(parent,mod)
939
+ else
940
+ raise "#{mod} is not a window class"
941
+ end
942
+ elsif mod.is_a?(Module) then
943
+ frm=@factory.newwindow(parent,VRForm)
944
+ frm.extend mod
945
+ else
946
+ raise ArgumentError,"required a child class of VRForm or a Module extending VRForm"
947
+ end
948
+ frm.style= style if style
949
+ frm.classname = frm.class.winclass if frm.class.winclass
950
+ frm.extend VRContainersSet
951
+ frm.forminit(self,parent)
952
+ frm
953
+ end
954
+
955
+ def showForm(formmodule,*rect)
956
+ if rect.is_a?(Array) and rect.size>3 then
957
+ x,y,w,h = *rect
958
+ end
959
+
960
+ frm=newform(nil,nil,formmodule)
961
+ frm.move x,y,w,h if x
962
+ frm.create.show
963
+ @_vr_box.push frm
964
+ frm
965
+ end
966
+
967
+ def start(*args)
968
+ showForm(*args)
969
+ messageloop
970
+ end
971
+
972
+ def addIdleproc(f)
973
+ @idleprocs=[] unless defined?(@idleprocs)
974
+ @idleprocs.push f
975
+ end
976
+
977
+ def messageloop(waitflag=false)
978
+ @idleprocs=[] unless defined?(@idleprocs)
979
+
980
+ =begin commented out for activex support
981
+ cth =Thread.new do
982
+ while true do
983
+ @_vr_box.reject! do |w| (! w.alive?); end
984
+ sleep WINDOWCHECK_INTERVAL
985
+ end
986
+ end
987
+ =end
988
+
989
+ @application.messageloop do
990
+ n=@idleprocs.shift
991
+ if n then
992
+ Thread.new do
993
+ n.call
994
+ end
995
+ else
996
+ if waitflag then
997
+ @application.waitmessage
998
+ else
999
+ # Thread.pass
1000
+ sleep(@idle_sleep_timer)
1001
+ end
1002
+ end
1003
+ end
1004
+ end
1005
+
1006
+ def idling_messageloop # obsolete
1007
+ @application.messageloop do |q|
1008
+ yield q
1009
+ end
1010
+ end
1011
+
1012
+ def newFormClass(name,brush=nil,style=nil,icon=nil,cursor=nil)
1013
+ hicon = case(icon)
1014
+ when Integer
1015
+ icon
1016
+ when SWin::Icon
1017
+ icon.hicon
1018
+ else
1019
+ nil
1020
+ end
1021
+
1022
+ sw = factory.registerWinClass(name.to_s,brush,style,hicon,cursor)
1023
+ raise "register class failed" unless sw
1024
+ a = Class.new(VRForm)
1025
+ a.class_eval(<<EEOOFF)
1026
+ VR_WINCLASS="#{sw}"
1027
+ def self.winclass() VR_WINCLASS end
1028
+ EEOOFF
1029
+ a
1030
+ end
1031
+
1032
+ def width
1033
+ @desktop.w
1034
+ end
1035
+ def height
1036
+ @desktop.h
1037
+ end
1038
+ alias w :width
1039
+ alias h :height
1040
+ def x() @desktop.x; end
1041
+ def y() @desktop.y; end
1042
+
1043
+ end
1044
+
1045
+ VRLocalScreen=
1046
+ VRScreen.new(SWin::Application,
1047
+ SWin::LWFactory.new(SWin::Application.hInstance))
1048
+
1049
+ # contributed files
1050
+ require VR_DIR+'contrib/vrwincomponent'
1051
+