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/vrdde.rb
ADDED
@@ -0,0 +1,625 @@
|
|
1
|
+
###################################
|
2
|
+
#
|
3
|
+
# vrdde.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) modules for DDE
|
14
|
+
This file provides modules for DDE conversation.
|
15
|
+
<<< handlers.rd
|
16
|
+
=end
|
17
|
+
|
18
|
+
|
19
|
+
# DDE_ADVISE not tested.
|
20
|
+
|
21
|
+
VR_DIR="vr/" unless defined?(::VR_DIR)
|
22
|
+
require VR_DIR+'vruby'
|
23
|
+
require VR_DIR+'sysmod'
|
24
|
+
|
25
|
+
module DDElParam
|
26
|
+
PackDDElParam=Win32API.new("user32","PackDDElParam",["I","I","I"],"L")
|
27
|
+
UnpackDDElParam=Win32API.new("user32","UnpackDDElParam",["I","L","P","P"],"I")
|
28
|
+
FreeDDElParam=Win32API.new("user32","FreeDDElParam",["I","L"],"I")
|
29
|
+
ReuseDDElParam=Win32API.new("user32","ReuseDDElParam","IIIII","L")
|
30
|
+
|
31
|
+
def packDDElParam(msg,low,high)
|
32
|
+
PackDDElParam.call(msg,low,high)
|
33
|
+
end
|
34
|
+
def unpackDDElParam(msg,lparam)
|
35
|
+
a=" "; b=" "
|
36
|
+
UnpackDDElParam.call(msg,lparam,a,b)
|
37
|
+
[a.unpack("I")[0],b.unpack("I")[0]]
|
38
|
+
end
|
39
|
+
|
40
|
+
def freeDDElParam(msg,lparam)
|
41
|
+
FreeDDElParam.call(msg,lparam)
|
42
|
+
end
|
43
|
+
|
44
|
+
def reuseDDElParam(lParam, uMsgIn, uMsgOut, uLow, uHigh) #by yukimi_sake
|
45
|
+
ReuseDDElParam.call(lParam, uMsgIn, uMsgOut, uLow, uHigh)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
module VRDdeConversation
|
50
|
+
=begin
|
51
|
+
== VRDdeConversation
|
52
|
+
Utilities for DDE conversation.
|
53
|
+
|
54
|
+
=== Methods
|
55
|
+
--- sendDDEAck(shwnd,aItem,retcode=0,ack=true,busy=false)
|
56
|
+
Sends DDE_ACK message to shwnd.
|
57
|
+
|
58
|
+
== VRDdeConversation::DDEAckFlags
|
59
|
+
This is a capsule of return code,ack flag, busy flag for DDE_ACK message
|
60
|
+
=== Attributes
|
61
|
+
--- retcode
|
62
|
+
8bit value.
|
63
|
+
--- ack
|
64
|
+
DDE request is accepted or not.
|
65
|
+
--- busy
|
66
|
+
busy or not.
|
67
|
+
=end
|
68
|
+
|
69
|
+
WM_DDE_INITIATE = 0x3e0
|
70
|
+
WM_DDE_TERMINATE= 0x3e1
|
71
|
+
WM_DDE_ADVISE = 0x3e2
|
72
|
+
WM_DDE_UNADVISE = 0x3e3
|
73
|
+
WM_DDE_ACK = 0x3e4
|
74
|
+
WM_DDE_DATA = 0x3e5
|
75
|
+
WM_DDE_REQUEST = 0x3e6
|
76
|
+
WM_DDE_POKE = 0x3e7
|
77
|
+
WM_DDE_EXECUTE = 0x3e8
|
78
|
+
|
79
|
+
class DDEAckFlags
|
80
|
+
# attr_accessor :ack
|
81
|
+
# attr_accessor :busy
|
82
|
+
# attr_accessor :retcode
|
83
|
+
def ack() @_vr_ack; end
|
84
|
+
def busy() @_vr_busy; end
|
85
|
+
def retcode() @_vr_retcode; end
|
86
|
+
|
87
|
+
def initialize(ack=true,busy=false,retcode=0)
|
88
|
+
@_vr_ack,@_vr_busy,@_vr_retcode = ack,busy,retcode
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def sendDDEAck(shwnd,aItem,retcode=0,ack=true,busy=false)
|
93
|
+
r = retcode & 0xff
|
94
|
+
r |= 0x8000 if ack
|
95
|
+
r |= 0x4000 if busy
|
96
|
+
lparam = packDDElParam(WM_DDE_ACK,r,aItem)
|
97
|
+
SMSG::PostMessage.call shwnd,WM_DDE_ACK, self.hWnd,lparam
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
module VRDdeServer
|
102
|
+
=begin
|
103
|
+
== VRDdeServer
|
104
|
+
This module prepares fundamental functions for DDE server.
|
105
|
+
|
106
|
+
=== Methods
|
107
|
+
--- addDDEAppTopic(appname,topic)
|
108
|
+
Adds acceptable pair of application name and topic for DDE.
|
109
|
+
--- delDDEAppTopic(appname,topic)
|
110
|
+
Deletes acceptable pair of application name and topic.
|
111
|
+
|
112
|
+
=== Event handlers
|
113
|
+
--- ????_ddeinitiate(shwnd,appname,topic)
|
114
|
+
Fired when DDE client whose hwnd is ((|shwnd|)) connects the
|
115
|
+
DDE server.
|
116
|
+
--- ???_ddeterminate(shwnd)
|
117
|
+
Fred when DDE client whose hwnd is ((|shwnd|)) disconnects.
|
118
|
+
=end
|
119
|
+
|
120
|
+
include VRMessageHandler
|
121
|
+
include VRDdeConversation
|
122
|
+
include DDElParam
|
123
|
+
|
124
|
+
def ddeserverinit
|
125
|
+
acceptEvents([WM_DDE_INITIATE,WM_DDE_TERMINATE])
|
126
|
+
addHandler WM_DDE_INITIATE,"_ddeInitiate",MSGTYPE::ARGINTINTINT,nil
|
127
|
+
addHandler WM_DDE_TERMINATE,"_ddeTerminate",MSGTYPE::ARGWINT,nil
|
128
|
+
@_vr_clients={} #{client's hwnd=>[client's hwnd,appname,topic]
|
129
|
+
@_vr_ddeacceptable=[] # [appname,topic]
|
130
|
+
end
|
131
|
+
def vrinit
|
132
|
+
super
|
133
|
+
ddeserverinit
|
134
|
+
end
|
135
|
+
|
136
|
+
def self__ddeInitiate(shwnd,aApp,aTopic)
|
137
|
+
p=[GAtom::GetName(aApp),GAtom::GetName(aTopic)]
|
138
|
+
return unless @_vr_ddeacceptable.index(p)
|
139
|
+
|
140
|
+
@_vr_clients[shwnd] = [shwnd] + p
|
141
|
+
r=nil
|
142
|
+
r=selfmsg_dispatching("ddeinitiate",shwnd,p[0],p[1])
|
143
|
+
SMSG::SendMessage.call shwnd,WM_DDE_ACK,self.hWnd,MAKELPARAM(aApp,aTopic)
|
144
|
+
end
|
145
|
+
|
146
|
+
def self__ddeTerminate(shwnd)
|
147
|
+
selfmsg_dispatching("ddeterminate",shwnd)
|
148
|
+
SMSG::PostMessage.call shwnd,WM_DDE_TERMINATE,self.hWnd,0
|
149
|
+
@_vr_clients.delete(shwnd)
|
150
|
+
end
|
151
|
+
|
152
|
+
def addDDEAppTopic(appname,topic)
|
153
|
+
@_vr_ddeacceptable.push([appname,topic])
|
154
|
+
end
|
155
|
+
def delDDEAppTopic(appname,topic)
|
156
|
+
@_vr_ddeacceptable.delete([appname,topic])
|
157
|
+
end
|
158
|
+
|
159
|
+
def self_ddeinitiate(*args) end
|
160
|
+
def self_ddeterminate(*arg) end
|
161
|
+
end
|
162
|
+
|
163
|
+
module VRDdeExecuteServer
|
164
|
+
=begin
|
165
|
+
== VRDdeExecuteServer
|
166
|
+
This module provides a feature of DDE_Execute server.
|
167
|
+
((<VRDdeServer>)) is included.
|
168
|
+
|
169
|
+
=== Event handler
|
170
|
+
--- self_ddeexecute(command,shwnd,appname,topic)
|
171
|
+
Fired when the client whose name is ((|shwnd|)) sends DDE_EXECUTE
|
172
|
+
to the server.The command string is ((|command|)).
|
173
|
+
If the return value is a kind of VRDdeConversation::((<DDEAckFlags>)),
|
174
|
+
DDE_ACK message that will be sent is according to this return value.
|
175
|
+
=end
|
176
|
+
|
177
|
+
include VRDdeServer
|
178
|
+
|
179
|
+
EXECUTEMETHOD="ddeexecute"
|
180
|
+
|
181
|
+
def ddeexecuteserverinit
|
182
|
+
addEvent WM_DDE_EXECUTE
|
183
|
+
addHandler WM_DDE_EXECUTE,"_ddeexecuteinternal",MSGTYPE::ARGINTINT,nil
|
184
|
+
end
|
185
|
+
def vrinit
|
186
|
+
super
|
187
|
+
ddeexecuteserverinit
|
188
|
+
end
|
189
|
+
|
190
|
+
def self__ddeexecuteinternal(shwnd,hcmd)
|
191
|
+
cl=@_vr_clients[shwnd]
|
192
|
+
raise "unknown dde client (not initiated)" unless cl
|
193
|
+
cmd=GMEM::Get(hcmd).unpack("A*")[0]
|
194
|
+
ret=nil
|
195
|
+
ret=selfmsg_dispatching(EXECUTEMETHOD,cmd,*cl)
|
196
|
+
freeDDElParam(WM_DDE_EXECUTE,hcmd) #by yukimi_sake
|
197
|
+
if ret.is_a?(DDEAckFlags) then
|
198
|
+
sendDDEAck shwnd,hcmd,(ret.retcode || 0),ret.ack,ret.busy
|
199
|
+
else
|
200
|
+
sendDDEAck shwnd,hcmd
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
module VRDdeRequestServer #by yukimi_sake
|
206
|
+
=begin
|
207
|
+
== VRDdeRequestServer
|
208
|
+
This module provides a feature of DDE_REQUEST server.
|
209
|
+
((<VRDdeServer>)) is included.
|
210
|
+
|
211
|
+
=== Event handler
|
212
|
+
--- self_dderequest(item,shwnd,app,topic)
|
213
|
+
Fired when the client whose name is ((|shwnd|)) sends DDE_REQUEST
|
214
|
+
to the server.The item string is ((|item|)).
|
215
|
+
Retuern value(as String) is sended to shwnd which is handle of client,
|
216
|
+
using WM_DDE_DATA message.
|
217
|
+
If the return value is a kind of VRDdeConversation::((<DDEAckFlags>)),
|
218
|
+
DDE_ACK message that will be sent is according to this return value.
|
219
|
+
=end
|
220
|
+
|
221
|
+
include VRDdeServer
|
222
|
+
|
223
|
+
EXECUTEMETHOD="dderequest"
|
224
|
+
GMEM_DDESHARE=0x2000
|
225
|
+
|
226
|
+
def sendDDEData(shwnd,lp,data)
|
227
|
+
raise "Data must be a String" unless data.is_a? String
|
228
|
+
dDEDATA=[0xb000,ClipboardFormat::CF_TEXT,data+"\0"].pack("Ssa*")
|
229
|
+
hData=GMEM::AllocStr(GMEM_DDESHARE,dDEDATA)
|
230
|
+
lParam=reuseDDElParam lp,WM_DDE_REQUEST,WM_DDE_DATA,hData,HIWORD(lp)
|
231
|
+
SMSG::PostMessage.call shwnd, WM_DDE_DATA, self.hWnd, lParam
|
232
|
+
end
|
233
|
+
|
234
|
+
def dderequestserverinit
|
235
|
+
addEvent WM_DDE_REQUEST
|
236
|
+
addHandler WM_DDE_REQUEST,"_dderequestinternal",MSGTYPE::ARGINTINT,nil
|
237
|
+
end
|
238
|
+
|
239
|
+
def vrinit
|
240
|
+
super
|
241
|
+
dderequestserverinit
|
242
|
+
end
|
243
|
+
|
244
|
+
def self__dderequestinternal(shwnd,lparam)
|
245
|
+
cl=@_vr_clients[shwnd]
|
246
|
+
raise "unknown dde client (not initiated)" unless cl
|
247
|
+
cformat,aitem = unpackDDElParam(WM_DDE_REQUEST,lparam)
|
248
|
+
raise "not supported this format" unless cformat == 1
|
249
|
+
item = GAtom::GetName(aitem)
|
250
|
+
ret=nil
|
251
|
+
ret=selfmsg_dispatching(EXECUTEMETHOD,item,*cl)
|
252
|
+
if ret.is_a?(DDEAckFlags) then
|
253
|
+
freeDDElParam(WM_DDE_REQEST,lparam)
|
254
|
+
sendDDEAck shwnd,aitem,(ret.retcode || 0),ret.ack,ret.busy
|
255
|
+
else
|
256
|
+
sendDDEData shwnd,lparam,ret
|
257
|
+
end
|
258
|
+
end
|
259
|
+
def self_dderequest(item,shwnd,app,topic) end
|
260
|
+
end
|
261
|
+
|
262
|
+
module VRDdePokeServer #by yukimi_sake
|
263
|
+
=begin
|
264
|
+
== VRDdePokeServer
|
265
|
+
This module provides a feature of DDE_POKE server.
|
266
|
+
((<VRDdeServer>)) is included.
|
267
|
+
|
268
|
+
=== Event handler
|
269
|
+
--- self_ddepoke(item,data,cfmt,shwnd,app,topic)
|
270
|
+
Fired when the client whose name is ((|shwnd|)) sends DDE_POKE
|
271
|
+
to the server.The item string is ((|item|)).The data is ((|data|)).
|
272
|
+
If you want to treat data other than String, carry out according to
|
273
|
+
clipboard format ((|cfmt|)) in the handler.
|
274
|
+
If the return value is a kind of VRDdeConversation::((<DDEAckFlags>)),
|
275
|
+
DDE_ACK message that will be sent is according to this return value.
|
276
|
+
=end
|
277
|
+
include VRDdeServer
|
278
|
+
|
279
|
+
EXECUTEMETHOD="ddepoke"
|
280
|
+
|
281
|
+
def ddepokeserverinit
|
282
|
+
addEvent WM_DDE_POKE
|
283
|
+
addHandler WM_DDE_POKE,"_ddepokeinternal",MSGTYPE::ARGINTINT,nil
|
284
|
+
end
|
285
|
+
|
286
|
+
def vrinit
|
287
|
+
super
|
288
|
+
ddepokeserverinit
|
289
|
+
end
|
290
|
+
|
291
|
+
def self__ddepokeinternal(shwnd,lparam)
|
292
|
+
cl=@_vr_clients[shwnd]
|
293
|
+
raise "unknown dde client (not initiated)" unless cl
|
294
|
+
hdata,aitem = unpackDDElParam(WM_DDE_POKE,lparam)
|
295
|
+
item = GAtom::GetName(aitem)
|
296
|
+
datastr = GMEM::Get(hdata)
|
297
|
+
flag,cfmt,data = datastr.unpack("SsA*")
|
298
|
+
if (flag&0x2000) > 0 then # fRelease is asserted
|
299
|
+
GMEM::Free(hdata)
|
300
|
+
end
|
301
|
+
ret=nil
|
302
|
+
ret=selfmsg_dispatching(EXECUTEMETHOD,item,data,cfmt,*cl)
|
303
|
+
freeDDElParam(WM_DDE_POKE, lparam)
|
304
|
+
if ret.is_a?(DDEAckFlags) then
|
305
|
+
sendDDEAck shwnd,aitem,(ret.retcode || 0),ret.ack,ret.busy
|
306
|
+
else
|
307
|
+
sendDDEAck shwnd,aitem
|
308
|
+
end
|
309
|
+
end
|
310
|
+
def self_ddepoke(item,data,cfmt,shwnd,app,topic) end
|
311
|
+
end
|
312
|
+
|
313
|
+
module VRDdeClient
|
314
|
+
=begin
|
315
|
+
== VRDdeClient
|
316
|
+
This module provides features of DDE clients.
|
317
|
+
|
318
|
+
=== Methods
|
319
|
+
--- ddeconnected?
|
320
|
+
--- ddeready?
|
321
|
+
Returns whether it is able to request dde conversation.
|
322
|
+
--- ddebusy?
|
323
|
+
Returns true when it waits DDE_ACK/DDE_DATA message.
|
324
|
+
|
325
|
+
--- ddeexecute(appname,topic.command)
|
326
|
+
Sends DDE_EXECUTE request to the server specified by the pair of (appname,topic).
|
327
|
+
--- ddepoke(appname,topic,item,data,fmt)
|
328
|
+
Sends DDE_POKE request to the server specified by the pair of (appname,topic).
|
329
|
+
The ((|data|)) in the format of ((|fmt|)) (1 as CF_TEXT and so on) is transferred
|
330
|
+
tothe ((|item|)) in the server
|
331
|
+
--- dderequest(appname,topic,item,fmt)
|
332
|
+
Sends DDE_REQUEST request to the server specified by the pair of (appname,topic).
|
333
|
+
The server calls back ((<self_dderequestdata>)) method of client window to
|
334
|
+
transfer the data of ((|item|)).
|
335
|
+
--- ddeadvise(appname,topic,item,fmt)
|
336
|
+
--- ddeunadvise(appname,topic,item,fmt)
|
337
|
+
Not tested.
|
338
|
+
|
339
|
+
=== Event handlers
|
340
|
+
???? is the downcase-ed appname of the DDE conversation. It is because the ???? name
|
341
|
+
is named by WM_DDE_ACK message's App-name which is created by the server and that
|
342
|
+
may be different from the requested appname from client.
|
343
|
+
|
344
|
+
--- ????_ddeterminate(shwnd)
|
345
|
+
Fired when the server disconnects the conversation.
|
346
|
+
--- ????_dderefused(retcode,busy)
|
347
|
+
Fired when the server refused the connection. The return code is ((|retcode|)) and
|
348
|
+
busy flag is ((|busy|)).
|
349
|
+
--- ????_ddeexecdone(retcode)
|
350
|
+
Fired when the server accepts the DDE_EXECUTE request.
|
351
|
+
--- ????_ddepokedone(retcode)
|
352
|
+
Fired when the server accepts the DDE_POKE request.
|
353
|
+
--- ????_ddedata(data,fmt,flag)
|
354
|
+
Fired when the server returns the data by the DDE_REQUEST that client sended.
|
355
|
+
If the return value is a kind of VRDdeConversation::((<DDEAckFlags>)),
|
356
|
+
DDE_ACK message that will be sent is according to this return value.
|
357
|
+
--- ????_ddeadvisedata(data,fmt,flag)
|
358
|
+
Not tested.
|
359
|
+
=end
|
360
|
+
|
361
|
+
include VRMessageHandler
|
362
|
+
include VRDdeConversation
|
363
|
+
include DDElParam
|
364
|
+
|
365
|
+
private
|
366
|
+
STATUSCONNECT= 1
|
367
|
+
STATUSEXECUTE= 2
|
368
|
+
STATUSPOKE = 4
|
369
|
+
STATUSREQUEST= 8
|
370
|
+
STATUSADVISE = 16
|
371
|
+
STATUSTERMINATE=128
|
372
|
+
GMEMSTYLE = 0x2042
|
373
|
+
|
374
|
+
|
375
|
+
def ddeconnect(appname,topic)
|
376
|
+
raise "DDE_INITIATE busy!" if @_vr_ddesearching
|
377
|
+
raise "Application name must be specified" unless appname
|
378
|
+
aApp = GAtom::Add(appname)
|
379
|
+
aTopic = if topic then GAtom::Add(topic) else 0 end
|
380
|
+
|
381
|
+
srv = @_vr_servers.find do |key,item| item[1]==appname end
|
382
|
+
|
383
|
+
shwnd = if srv then srv[0] else 0xffffffff end
|
384
|
+
@_vr_ddesearching=nil
|
385
|
+
SMSG::SendMessage.call shwnd,WM_DDE_INITIATE,self.hWnd,MAKELPARAM(aApp,aTopic)
|
386
|
+
shwnd = @_vr_ddesearching unless srv
|
387
|
+
@_vr_ddesearching=nil
|
388
|
+
|
389
|
+
GAtom::Delete(aApp)
|
390
|
+
GAtom::Delete(aTopic) if topic!=0
|
391
|
+
raise "DDE Server (#{appname}:#{topic}) not found" unless shwnd
|
392
|
+
shwnd
|
393
|
+
end
|
394
|
+
|
395
|
+
def ddeterminate(shwnd)
|
396
|
+
SMSG::PostMessage.call shwnd,WM_DDE_TERMINATE,self.hWnd,0
|
397
|
+
@_vr_servers[shwnd][2]|=STATUSTERMINATE
|
398
|
+
# @_vr_servers.delete(shwnd)
|
399
|
+
end
|
400
|
+
|
401
|
+
public
|
402
|
+
def vrinit
|
403
|
+
super
|
404
|
+
ddeclientinit
|
405
|
+
end
|
406
|
+
|
407
|
+
def ddeclientinit
|
408
|
+
acceptEvents([WM_DDE_ACK,WM_DDE_DATA,WM_DDE_TERMINATE])
|
409
|
+
addHandler WM_DDE_ACK, "ddeAck", MSGTYPE::ARGINTINT,nil
|
410
|
+
addHandler WM_DDE_DATA,"ddeData",MSGTYPE::ARGINTINT,nil
|
411
|
+
addHandler WM_DDE_TERMINATE,"ddeTerminate",MSGTYPE::ARGWINT,nil
|
412
|
+
@_vr_servers={} # {server's hwnd => [server's hwnd,appname,status,params]}
|
413
|
+
@_vr_ddesearching = false
|
414
|
+
end
|
415
|
+
|
416
|
+
def ddeconnected?(appname)
|
417
|
+
srv = @_vr_servers.find do |key,item| item[1].downcase==appname.downcase end
|
418
|
+
if srv then srv=srv[1];((srv[2]&STATUSCONNECT)>0) else false end
|
419
|
+
end
|
420
|
+
def ddebusy?(appname)
|
421
|
+
srv = @_vr_servers.find do |key,item| item[1].downcase==appname.downcase end
|
422
|
+
if srv then srv=srv[1]; ((srv[2] & ~STATUSCONNECT)>0) else nil end
|
423
|
+
end
|
424
|
+
def ddeidle?(appname)
|
425
|
+
srv = @_vr_servers.find do |key,item| item[1].downcase==appname.downcase end
|
426
|
+
if srv then
|
427
|
+
srv=srv[1]
|
428
|
+
((srv[2]&STATUSCONNECT)>0) and ((srv[2] & ~STATUSCONNECT)==0)
|
429
|
+
else
|
430
|
+
true
|
431
|
+
end
|
432
|
+
end
|
433
|
+
def ddeready?(appname)
|
434
|
+
srv = @_vr_servers.find do |key,item| item[1].downcase==appname.downcase end
|
435
|
+
if srv then
|
436
|
+
srv=srv[1]
|
437
|
+
((srv[2]&STATUSCONNECT)>0) and
|
438
|
+
((srv[2] & ~(STATUSCONNECT | STATUSADVISE))==0)
|
439
|
+
else
|
440
|
+
true
|
441
|
+
end
|
442
|
+
end
|
443
|
+
|
444
|
+
def ddeexecute(appname,topic,cmdstr)
|
445
|
+
raise "dde(#{appname}:#{topic}) not ready" unless ddeready?(appname)
|
446
|
+
shwnd=ddeconnect(appname,topic)
|
447
|
+
executemem = GMEM::AllocStr(GMEMSTYLE,cmdstr)
|
448
|
+
@_vr_servers[shwnd][2] |= STATUSEXECUTE
|
449
|
+
SMSG::PostMessage.call shwnd,WM_DDE_EXECUTE,self.hWnd,executemem
|
450
|
+
end
|
451
|
+
|
452
|
+
def ddepoke(appname,topic,item,data,fmt=ClipboardFormat::CF_TEXT)
|
453
|
+
raise "dde(#{appname}:#{topic}) not ready" unless ddeready?(appname)
|
454
|
+
shwnd=ddeconnect(appname,topic)
|
455
|
+
|
456
|
+
aItem = GAtom::Add(item.to_s)
|
457
|
+
|
458
|
+
pokedata=[0,fmt].pack("Ss")+data.to_s
|
459
|
+
pokemem = GMEM::AllocStr(GMEMSTYLE,pokedata)
|
460
|
+
|
461
|
+
@_vr_servers[shwnd][2] |= STATUSPOKE
|
462
|
+
@_vr_servers[shwnd][3] = pokemem
|
463
|
+
|
464
|
+
lparam = packDDElParam(WM_DDE_POKE,pokemem,aItem)
|
465
|
+
SMSG::PostMessage.call shwnd,WM_DDE_POKE,self.hWnd,lparam
|
466
|
+
end
|
467
|
+
|
468
|
+
def dderequest(appname,topic,item,fmt=ClipboardFormat::CF_TEXT)
|
469
|
+
raise "dde(#{appname}:#{topic}) not ready" unless ddeready?(appname)
|
470
|
+
shwnd=ddeconnect(appname,topic)
|
471
|
+
|
472
|
+
aItem = GAtom::Add(item.to_s)
|
473
|
+
|
474
|
+
@_vr_servers[shwnd][2] |= STATUSREQUEST
|
475
|
+
SMSG::PostMessage.call shwnd,WM_DDE_REQUEST,self.hWnd,
|
476
|
+
MAKELPARAM(fmt.to_i,aItem)
|
477
|
+
end
|
478
|
+
|
479
|
+
def ddeadvise(appname,topic,item,fmt=1,defup=false,ackreq=false)
|
480
|
+
raise "dde(#{appname}:#{topic}) not ready" unless ddeready?(appname)
|
481
|
+
shwnd=ddeconnect(appname,topic)
|
482
|
+
|
483
|
+
aItem = GAtom::Add(item.to_s)
|
484
|
+
|
485
|
+
flag = 0
|
486
|
+
if defup then flag |= 0x4000 end
|
487
|
+
if ackreq then flag |= 0x8000 end
|
488
|
+
|
489
|
+
advisedata=[flag,fmt].pack("Ss")
|
490
|
+
advisemem = GMEM::AllocStr(GMEMSTYLE,advisedata)
|
491
|
+
|
492
|
+
@_vr_servers[shwnd][2] |= STATUSADVISE
|
493
|
+
lparam = packDDElParam(WM_DDE_POKE,advisemem,aItem)
|
494
|
+
SMSG::PostMessage.call shwnd,WM_DDE_ADVISE,self.hWnd,lparam
|
495
|
+
end
|
496
|
+
|
497
|
+
def ddeunadvise(appname,topic,item,fmt=0)
|
498
|
+
raise "dde(#{appname}:#{topic}) not ready" unless ddeready?(appname)
|
499
|
+
shwnd=ddeconnect(appname,topic)
|
500
|
+
|
501
|
+
aItem = GAtom::Add(item.to_s)
|
502
|
+
|
503
|
+
@_vr_servers[n][2] |= STATUSREQUEST
|
504
|
+
SMSG::PostMessage.call @_vr_servers[n][0],WM_DDE_UNADVISE,self.hWnd,
|
505
|
+
MAKELPARAM(fmt.to_i,aItem)
|
506
|
+
end
|
507
|
+
|
508
|
+
|
509
|
+
def self_ddeTerminate(shwnd)
|
510
|
+
controlmsg_dispatching(@_vr_servers[shwnd][1],"ddeterminate")
|
511
|
+
# fname=@_vr_servers[shwnd][1] + "_ddeterminate"
|
512
|
+
# send(fname,shwnd) if respond_to?(fname)
|
513
|
+
@_vr_servers.delete(shwnd)
|
514
|
+
end
|
515
|
+
|
516
|
+
def self_ddeAck(shwnd,lparam)
|
517
|
+
#p "ACK"
|
518
|
+
sv = @_vr_servers[shwnd]
|
519
|
+
fname=""
|
520
|
+
if(!sv) then
|
521
|
+
aApp,aTopic = LOWORD(lparam),HIWORD(lparam)
|
522
|
+
appname=GAtom::GetName(aApp).downcase
|
523
|
+
tpcname=GAtom::GetName(aTopic)
|
524
|
+
appname2=appname.dup
|
525
|
+
def appname2.name() self; end # tricky thing for parentrelayer
|
526
|
+
@_vr_servers[shwnd]=[shwnd,appname2,STATUSCONNECT,nil]
|
527
|
+
|
528
|
+
@_vr_ddesearching=shwnd
|
529
|
+
|
530
|
+
GAtom::Delete(aApp)
|
531
|
+
GAtom::Delete(aTopic)
|
532
|
+
|
533
|
+
elsif (sv[2] & ~STATUSCONNECT)>0 then
|
534
|
+
wstatus,param = unpackDDElParam(WM_DDE_ACK,lparam)
|
535
|
+
freeDDElParam(WM_DDE_ACK,lparam)
|
536
|
+
|
537
|
+
retcode = wstatus&0xf
|
538
|
+
busy= 0<(wstatus&0x4000)
|
539
|
+
ack = 0<(wstatus&0x8000)
|
540
|
+
sname = sv[1]
|
541
|
+
|
542
|
+
unless ack then
|
543
|
+
sv[2] &= STATUSCONNECT
|
544
|
+
# fname=sname+"_dderefused"
|
545
|
+
# send(fname,retcode,busy) if respond_to?(fname)
|
546
|
+
controlmsg_dispatching(sname,"dderefused",retcode,busy)
|
547
|
+
end
|
548
|
+
if (sv[2] & STATUSEXECUTE)>0 then
|
549
|
+
GMEM::Free(param) unless ack
|
550
|
+
sv[2] &= ~STATUSEXECUTE
|
551
|
+
fname="ddeexecdone"
|
552
|
+
ddeterminate(shwnd)
|
553
|
+
elsif(sv[2] & STATUSPOKE)>0 then
|
554
|
+
GAtom::Delete(param)
|
555
|
+
GMEM::Free(sv[3])
|
556
|
+
sv[3]=nil
|
557
|
+
sv[2] &= ~STATUSPOKE
|
558
|
+
fname="ddepokedone"
|
559
|
+
ddeterminate(shwnd)
|
560
|
+
elsif(sv[2] & STATUSREQUEST)>0 then
|
561
|
+
GAtom::Delete(param)
|
562
|
+
sv[2] &= ~STATUSPOKE
|
563
|
+
fname=nil
|
564
|
+
ddeterminate(shwnd)
|
565
|
+
elsif(sv[2] & STATUSADVISE)>0 then
|
566
|
+
GMEM::Free(param) unless ack
|
567
|
+
sv[2] &= ~STATUSADVISE
|
568
|
+
fname=nil
|
569
|
+
else
|
570
|
+
ddeterminate(shwnd)
|
571
|
+
end
|
572
|
+
controlmsg_dispatching(sname,fname,retcode) if ack and fname
|
573
|
+
else
|
574
|
+
raise "DDE MultiSession Error"
|
575
|
+
end
|
576
|
+
end
|
577
|
+
|
578
|
+
def self_ddeData(shwnd,lparam)
|
579
|
+
#p "DATA"
|
580
|
+
datamem,aItem = unpackDDElParam(WM_DDE_DATA,lparam)
|
581
|
+
freeDDElParam(WM_DDE_DATA,lparam)
|
582
|
+
|
583
|
+
sv = @_vr_servers[shwnd]
|
584
|
+
fname=sname=nil
|
585
|
+
|
586
|
+
datastr = GMEM::Get(datamem)
|
587
|
+
flag,fmt,data = datastr.unpack("Ssa*")
|
588
|
+
|
589
|
+
if (flag&0x2000) > 0 then # fRelease is asserted
|
590
|
+
GMEM::Free(datamem)
|
591
|
+
end
|
592
|
+
|
593
|
+
ret = nil
|
594
|
+
if(!sv) then
|
595
|
+
# Ignored
|
596
|
+
else
|
597
|
+
sname=sv[1]
|
598
|
+
if (sv[2] & STATUSREQUEST)>0 then
|
599
|
+
sv[2]&=1
|
600
|
+
fname="ddedata"
|
601
|
+
ddeterminate(sv[0])
|
602
|
+
elsif (sv[2] & STATUSADVISE)>0
|
603
|
+
sv[2]&=1
|
604
|
+
fname="ddeadvisedata"
|
605
|
+
else
|
606
|
+
end
|
607
|
+
|
608
|
+
fn=sname+fname
|
609
|
+
if(fn) then
|
610
|
+
ret=controlmsg_dispatching(sname,fname,data,fmt,flag)
|
611
|
+
end
|
612
|
+
end
|
613
|
+
|
614
|
+
if (flag&0x8000) > 0 then #fAckReq is asserted
|
615
|
+
if ret.is_a?(DDEAckFlags) then
|
616
|
+
sendDDEAck shwnd,aItem,(ret.retcode || 0),ret.ack,ret.busy
|
617
|
+
else
|
618
|
+
sendDDEAck shwnd,aItem
|
619
|
+
end
|
620
|
+
else
|
621
|
+
GAtom::Delete(aItem)
|
622
|
+
end
|
623
|
+
|
624
|
+
end
|
625
|
+
end
|