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.
- data/lib/vr/clipboard.rb +107 -0
- data/lib/vr/compat/rubycompat.rb +18 -0
- data/lib/vr/compat/vrcomctl.rb +12 -0
- data/lib/vr/compat/vrcontrol.rb +50 -0
- data/lib/vr/compat/vrmmedia.rb +24 -0
- data/lib/vr/contrib/inifile.rb +111 -0
- data/lib/vr/contrib/msgboxconst.rb +55 -0
- data/lib/vr/contrib/toolbar.rb +378 -0
- data/lib/vr/contrib/vrctlcolor.rb +110 -0
- data/lib/vr/contrib/vrhotkey.rb +35 -0
- data/lib/vr/contrib/vrlistviewex.rb +71 -0
- data/lib/vr/contrib/vrwincomponent.rb +54 -0
- data/lib/vr/dragdropformat.rb +210 -0
- data/lib/vr/handlers.rd +5 -0
- data/lib/vr/rscutil.rb +170 -0
- data/lib/vr/sysmod.rb +250 -0
- data/lib/vr/vractivex.rb +56 -0
- data/lib/vr/vrclipboard.rb +55 -0
- data/lib/vr/vrcomctl.rb +1779 -0
- data/lib/vr/vrcontrol.rb +1326 -0
- data/lib/vr/vrdde.rb +625 -0
- data/lib/vr/vrddrop.rb +191 -0
- data/lib/vr/vrdialog.rb +403 -0
- data/lib/vr/vrhandler.rb +196 -0
- data/lib/vr/vrlayout.old.rb +209 -0
- data/lib/vr/vrlayout.rb +174 -0
- data/lib/vr/vrlayout2.rb +340 -0
- data/lib/vr/vrmmedia.rb +289 -0
- data/lib/vr/vrolednd.rb +193 -0
- data/lib/vr/vrowndraw.rb +109 -0
- data/lib/vr/vrrichedit.rb +335 -0
- data/lib/vr/vrtimer.rb +150 -0
- data/lib/vr/vrtooltip.rb +274 -0
- data/lib/vr/vrtray.rb +144 -0
- data/lib/vr/vrtvitem.rb +120 -0
- data/lib/vr/vrtwopane.rb +226 -0
- data/lib/vr/vruby.rb +1050 -0
- data/lib/vr/winconst.rb +159 -0
- metadata +86 -0
data/lib/vr/vrtvitem.rb
ADDED
@@ -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
|
+
|
data/lib/vr/vrtwopane.rb
ADDED
@@ -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
|
+
|
data/lib/vr/vruby.rb
ADDED
@@ -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
|
+
|