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