vruby 2004.08.07

Sign up to get free protection for your applications and to get access to all the features.
@@ -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