vruby 2004.08.07

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.
@@ -0,0 +1,191 @@
1
+ ###################################
2
+ #
3
+ # vrddrop.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
+ VR_DIR="vr/" unless defined?(::VR_DIR)
13
+ require VR_DIR+'vruby'
14
+ require VR_DIR+'sysmod'
15
+ require VR_DIR+'dragdropformat'
16
+ require 'Win32API'
17
+
18
+
19
+ module VRDropFileTarget
20
+ =begin
21
+ == VRDropFileTarget
22
+ This module prepares the feature that accepts file dropping.
23
+
24
+ === Event handler(s)
25
+ --- self_dropfiles(files)
26
+ Argument ((|files|)) is the array of dropped filenames.
27
+ =end
28
+
29
+ include VRMessageHandler
30
+
31
+ DragAcceptFiles = Win32API.new("shell32","DragAcceptFiles",["I","I"],"")
32
+ DragFinish = Win32API.new("shell32","DragFinish",["I"],"")
33
+
34
+ def filedropinit
35
+ addHandler(WMsg::WM_DROPFILES,"vrdropfiles",MSGTYPE::ARGWINT,nil)
36
+ addEvent WMsg::WM_DROPFILES
37
+ addNoRelayMessages [WMsg::WM_DROPFILES]
38
+ DragAcceptFiles.call(self.hWnd,1)
39
+ end
40
+
41
+ def vrinit
42
+ super
43
+ filedropinit
44
+ end
45
+
46
+ def self_vrdropfiles(handle)
47
+ r = DragDropFiles.get(handle).files
48
+ DragFinish.call(handle)
49
+ selfmsg_dispatching("dropfiles",r)
50
+ # self_dropfiles(r) if self.respond_to?("self_dropfiles")
51
+ end
52
+ end
53
+
54
+
55
+ module VRDragDropSource
56
+ =begin
57
+ == VRDragDropSource
58
+ This module is a base module for dragdrop source. Note that this module uses
59
+ message posting to realize drag and drop instead of using OLE Drag&Drop.
60
+ To use this module, see VRDragFileSource module.
61
+ This module needs a callback function createDropItem, which is called
62
+ when the user releases a mouse button to drop.
63
+
64
+ === Methods
65
+ --- dragDetect()
66
+ Determines by the user's input whether the user is doing dragging or not.
67
+ --- dragStart()
68
+ Starts dragging.
69
+ --- createDropItem()
70
+ This is a callback method to calculate the dropping item. This needs to
71
+ return three values message,wParam and lParam to send to the dropped window.
72
+ The dropped window will receive the message by Windows messaging service.
73
+
74
+ === Attributes
75
+ --- dropToplevel
76
+ While this is true, the message is sent to the toplevel window under the
77
+ cursor, and in the other case the message is sent to the window just
78
+ under the cursor.
79
+
80
+ =end
81
+
82
+ include VRMessageHandler
83
+
84
+ DragDetect = Win32API.new("user32","DragDetect","IP","I")
85
+ GetCursorPos = Win32API.new("user32","GetCursorPos","P","I")
86
+ WindowFromPoint = Win32API.new("user32","WindowFromPoint","II","I")
87
+ GetParent=Win32API.new("user32","GetParent","I","I")
88
+
89
+ def dragdropsourceinit
90
+ @_vr_dragging=false
91
+ @_vr_droptotoplevel=true;
92
+ @_vr_pointbuffer=[0,0].pack("II")
93
+ unless @_vr_dragging_cursor then
94
+ @_vr_dragging_cursor=@screen.application::SysCursors.Cross
95
+ end
96
+ addHandler(WMsg::WM_LBUTTONUP,"_vrdsrclbuttonup",MSGTYPE::ARGINTINT,nil)
97
+ acceptEvents [WMsg::WM_LBUTTONUP]
98
+ end
99
+
100
+ def vrinit
101
+ super
102
+ dragdropsourceinit
103
+ end
104
+
105
+ def dropToplevel() @_vr_droptotoplevel; end
106
+ def dropToplevel=(f) @_vr_droptotoplevel=f;end
107
+
108
+ def dragDetect
109
+ DragDetect.call(self.hWnd,@_vr_pointbuffer)!=0
110
+ end
111
+
112
+ def dragStart()
113
+ GetCursorPos.call(@_vr_pointbuffer)
114
+ if DragDetect.call(self.hWnd,@_vr_pointbuffer)!=0 then
115
+ @_vr_dragging=true
116
+ @screen.application.setCursor @_vr_dragging_cursor
117
+ setCapture
118
+ end
119
+ end
120
+
121
+ def createDropItem()
122
+ # msg,wParam,lParam
123
+ return nil,nil,nil
124
+ end
125
+
126
+ def self__vrdsrclbuttonup(shift,xy)
127
+ if @_vr_dragging then
128
+ @screen.application.setCursor @screen.application::SysCursors.Arrow
129
+ GetCursorPos.call(@_vr_pointbuffer)
130
+ handle=WindowFromPoint.call(*@_vr_pointbuffer.unpack("II"))
131
+ releaseCapture
132
+
133
+ if @_vr_droptotoplevel then
134
+ while handle!=0 do # search the top level window
135
+ droptarget=handle; handle=GetParent.call(handle)
136
+ end
137
+ else
138
+ droptarget=handle;
139
+ end
140
+
141
+ msg,wParam,lParam = self.createDropItem
142
+ SMSG::postMessage droptarget,msg,wParam,lParam
143
+ end
144
+ @_vr_dragging=false
145
+ end
146
+ end
147
+
148
+ module VRDragFileSource
149
+ include VRDragDropSource
150
+ =begin
151
+ == VRDragFileSource
152
+ This module prepares the feature to start dragging files.
153
+ This is the result of quick-hacking. Are you so kind that teach me
154
+ the structure of "internal structure describing the dropped files?"
155
+
156
+ === Event handler(s)
157
+ --- dragStart(files)
158
+ Starts file dragging with ((|files|)) that is an Array including
159
+ the filenames to be dragged.
160
+ =end
161
+
162
+ def dragStart(paths)
163
+ @_vr_dragpaths=paths
164
+ super()
165
+ end
166
+
167
+ def createDropItem
168
+ hDrop = DragDropFiles.set(@_vr_dragpaths).handle
169
+ return WMsg::WM_DROPFILES, hDrop, 0
170
+ end
171
+ end
172
+
173
+ =begin VRDragFileSource sample
174
+ require 'vr/vrcontrol'
175
+ require 'vr/vrhandler'
176
+ require 'vr/vrddrop'
177
+
178
+ class MyForm < VRForm
179
+ include VRDragFileSource
180
+ include VRMouseFeasible
181
+
182
+ def self_lbuttondown(shift,x,y)
183
+ if dragDetect then
184
+ dragStart ['c:\autoexec.bat','c:\config.sys']
185
+ end
186
+ end
187
+ end
188
+
189
+ VRLocalScreen.start(MyForm)
190
+ =end
191
+
@@ -0,0 +1,403 @@
1
+ ###################################
2
+ #
3
+ # vrdialog.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) Dialog boxes
14
+ =end
15
+
16
+
17
+ VR_DIR="vr/" unless defined?(::VR_DIR)
18
+ require VR_DIR+'vruby'
19
+ require VR_DIR+'vrcontrol'
20
+
21
+ class VRDialogTemplate
22
+ =begin
23
+ == VRDialogTemplate
24
+ Create Dialog template string for the argument of
25
+ DialogBoxIndirectParam() Win32API.
26
+
27
+ === Attributes
28
+ ((|style|)),((|exstyle|)),((|caption|)),((|fontsize|)),((|fontname|)) are
29
+ read/write accessible.
30
+ ((|x|)),((|y|)),((|w|)),((|h|)) are read-only and access these attributes
31
+ with 'move' method.
32
+
33
+ === Methods
34
+ --- move(x,y,w,h)
35
+ Sets the dialog dimension and position. The position is relative from
36
+ parent window.
37
+ --- addDlgControl(ctype,caption,x,y,w,h,style=0)
38
+ Adds a control on the dialog. ((|ctype|)) is the control-class such as
39
+ VRButton.
40
+ --- to_template
41
+ Create a dialog template string and return it.
42
+ =end
43
+
44
+ attr_accessor :style
45
+ attr_accessor :exstyle
46
+ attr_reader :x
47
+ attr_reader :y
48
+ attr_reader :w
49
+ attr_reader :h
50
+ attr_accessor :caption
51
+ attr_accessor :fontsize
52
+ attr_accessor :fontname
53
+
54
+ require 'Win32API'
55
+ MultiByteToWideChar =
56
+ Win32API.new("kernel32","MultiByteToWideChar",["I","I","P","I","P","I"],"I")
57
+
58
+ private
59
+ def padding_dwordAlignment(str)
60
+ a=str.length
61
+ c = ( (a+3)&0xfffc ) - a # Don't use String whose length is over 0xfffc :)
62
+ str << " "*c
63
+ end
64
+
65
+ def mb2wc(str)
66
+ r=" "*(str.length*2)
67
+ l=MultiByteToWideChar.call(0,0,str,str.length,r,r.length)
68
+ r
69
+ end
70
+
71
+ def class2param(cls)
72
+ if cls == VRButton then
73
+ [0xffff,0x80].pack("SS")
74
+ elsif cls == VREdit || cls == VRText
75
+ [0xffff,0x81].pack("SS")
76
+ elsif cls == VRStatic
77
+ [0xffff,0x82].pack("SS")
78
+ elsif cls == VRListbox
79
+ [0xffff,0x83].pack("SS")
80
+ elsif cls == VRScrollbar
81
+ [0xffff,0x84].pack("SS")
82
+ elsif cls == VRCombobox
83
+ [0xffff,0x85].pack("SS")
84
+ else
85
+ mb2wc(cls.Controltype[0]+"\0")
86
+ end
87
+ end
88
+
89
+ def tmplateinit
90
+ @_vr_dcontrols={}; @_vr_cid=0;
91
+ @style = 0x90c800c0
92
+ @exstyle=0
93
+ self.move 100,100,200,100
94
+ @caption=""
95
+ @fontname="system"
96
+ @fontsize=10
97
+ end
98
+
99
+ def initialize
100
+ tmplateinit
101
+ end
102
+
103
+ public
104
+ def move(x,y,w,h)
105
+ @x,@y,@w,@h = x,y,w,h
106
+ end
107
+
108
+ def addDlgControl(ctype,caption,x,y,w,h,style=0)
109
+ newid = @_vr_cid + $VRCONTROL_STARTID*2
110
+ @_vr_dcontrols[newid] =
111
+ [ctype,"",caption,x,y,w,h,
112
+ ctype.Controltype[1] | style | 0x50000000] #WS_VISIBLECHILD
113
+ @_vr_cid+=1
114
+ return newid
115
+ end
116
+
117
+
118
+ def to_template
119
+ tmp =
120
+ [
121
+ @style,@exstyle,@_vr_dcontrols.size,@x,@y,@w,@h,0,0
122
+ ] .pack("LISSSSSSS") + mb2wc(@caption+"\0")
123
+
124
+ if (@style & 0x40)>0 then # DS_SETFONT
125
+ tmp << [@fontsize].pack("S") << mb2wc(@fontname+"\0")
126
+ end
127
+ padding_dwordAlignment(tmp)
128
+
129
+ @_vr_dcontrols.each do |iid,val|
130
+ tmp << [val[7],0,val[3,4],iid].flatten.pack("IISSSSS")
131
+ tmp << class2param(val[0])
132
+ tmp << mb2wc(val[2]+"\0") << [0].pack("S")
133
+ padding_dwordAlignment(tmp)
134
+ end
135
+ return tmp
136
+ end
137
+ end
138
+
139
+
140
+ module WMsg
141
+ WM_INITDIALOG = 0x110
142
+ end
143
+
144
+ class VRDialogComponent < SWin::Dialog
145
+ =begin
146
+ == VRDialogComponent
147
+ This class represents modal/modeless dialogs.
148
+ --- setButtonAs(button,dlgbuttonid)
149
+ Set the button as dialog's functional button like IDOK, IDCANCEL and so on.
150
+ ((|button|)) must be a VRButton and dlgbuttonid must be between IDOK and IDHELP
151
+ --- centering
152
+ set the dialog at the center of the parent window.
153
+ =end
154
+
155
+ include VRParent
156
+
157
+ IDOK = 1
158
+ IDCANCEL = 2
159
+ IDABORT = 3
160
+ IDRETRY = 4
161
+ IDIGNORE = 5
162
+ IDYES = 6
163
+ IDNO = 7
164
+ IDCLOSE = 8
165
+ IDHELP = DLGMAX_ID = 9
166
+
167
+ attr :options,1 #hash
168
+
169
+ def vrinit
170
+ extend VRWinComponent::VRInitBlocker
171
+ end
172
+
173
+ def setscreen(scr)
174
+ @screen=scr
175
+ end
176
+ def create(*arg)
177
+ self.open(*arg)
178
+ end
179
+
180
+ def setButtonAs(control, newid) #contributed by Katonbo-san.
181
+ if newid > DLGMAX_ID then
182
+ raise "id[#{newid}] is too big"
183
+ end
184
+ id = control.etc
185
+ @controls[newid] = @controls[id]
186
+ # control.etc = newid
187
+ # @controls.delete(id)
188
+ end
189
+
190
+ def centering(target = @parent) #contributed by Yuya-san./modified by nyasu.
191
+ unless target.is_a?(SWin::Window) then
192
+ target = @screen
193
+ end
194
+ raise "No specified centering target" unless target
195
+
196
+ x = target.x + target.w / 2 - self.w / 2
197
+ y = target.y + target.h / 2 - self.h / 2
198
+ self.move(x, y, self.w, self.h)
199
+ end
200
+
201
+ def initialize(*arg)
202
+ @options={}
203
+ end
204
+
205
+ def self.new(screen,template) # obsolete
206
+ r=screen.factory.newdialog(template.to_template,self)
207
+ r.parentinit(screen)
208
+ r.options={}
209
+ r.addEvent WMsg::WM_INITDIALOG
210
+ r.addEvent WMsg::WM_COMMAND
211
+ return r
212
+ end
213
+
214
+ def self.new2(screen) # obsolete
215
+ template = VRDialogTemplate.new
216
+ opt={}
217
+ yield(opt,template)
218
+ r=self.new(screen,template)
219
+ r.options=opt if opt.is_a?(Hash)
220
+ return r
221
+ end
222
+
223
+ module VRInitDialogHandler
224
+ def vrinit
225
+ if self.kind_of?(VRMessageHandler) then
226
+ addHandler WMsg::WM_INITDIALOG,"initdialog",MSGTYPE::ARGINTINT,nil
227
+ end
228
+ super
229
+ end
230
+
231
+ def msghandler(msg)
232
+ if msg.msg==WMsg::WM_INITDIALOG then
233
+ self.vrinit
234
+ self.construct if self.respond_to?(:construct)
235
+ self.self_created if self.respond_to?(:self_created)
236
+ end
237
+ super
238
+ end
239
+ end
240
+
241
+ def open(parent=@parent,modal=true)
242
+ @parent=parent
243
+ super parent,modal
244
+ end
245
+ end
246
+
247
+
248
+ class VRModalDialog <VRDialogComponent
249
+ =begin
250
+ == VRModalDialog
251
+ This class represents a modal dialog.
252
+ When a modal dialog opens, the sequence is blocked until the dialog is closed.
253
+ (Process about the dialog is advancing.)
254
+ VRModalDialog#open method returns the value which is the argument
255
+ at VRModalDialog#close(value). <- SWin::Dialog#close
256
+
257
+ === Attributes
258
+ Hash of ((|options|)) set values as 'options["cancelbutton"]=canbtn'
259
+
260
+ === Methods
261
+ --- close(value)
262
+ See SWin::Dialog#close
263
+ =end
264
+
265
+ include VRParent
266
+
267
+ end
268
+
269
+ class VRModelessDialog <VRDialogComponent
270
+ =begin
271
+ == VRModelessDialog
272
+ This class represents a modeless dialog.
273
+ VRModelessDialog dialog is resemble like VRForm except at creating.
274
+ The modeless dialogs have advantages enabling TAB_STOP control focusing.
275
+
276
+ === Attributes
277
+ Hash of ((|options|)) set values as 'options["cancelbutton"]=canbtn'
278
+
279
+ === Methods
280
+ --- open(parent=@parent)
281
+ See SWin::Dialog#open.
282
+ --- close(value)
283
+ See SWin::Dialog#close
284
+ =end
285
+
286
+ include VRParent
287
+
288
+ def open(parent=@parent,ignored_modal=false)
289
+ super parent,false
290
+ end
291
+ end
292
+
293
+
294
+
295
+ class VRScreen
296
+ =begin
297
+ == VRScreen
298
+ A method is added to VRScreen by loading this file.
299
+
300
+ === Method
301
+ --- openModalDialog(parent,style=nil,mod=VRDialogComponent,template=PlaneDialogTemplate,options={})
302
+ Creates and opens a modal dialog box.
303
+ This method is blocked until the dialog box closed.
304
+ GUI definition can be specified by ((|template|)) or mod#construct.
305
+ When mod==nil, then this method use VRDialogComponent instead of nil.
306
+ The return value is dialog's return value set by SWin::Dialog#close.
307
+ ((|options|)) specifies the focused control, ok button, cancel button, etc.
308
+ --- openModelessDialog(parent,style=nil,mod=VRDialogComponent,template=PlaneDialogTemplate,options={})
309
+ Creates and opens a modeless dialog box.
310
+ GUI definition can be specified by ((|template|)) or mod#construct.
311
+ When mod==nil, then this method use VRDialogComponent instead of nil.
312
+ The return value is false and this method returns immediately.(non-blocking)
313
+ ((|options|)) specifies the focused control, ok button, cancel button, etc.
314
+ (see VRInputbox)
315
+
316
+ --- newdialog(parent,style=nil,mod=VRDialogComponent,template=PlaneDialogTemplate,options={})
317
+ Creates a dialogbox whose parent is ((|parent|)), and returns it.
318
+ To open that dialogbox, call "open" method.
319
+ This method is called by openModalDialog() and openModelessDialog() .
320
+ ((|mod|)) may be a module or a class which is a descendant of
321
+ VRDialogComponent.
322
+ =end
323
+
324
+ PlaneDialogTemplate = VRDialogTemplate.new.to_template
325
+
326
+ def newdialog(parent,style=nil,mod=VRDialogComponent,*template_arg)
327
+ template,options = *template_arg
328
+ template = PlaneDialogTemplate unless template
329
+ options = {} unless options
330
+ if mod.is_a?(Class) and mod.ancestors.index(VRDialogComponent) then
331
+ frm=@factory.newdialog(template,mod)
332
+ elsif mod.is_a?(Class) then
333
+ raise "#{mod.class} is not a descendant of VRDialogComponent"
334
+ elsif mod.is_a?(Module) then
335
+ frm=@factory.newdialog(template,VRDialogComponent)
336
+ frm.extend VRParent
337
+ frm.extend mod
338
+ else
339
+ raise ArgError,"a Class/Module of VRDialogComponent required"
340
+ end
341
+ frm.parentinit(self)
342
+ frm.addEvent WMsg::WM_INITDIALOG
343
+ frm.extend(VRStdControlContainer)
344
+ frm.style=style if style
345
+ frm.extend(VRDialogComponent::VRInitDialogHandler)
346
+ frm.options.update(options)
347
+ frm.instance_eval("@parent=parent")
348
+ frm
349
+ end
350
+
351
+ def openModalDialog(parent,style=nil,mod=VRModalDialog,*template_arg)
352
+ mod = VRModalDialog unless mod
353
+ frm = newdialog(parent,style,mod,*template_arg)
354
+ a = frm.open(parent,true)
355
+ end
356
+
357
+ def openModelessDialog(parent,style=nil,mod=VRModelessDialog,*template_arg)
358
+ mod = VRModelessDialog unless mod
359
+ frm = newdialog(parent,style,mod,*template_arg)
360
+ frm.open parent,false
361
+ @_vr_box.push frm
362
+ frm
363
+ end
364
+
365
+ alias modalform :openModalDialog
366
+ alias modelessform :openModelessDialog
367
+ end
368
+
369
+ module VRInputboxDialog
370
+ =begin
371
+ == VRInputboxDialog
372
+ Abstract module of Inputbox.
373
+ Ok button, Cancel button and input area are have to be added by addDlgControl.
374
+ After creating them, set the options "okbutton","cancelbutton","target" and
375
+ "default".
376
+ =end
377
+
378
+ include VRParent
379
+ include VRStdControlContainer
380
+
381
+ def vrinit
382
+ super
383
+ target = @options["target"]
384
+ end
385
+
386
+ def msghandler(msg)
387
+ if msg.msg == WMsg::WM_INITDIALOG then
388
+ self.setItemTextOf(@options["target"],@options["default"].to_s)
389
+ end
390
+
391
+ if msg.msg == WMsg::WM_COMMAND then
392
+ if msg.wParam==@options["okbutton"] then
393
+ close self.getItemTextOf(@options["target"])
394
+ elsif msg.wParam==@options["cancelbutton"] then
395
+ close false
396
+ end
397
+ end
398
+ end
399
+ end
400
+
401
+ class VRInputbox < VRDialogComponent
402
+ include VRInputboxDialog
403
+ end