vruby 2004.08.07

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