win 0.1.18 → 0.1.22
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/VERSION +1 -1
- data/lib/win/dde.rb +139 -3
- data/lib/win/error.rb +14 -14
- data/lib/win/gui/dialog.rb +1 -0
- data/lib/win/gui/input.rb +1 -27
- data/lib/win/gui/message.rb +412 -72
- data/lib/win/gui/window.rb +5 -5
- data/spec/win/dde_spec.rb +187 -57
- data/spec/win/gui/message_spec.rb +195 -8
- data/win.gemspec +2 -2
- metadata +2 -2
data/spec/win/dde_spec.rb
CHANGED
@@ -4,6 +4,7 @@ require 'win/dde'
|
|
4
4
|
module WinDDETest
|
5
5
|
include WinTest
|
6
6
|
include Win::DDE
|
7
|
+
include Win::GUI::Message
|
7
8
|
|
8
9
|
def dde_cmd
|
9
10
|
APPCLASS_STANDARD
|
@@ -21,6 +22,19 @@ module WinDDETest
|
|
21
22
|
FFI::MemoryPointer.new(:char, 1024)
|
22
23
|
end
|
23
24
|
|
25
|
+
def string_pointer
|
26
|
+
FFI::MemoryPointer.from_string("Pointer_string")
|
27
|
+
end
|
28
|
+
|
29
|
+
def extract_values(*args)
|
30
|
+
type, format, conv, hsz1, hsz2, data, data1, data2 = *args
|
31
|
+
@server_conv = conv
|
32
|
+
[Win::DDE::TYPES[type], format, conv,
|
33
|
+
dde_query_string(@client_id, hsz1),
|
34
|
+
dde_query_string(@client_id, hsz2),
|
35
|
+
data, data1, data2]
|
36
|
+
end
|
37
|
+
|
24
38
|
describe Win::DDE, ' contains a set of pre-defined Windows API functions' do
|
25
39
|
describe 'register_clipboard_format' do
|
26
40
|
spec{ use{ RegisterClipboardFormat(format_name = "XlTable") }}
|
@@ -44,48 +58,50 @@ module WinDDETest
|
|
44
58
|
end
|
45
59
|
|
46
60
|
describe 'dde_initialize' do
|
61
|
+
after(:each) {dde_uninitialize(@instance_id) if @instance_id}
|
62
|
+
|
47
63
|
spec{ use{ status = DdeInitialize( zero_id, dde_callback, dde_cmd, unused = 0)}}
|
48
64
|
spec{ use{ id, status = dde_initialize( instance_id = 0, dde_cmd) do|*args|
|
49
65
|
end }}
|
50
66
|
|
51
67
|
it 'with zero instance_id, returns integer id and DMLERR_NO_ERROR if initialization successful' do
|
52
|
-
|
53
|
-
|
54
|
-
|
68
|
+
@instance_id, status = dde_initialize(0, APPCLASS_STANDARD) {|*args| }
|
69
|
+
@instance_id.should be_an Integer
|
70
|
+
@instance_id.should_not == 0
|
55
71
|
status.should == DMLERR_NO_ERROR
|
56
72
|
end
|
57
73
|
|
58
74
|
it 'with nil instance_id, returns integer id and DMLERR_NO_ERROR if initialization successful' do
|
59
|
-
|
60
|
-
|
61
|
-
|
75
|
+
@instance_id, status = dde_initialize(nil, APPCLASS_STANDARD) {|*args| }
|
76
|
+
@instance_id.should be_an Integer
|
77
|
+
@instance_id.should_not == 0
|
62
78
|
status.should == DMLERR_NO_ERROR
|
63
79
|
end
|
64
80
|
|
65
81
|
it 'with omitted instance_id, returns integer id and DMLERR_NO_ERROR if initialization successful' do
|
66
|
-
|
67
|
-
|
68
|
-
|
82
|
+
@instance_id, status = dde_initialize(APPCLASS_STANDARD) {|*args| }
|
83
|
+
@instance_id.should be_an Integer
|
84
|
+
@instance_id.should_not == 0
|
69
85
|
status.should == DMLERR_NO_ERROR
|
70
86
|
end
|
71
87
|
|
72
88
|
it 'returns error status if initialization unsuccessful' do
|
73
|
-
|
89
|
+
@instance_id, status = dde_initialize(12345, APPCLASS_STANDARD) {|*args| }
|
74
90
|
status.should == DMLERR_INVALIDPARAMETER
|
75
|
-
|
91
|
+
@instance_id.should == nil
|
76
92
|
end
|
77
93
|
|
78
94
|
it 'is able to reinitialize with correct id' do
|
79
|
-
|
80
|
-
new_id, status = dde_initialize(
|
95
|
+
@instance_id, status = dde_initialize(APPCLASS_STANDARD) {|*args| }
|
96
|
+
new_id, status = dde_initialize(@instance_id, APPCLASS_STANDARD) {|*args| }
|
81
97
|
status.should == DMLERR_NO_ERROR
|
82
|
-
new_id.should ==
|
98
|
+
new_id.should == @instance_id
|
83
99
|
end
|
84
100
|
end
|
85
101
|
|
86
102
|
context 'after initialization:' do
|
87
103
|
before(:each) {@instance_id, status = dde_initialize(APPCLASS_STANDARD) {|*args| }}
|
88
|
-
after(:each) {dde_uninitialize(@instance_id)}
|
104
|
+
after(:each) {dde_uninitialize(@instance_id) if @instance_id}
|
89
105
|
|
90
106
|
describe '#dde_uninitialize' do
|
91
107
|
|
@@ -101,47 +117,50 @@ module WinDDETest
|
|
101
117
|
res = dde_uninitialize(12345)
|
102
118
|
res.should == false
|
103
119
|
end
|
104
|
-
end
|
120
|
+
end # describe '#dde_uninitialize'
|
105
121
|
|
106
122
|
describe '#dde_create_string_handle' do
|
107
|
-
|
108
|
-
|
123
|
+
after(:each) {dde_free_string_handle(@instance_id, @string_handle) if @string_handle}
|
124
|
+
|
125
|
+
spec{ use{ @string_handle = DdeCreateStringHandle(instance_id=0, string_pointer, code_page_id=CP_WINANSI) }}
|
126
|
+
spec{ use{ @string_handle = dde_create_string_handle(instance_id=0, string='Any String', code_page_id=CP_WINANSI)}}
|
109
127
|
|
110
128
|
it 'returns nonzero Integer handle to a string (passable to other DDEML functions)' do
|
111
|
-
string_handle = dde_create_string_handle(@instance_id, 'My String', CP_WINANSI)
|
112
|
-
string_handle.should be_an Integer
|
113
|
-
string_handle.should_not == 0
|
129
|
+
@string_handle = dde_create_string_handle(@instance_id, 'My String', CP_WINANSI)
|
130
|
+
@string_handle.should be_an Integer
|
131
|
+
@string_handle.should_not == 0
|
114
132
|
end
|
115
133
|
|
116
134
|
it 'creates handle even if code_page is omitted' do
|
117
|
-
string_handle = dde_create_string_handle(@instance_id, 'My String')
|
118
|
-
string_handle.should be_an Integer
|
119
|
-
string_handle.should_not == 0
|
135
|
+
@string_handle = dde_create_string_handle(@instance_id, 'My String')
|
136
|
+
@string_handle.should be_an Integer
|
137
|
+
@string_handle.should_not == 0
|
120
138
|
end
|
121
139
|
|
122
140
|
it 'creating two handles for the SAME string (inside one instance) USUALLY returns same handle' do
|
123
|
-
|
141
|
+
@string_handle = dde_create_string_handle(@instance_id, 'My String')
|
124
142
|
10.times do
|
125
|
-
|
126
|
-
string_handle1.should ==
|
143
|
+
string_handle1 = dde_create_string_handle(@instance_id, 'My String')
|
144
|
+
string_handle1.should == @string_handle
|
145
|
+
dde_free_string_handle(@instance_id, string_handle1)
|
127
146
|
end
|
128
147
|
end
|
129
148
|
|
130
149
|
it 'created different handles for two different strings ' do
|
131
|
-
|
132
|
-
|
133
|
-
string_handle1.should_not ==
|
150
|
+
@string_handle = dde_create_string_handle(@instance_id, 'My String')
|
151
|
+
string_handle1 = dde_create_string_handle(@instance_id, 'My String1')
|
152
|
+
string_handle1.should_not == @string_handle
|
153
|
+
dde_free_string_handle(@instance_id, string_handle1)
|
134
154
|
end
|
135
155
|
|
136
156
|
it 'returns nil if unable to register handle to a string' do
|
137
|
-
string_handle = dde_create_string_handle(@instance_id, "", CP_WINANSI)
|
138
|
-
string_handle.should == nil
|
157
|
+
@string_handle = dde_create_string_handle(@instance_id, "", CP_WINANSI)
|
158
|
+
@string_handle.should == nil
|
139
159
|
end
|
160
|
+
end # describe '#dde_create_string_handle'
|
140
161
|
|
141
|
-
|
142
|
-
|
143
|
-
context "with dde string handle to 'My String':" do
|
144
|
-
before(:each) {@string_handle = dde_create_string_handle(@instance_id, 'My String', CP_WINANSI)}
|
162
|
+
context "with dde string handle to 'My String 2'" do
|
163
|
+
before(:each) {@string_handle = dde_create_string_handle(@instance_id, 'My String 2', CP_WINANSI)}
|
145
164
|
after(:each) {dde_free_string_handle(@instance_id, @string_handle)}
|
146
165
|
|
147
166
|
describe '#dde_query_string' do
|
@@ -151,19 +170,19 @@ module WinDDETest
|
|
151
170
|
|
152
171
|
it 'retrieves string that given string handle refers to' do
|
153
172
|
string = dde_query_string(@instance_id, @string_handle)
|
154
|
-
string.should == 'My String'
|
173
|
+
string.should == 'My String 2'
|
155
174
|
end
|
156
175
|
|
157
176
|
it 'retrieves string even if code_page is omitted' do
|
158
177
|
string = dde_query_string(@instance_id, @string_handle)
|
159
|
-
string.should == 'My String'
|
178
|
+
string.should == 'My String 2'
|
160
179
|
end
|
161
180
|
|
162
181
|
it 'returns nil attempting to retrieve invalid handle' do
|
163
182
|
string = dde_query_string(@instance_id, 12345)
|
164
183
|
string.should == nil
|
165
184
|
end
|
166
|
-
end
|
185
|
+
end # describe '#dde_query_string'
|
167
186
|
|
168
187
|
describe '#dde_free_string_handle' do
|
169
188
|
|
@@ -179,21 +198,35 @@ module WinDDETest
|
|
179
198
|
res = dde_free_string_handle(@instance_id, 12345)
|
180
199
|
res.should == false
|
181
200
|
end
|
182
|
-
|
201
|
+
|
202
|
+
it 'keeps string accessible if there are more handles to it around' do
|
203
|
+
string_handle_1 = dde_create_string_handle(@instance_id, 'My String 2', CP_WINANSI)
|
204
|
+
|
205
|
+
dde_free_string_handle(@instance_id, @string_handle)
|
206
|
+
|
207
|
+
dde_query_string(@instance_id, @string_handle).should == 'My String 2'
|
208
|
+
dde_free_string_handle(@instance_id, string_handle_1)
|
209
|
+
end
|
210
|
+
|
211
|
+
it 'makes string inaccessible once its last handle is freed' do
|
212
|
+
dde_free_string_handle(@instance_id, @string_handle)
|
213
|
+
|
214
|
+
dde_query_string(@instance_id, @string_handle).should == nil
|
215
|
+
end
|
216
|
+
end # describe '#dde_free_string_handle'
|
183
217
|
|
184
218
|
describe '#dde_name_service' do
|
185
219
|
spec{ use{ success = dde_name_service(@instance_id, @string_handle, cmd=DNS_UNREGISTER ) }}
|
186
220
|
spec{ use{ success = DdeNameService(@instance_id, @string_handle, reserved=0, cmd=DNS_UNREGISTER) }}
|
187
221
|
|
188
222
|
it 'registers or unregisters the service names that DDE server supports' do
|
189
|
-
|
190
223
|
success = dde_name_service( @instance_id, @string_handle, DNS_REGISTER )
|
191
224
|
success.should == true
|
192
225
|
|
193
226
|
success = dde_name_service( @instance_id, @string_handle, DNS_UNREGISTER )
|
194
227
|
success.should == true
|
195
228
|
end
|
196
|
-
end
|
229
|
+
end # describe '#dde_name_service'
|
197
230
|
|
198
231
|
describe '#dde_get_last_error' do
|
199
232
|
spec{ use{ error_code = DdeGetLastError( @instance_id) }}
|
@@ -211,9 +244,109 @@ module WinDDETest
|
|
211
244
|
dde_name_service( @instance_id, 1234, DNS_REGISTER )
|
212
245
|
dde_get_last_error( @instance_id).should == DMLERR_INVALIDPARAMETER
|
213
246
|
end
|
214
|
-
end
|
247
|
+
end # describe '#dde_get_last_error'
|
248
|
+
|
249
|
+
end # context "with dde string handle to 'My String'"
|
250
|
+
end # context 'after initialization:'
|
251
|
+
|
252
|
+
context 'with synthetic DDE client/server' do
|
253
|
+
before(:each) do
|
254
|
+
@client_calls = []
|
255
|
+
@server_calls = []
|
256
|
+
@client_id, status = dde_initialize(APPCLASS_STANDARD) {|*args| @client_calls << extract_values(*args); 1}
|
257
|
+
@server_id, status = dde_initialize(APPCLASS_STANDARD) {|*args| @server_calls << extract_values(*args); 1}
|
258
|
+
@service_handle = dde_create_string_handle(@server_id, 'service 2', CP_WINANSI)
|
259
|
+
@topic_handle = dde_create_string_handle(@client_id, 'topic 2', CP_WINANSI)
|
260
|
+
dde_name_service(@server_id, @service_handle, DNS_REGISTER)
|
261
|
+
end
|
262
|
+
|
263
|
+
after(:each) do
|
264
|
+
# p @server_calls, @client_calls, @server_conv
|
265
|
+
# p ERRORS[dde_get_last_error(@server_id)]
|
266
|
+
# p ERRORS[dde_get_last_error(@client_id)]
|
215
267
|
|
268
|
+
dde_name_service(@server_id, @service_handle, DNS_UNREGISTER)
|
269
|
+
dde_free_string_handle(@server_id, @service_handle)
|
270
|
+
dde_free_string_handle(@client_id, @topic_handle)
|
271
|
+
dde_uninitialize(@client_id)
|
272
|
+
dde_uninitialize(@server_id)
|
216
273
|
end
|
274
|
+
|
275
|
+
describe '#dde_connect' do
|
276
|
+
after(:each) { dde_disconnect(@conv_handle) if @conv_handle}
|
277
|
+
spec{ use{ @conv_handle = DdeConnect( instance_id=0, service=0, topic=0, context=nil) }}
|
278
|
+
spec{ use{ @conv_handle = dde_connect( instance_id=0, service=0, topic=0, context=nil) }}
|
279
|
+
|
280
|
+
it 'connects to existing DDE server (self in this case)' do
|
281
|
+
@conv_handle = dde_connect( @server_id, @service_handle, @topic_handle, context=nil)
|
282
|
+
|
283
|
+
@server_calls.first[0].should == 'XTYP_CONNECT'
|
284
|
+
@server_calls.first[3].should == 'topic 2'
|
285
|
+
@server_calls.first[4].should == 'service 2'
|
286
|
+
@server_calls[1][0].should == 'XTYP_CONNECT_CONFIRM'
|
287
|
+
@server_calls[1][3].should == 'topic 2'
|
288
|
+
@server_calls[1][4].should == 'service 2'
|
289
|
+
dde_disconnect(@server_conv).should == true
|
290
|
+
dde_disconnect(@conv_handle).should == true
|
291
|
+
|
292
|
+
p @server_calls, @client_calls, @conv_handle, @server_conv
|
293
|
+
p ERRORS[dde_get_last_error(@server_id)]
|
294
|
+
p ERRORS[dde_get_last_error(@client_id)]
|
295
|
+
end
|
296
|
+
|
297
|
+
it 'connects to existing DDE server (NOT self)' do
|
298
|
+
pending 'something is wrong when connecting to separate service instance, uninitialize fails'
|
299
|
+
conv_handle = dde_connect( @client_id, @service_handle, @topic_handle, context=nil)
|
300
|
+
puts conv_handle
|
301
|
+
p @server_calls, @client_calls, @server_conv
|
302
|
+
p dde_disconnect(@server_conv) #conv_handle)
|
303
|
+
# p @server_calls, @client_calls
|
304
|
+
end
|
305
|
+
end # describe '#dde_connect'
|
306
|
+
|
307
|
+
describe '#dde_disconnect' do
|
308
|
+
spec{ use{ success = DdeDisconnect(conversation_handle=0) }}
|
309
|
+
spec{ use{ success = dde_disconnect(conversation_handle=0) }}
|
310
|
+
|
311
|
+
it 'fails to disconnect if not valid conversation handle given' do
|
312
|
+
dde_disconnect(12345).should == false
|
313
|
+
end
|
314
|
+
|
315
|
+
it 'disconnects from existing DDE server' do
|
316
|
+
pending 'XTYP_DISCONNECT is not received by server callback for some reason'
|
317
|
+
end
|
318
|
+
end # describe '#dde_disconnect'
|
319
|
+
|
320
|
+
describe "#dde_client_transaction" do
|
321
|
+
after(:each) do
|
322
|
+
p @server_calls, @client_calls, @server_conv
|
323
|
+
p ERRORS[dde_get_last_error(@server_id)]
|
324
|
+
p ERRORS[dde_get_last_error(@client_id)]
|
325
|
+
end
|
326
|
+
|
327
|
+
spec{ use{ res = DdeClientTransaction(data=nil, size=0, conv=0, item=0, format=0, type=0, timeout=0, result=nil) }}
|
328
|
+
spec{ use{ res = dde_client_transaction(data=nil, size=0, conv=0, item=0, format=0, type=0, timeout=0, result=nil) }}
|
329
|
+
|
330
|
+
it "original api is used by CLIENT to begins a data transaction with server" do
|
331
|
+
# pending 'weird error - wrong number of arguments (8 for 0)'
|
332
|
+
p @conv_handle = dde_connect( @server_id, @service_handle, @topic_handle, context=nil)
|
333
|
+
str = FFI::MemoryPointer.from_string "Poke_string\n\x00\x00"
|
334
|
+
# res = DdeClientTransaction(str, str.size, @conv_handle, @topic_handle, CF_TEXT, XTYP_POKE, 1000, nil)
|
335
|
+
begin
|
336
|
+
get_message() if peek_message()
|
337
|
+
res = DdeClientTransaction(str, str.size, @conv_handle, @topic_handle, 0, XTYP_EXECUTE, 1000, nil)
|
338
|
+
p res
|
339
|
+
rescue => e
|
340
|
+
puts e.backtrace
|
341
|
+
raise e
|
342
|
+
end
|
343
|
+
end
|
344
|
+
|
345
|
+
it "snake_case api begins a data transaction between a client and a server. Only a Dynamic Data Exchange (DDE) client " do
|
346
|
+
pending
|
347
|
+
success = dde_client_transaction(p_data=0, cb_data=0, h_conv=0, hsz_item=0, w_fmt=0, w_type=0, dw_timeout=0, pdw_result=0)
|
348
|
+
end
|
349
|
+
end # describe dde_client_transaction
|
217
350
|
|
218
351
|
describe '#dde_get_data' do
|
219
352
|
spec{ use{ buffer, success = dde_get_data( data_handle = 123, max = 1073741823, offset = 0) }}
|
@@ -228,21 +361,18 @@ module WinDDETest
|
|
228
361
|
dde_get_data( data_handle = 123, 3741823, 0).should == nil
|
229
362
|
end
|
230
363
|
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
spec{ use{ conversation_handle = dde_connect( instance_id=0, service=0, topic=0, context=nil) }}
|
364
|
+
it 'original API returns 1 if connect successful' do
|
365
|
+
pending
|
366
|
+
DdeGetData( data_handle = 123, nil, 0, 0).should == 0
|
367
|
+
end
|
236
368
|
|
237
|
-
it '
|
238
|
-
|
369
|
+
it 'snake_case API returns returns true if connect successful' do
|
370
|
+
pending
|
371
|
+
dde_get_data( data_handle = 123, 3741823, 0).should == nil
|
372
|
+
end
|
239
373
|
|
240
|
-
describe '#
|
241
|
-
spec{ use{ success = DdeDisconnect(conversation_handle=0) }}
|
242
|
-
spec{ use{ success = dde_disconnect(conversation_handle=0) }}
|
374
|
+
end # describe '#dde_get_data'
|
243
375
|
|
244
|
-
|
245
|
-
end
|
246
|
-
end
|
376
|
+
end # context 'with synthetic DDE server'
|
247
377
|
end
|
248
|
-
end
|
378
|
+
end
|
@@ -1,37 +1,78 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
2
|
require 'win/gui/input'
|
3
|
-
|
3
|
+
require 'win/error'
|
4
4
|
|
5
5
|
module WinGUIMessageTest
|
6
6
|
|
7
7
|
include WinTestApp
|
8
8
|
include Win::GUI::Message
|
9
9
|
include Win::GUI::Window
|
10
|
+
include Win::GUI::Input
|
11
|
+
include Win::Error
|
12
|
+
|
13
|
+
def buffer
|
14
|
+
@buffer ||= FFI::MemoryPointer.new :char, 1024
|
15
|
+
end
|
16
|
+
|
17
|
+
def msg
|
18
|
+
@msg ||=Win::GUI::Message::Msg.new
|
19
|
+
end
|
20
|
+
|
21
|
+
def msg_callback
|
22
|
+
lambda {|handle, message, data, result| @handle = handle; @message = message; @data = data; @result = result }
|
23
|
+
end
|
24
|
+
|
25
|
+
def should_have msg, members
|
26
|
+
members.each do |member, value|
|
27
|
+
case member
|
28
|
+
when :l_param
|
29
|
+
msg[member].address.should == value
|
30
|
+
when :time
|
31
|
+
msg[member].should be > value
|
32
|
+
else
|
33
|
+
msg[member].should == value
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def clear_thread_queue
|
39
|
+
get_message while peek_message
|
40
|
+
end
|
10
41
|
|
11
42
|
describe Win::GUI::Message, ' defines a set of API functions related to Window messaging' do
|
12
|
-
|
43
|
+
before(:all){clear_thread_queue}
|
13
44
|
|
14
45
|
describe '#post_message' do
|
46
|
+
before(:each){clear_thread_queue}
|
47
|
+
after(:all){close_test_app if @launched_test_app}
|
48
|
+
|
15
49
|
spec{ use{ success = PostMessage(handle = 0, msg = 0, w_param = 0, l_param = nil) }}
|
16
50
|
spec{ use{ success = post_message(handle = 0, msg = 0, w_param = 0, l_param = nil) }}
|
17
51
|
|
18
52
|
it 'places (posts) a message in the message queue associated with the thread that created the specified window' do
|
19
53
|
app = launch_test_app
|
20
|
-
post_message(app.handle, WM_SYSCOMMAND, SC_CLOSE, nil)
|
54
|
+
post_message(app.handle, WM_SYSCOMMAND, SC_CLOSE, nil).should == true
|
21
55
|
sleep TEST_SLEEP_DELAY
|
22
56
|
window?(app.handle).should == false
|
23
57
|
end
|
24
58
|
|
59
|
+
it 'places (posts) a message into current thread`s queue if first arg is 0' do
|
60
|
+
post_message(0, WM_USER, 33, nil).should == true
|
61
|
+
msg = get_message()
|
62
|
+
should_have msg, hwnd: 0, message: WM_USER, w_param: 33, l_param: 0
|
63
|
+
end
|
64
|
+
|
25
65
|
it 'returns without waiting for the thread to process the message'
|
66
|
+
|
26
67
|
end # describe '#post_message'
|
27
68
|
|
28
69
|
describe '#send_message' do
|
29
|
-
spec{ use{ success = SendMessage(handle = 0, msg = 0, w_param =
|
30
|
-
spec{ use{ success = send_message(handle = 0, msg = 0, w_param =
|
70
|
+
spec{ use{ success = SendMessage(handle = 0, msg = 0, w_param = 0, l_param = nil) }}
|
71
|
+
spec{ use{ success = send_message(handle = 0, msg = 0, w_param = 0, l_param = nil) }}
|
31
72
|
|
32
|
-
it 'sends the specified message to a window or windows' do
|
73
|
+
it 'directly sends the specified message to a window or windows' do
|
33
74
|
app = launch_test_app
|
34
|
-
|
75
|
+
|
35
76
|
num_chars = send_message app.handle, WM_GETTEXT, buffer.size, buffer
|
36
77
|
buffer.get_bytes(0, num_chars).should == "LockNote - Steganos LockNote"
|
37
78
|
|
@@ -39,10 +80,156 @@ module WinGUIMessageTest
|
|
39
80
|
buffer.get_bytes(0, num_chars).should =~ /Welcome to Steganos LockNote/
|
40
81
|
|
41
82
|
send_message(app.handle, WM_SYSCOMMAND, SC_CLOSE, nil)
|
42
|
-
sleep TEST_SLEEP_DELAY
|
83
|
+
sleep TEST_SLEEP_DELAY # delay to allow window close
|
43
84
|
window?(app.handle).should == false
|
44
85
|
end
|
45
86
|
end # describe '#send_message'
|
87
|
+
|
88
|
+
# :call-seq:
|
89
|
+
# success = send_message_callback(handle, msg, w_param, l_param, data)
|
90
|
+
# {|handle, msg, data, l_result| callback code }
|
91
|
+
|
92
|
+
describe "#send_message_callback" do
|
93
|
+
before(:all){@app=launch_test_app}
|
94
|
+
after(:all){close_test_app if @launched_test_app}
|
95
|
+
|
96
|
+
spec{ use{ success = SendMessageCallback(h_wnd=0, msg=0, w_param=0, l_param=nil, msg_callback, data=0) }}
|
97
|
+
spec{ use{ success = send_message_callback(h_wnd=0, msg=0, w_param=0, l_param=nil, data=0, &msg_callback) }}
|
98
|
+
|
99
|
+
it "sends message to window and returns, specifying callback to be called by system after message is processed" do
|
100
|
+
sent = SendMessageCallback(@app.handle, WM_USER, 0, nil, msg_callback, data=13)
|
101
|
+
sent.should == 1
|
102
|
+
@handle.should == nil
|
103
|
+
@message.should == nil
|
104
|
+
@data.should == nil
|
105
|
+
@result.should == nil
|
106
|
+
|
107
|
+
sleep TEST_SLEEP_DELAY # small delay to allow message delivery
|
108
|
+
peek_message # dispatching sent message (even though there is nothing in queue)
|
109
|
+
|
110
|
+
@handle.should == @app.handle
|
111
|
+
@message.should == WM_USER
|
112
|
+
@data.should == 13
|
113
|
+
@result.should == 0
|
114
|
+
end
|
115
|
+
|
116
|
+
it "snake_case api defaults data to 0, converts block into callback and returns true/false" do
|
117
|
+
sent = send_message_callback(@app.handle, WM_USER, 0, nil){|*args|@data=args[2]}
|
118
|
+
sent.should == true
|
119
|
+
@data.should == nil
|
120
|
+
|
121
|
+
sleep TEST_SLEEP_DELAY # small delay to allow message delivery
|
122
|
+
peek_message # dispatching sent message (even though there is nothing in queue)
|
123
|
+
|
124
|
+
@data.should == 0
|
125
|
+
end
|
126
|
+
|
127
|
+
it "fails if unable to send message" do
|
128
|
+
sent = SendMessageCallback(not_a_handle, WM_USER, 0, nil, msg_callback, 0)
|
129
|
+
sent.should == 0
|
130
|
+
send_message_callback(not_a_handle, WM_USER, 0, nil){|*args|@data=args[2]}
|
131
|
+
sent.should == 0
|
132
|
+
get_last_error.should == "Invalid window handle."
|
133
|
+
end
|
134
|
+
end # describe send_message_callback
|
135
|
+
|
136
|
+
describe "#get_message" do
|
137
|
+
before(:all){clear_thread_queue; 2.times {post_message 0,0,0,nil}}
|
138
|
+
|
139
|
+
spec{ use{ res = GetMessage(msg, handle=0, msg_filter_min=0, msg_filter_max=0) }}
|
140
|
+
spec{ use{ message = get_message(msg, handle=0, msg_filter_min=0, msg_filter_max=0) }}
|
141
|
+
|
142
|
+
it "original api retrieves a message from the calling thread's message queue" do
|
143
|
+
set_cursor_pos(x=0, y=0)
|
144
|
+
post_message(0, WM_USER+1, 33, nil)
|
145
|
+
res = GetMessage(msg, handle=0, msg_filter_min=0, msg_filter_max=0)
|
146
|
+
res.should == 1
|
147
|
+
# p msg[:hwnd], msg[:message], msg[:w_param], msg[:l_param], msg[:time], msg[:x], msg[:y]
|
148
|
+
should_have msg, hwnd: 0, message: WM_USER+1, w_param: 33, x: 0, y: 0, l_param: 0, time: 1000000
|
149
|
+
end
|
150
|
+
|
151
|
+
it "original api returns -1 if there is an error (wrong handle, in this case)" do
|
152
|
+
res = GetMessage(msg, not_a_handle, msg_filter_min=0, msg_filter_max=0)
|
153
|
+
res.should == -1
|
154
|
+
end
|
155
|
+
|
156
|
+
it "original api returns 0 if WM_QUIT was posted to thread`s message queue" do
|
157
|
+
post_message(0, WM_QUIT, 13, nil)
|
158
|
+
res = GetMessage(msg, 0, msg_filter_min=0, msg_filter_max=0)
|
159
|
+
res.should == 0
|
160
|
+
end
|
161
|
+
|
162
|
+
it "snake_case api returns a message struct retrieved from the calling thread's message queue " do
|
163
|
+
set_cursor_pos(x=99, y=99)
|
164
|
+
post_message(0, WM_USER+2, 33, nil)
|
165
|
+
msg = get_message()
|
166
|
+
should_have msg, hwnd: 0, message: WM_USER+2, w_param: 33, x: 99, y: 99, l_param: 0, time: 1000000
|
167
|
+
end
|
168
|
+
|
169
|
+
it "snake_case api returns nil if there is an error (wrong handle, in this case)" do
|
170
|
+
get_message(msg, not_a_handle).should == nil
|
171
|
+
end
|
172
|
+
|
173
|
+
it "snake_case api returns false if WM_QUIT was posted to thread`s message queue" do
|
174
|
+
post_message(0, WM_QUIT, 13, nil)
|
175
|
+
get_message.should == false
|
176
|
+
end
|
177
|
+
end # describe get_message
|
178
|
+
|
179
|
+
|
180
|
+
describe "#peek_message" do
|
181
|
+
before(:all){set_cursor_pos(x=0, y=0); post_message(0, WM_USER+2, 13, nil)}
|
182
|
+
spec{ use{ success = PeekMessage(msg, h_wnd=0, filter_min=0, filter_max=0, remove_msg=0) }}
|
183
|
+
spec{ use{ success = peek_message(msg, h_wnd=0, filter_min=0, filter_max=0, remove_msg=0) }}
|
184
|
+
|
185
|
+
it "original api checks the thread message queue for a posted message, retrieves it without removing" do
|
186
|
+
10.times do
|
187
|
+
res = PeekMessage(msg, h_wnd=0, filter_min=0, filter_max=0, remove_msg=0)
|
188
|
+
res.should == 1
|
189
|
+
should_have msg, hwnd: 0, message: WM_USER+2, w_param: 13, x: 0, y: 0, l_param: 0, time: 1000000
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
it "snake_case api checks the thread message queue for a posted message, returns it without removing" do
|
194
|
+
10.times do
|
195
|
+
msg = peek_message()
|
196
|
+
should_have msg, hwnd: 0, message: WM_USER+2, w_param: 13, x: 0, y: 0, l_param: 0, time: 1000000
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
it "original api returns 0 if no message in queue" do
|
201
|
+
get_message
|
202
|
+
PeekMessage(msg, h_wnd=0, filter_min=0, filter_max=0, remove_msg=0).should == 0
|
203
|
+
end
|
204
|
+
|
205
|
+
it "snake_case api returns nil if no message in queue" do
|
206
|
+
peek_message.should == nil
|
207
|
+
end
|
208
|
+
end # describe peek_message
|
209
|
+
|
210
|
+
describe "#translate_message" do
|
211
|
+
spec{ use{ success = TranslateMessage(msg) }}
|
212
|
+
spec{ use{ success = translate_message(msg) }}
|
213
|
+
|
214
|
+
it "translates virtual-key message into character message which is then posted to the thread's message queue"
|
215
|
+
|
216
|
+
it "returns zero/false if no translation took place" do
|
217
|
+
TranslateMessage(msg).should == 0
|
218
|
+
translate_message(msg).should == false
|
219
|
+
end
|
220
|
+
end # describe translate_message
|
221
|
+
|
222
|
+
describe "#dispatch_message" do
|
223
|
+
spec{ use{ res = DispatchMessage(msg) }} #return value is normally ignored
|
224
|
+
spec{ use{ res = dispatch_message(msg) }} #return value is normally ignored
|
225
|
+
|
226
|
+
it "dispatches a message to a window procedure. Typically used to dispatch a message retrieved by GetMessage" do
|
227
|
+
pending
|
228
|
+
res = DispatchMessage(msg)
|
229
|
+
end
|
230
|
+
|
231
|
+
end # describe dispatch_message
|
232
|
+
|
46
233
|
end # Win::GUI::Message, ' defines a set of API functions related to Window messaging'
|
47
234
|
end
|
48
235
|
|
data/win.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{win}
|
8
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.22"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["arvicco"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-03-06}
|
13
13
|
s.description = %q{Rubyesque interfaces and wrappers for Windows API functions pre-defined using FFI }
|
14
14
|
s.email = %q{arvitallian@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: win
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.22
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- arvicco
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-
|
12
|
+
date: 2010-03-06 00:00:00 +03:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|