win 0.0.4 → 0.0.6
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/README.rdoc +12 -13
- data/Rakefile +3 -2
- data/VERSION +1 -1
- data/lib/win/dde.rb +223 -0
- data/lib/win/library.rb +162 -151
- data/lib/win/window/extra.rb +113 -0
- data/lib/win/window.rb +280 -222
- data/spec/spec_helper.rb +15 -7
- data/spec/win/dde_spec.rb +68 -0
- data/spec/win/window/extra_spec.rb +181 -0
- data/spec/win/window_spec.rb +232 -5
- data/win.gemspec +13 -4
- metadata +20 -4
@@ -0,0 +1,68 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
require 'win/dde'
|
3
|
+
|
4
|
+
module WinDDETest
|
5
|
+
include WinTest
|
6
|
+
include Win::DDE
|
7
|
+
|
8
|
+
def dde_cmd
|
9
|
+
APPCLASS_STANDARD
|
10
|
+
end
|
11
|
+
|
12
|
+
def dde_callback
|
13
|
+
->{}
|
14
|
+
end
|
15
|
+
|
16
|
+
describe Win::DDE, ' contains a set of pre-defined Windows API functions' do
|
17
|
+
describe 'register_clipboard_format' do
|
18
|
+
spec{ use{ RegisterClipboardFormat(format_name = "XlTable") }}
|
19
|
+
spec{ use{ register_clipboard_format(format_name = "XlTable") }}
|
20
|
+
|
21
|
+
it 'returns format id (int) if successfully registered format' do
|
22
|
+
id = register_clipboard_format("XlTable")
|
23
|
+
id.should_not == 0
|
24
|
+
id.should_not == nil
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'returns same format id for already registered format' do
|
28
|
+
id1 = register_clipboard_format("XlTable")
|
29
|
+
id2 = register_clipboard_format("XlTable")
|
30
|
+
id1.should == id2
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'returns nil if not able to register format' do
|
34
|
+
register_clipboard_format("").should == nil
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe 'dde_initialize' do
|
39
|
+
spec{ use{ status = DdeInitialize( id = [0].pack('L'), dde_callback, dde_cmd, unused = 0)}}
|
40
|
+
spec{ use{ id, status = dde_initialize( id = 0, dde_cmd) do|*args| end }}
|
41
|
+
|
42
|
+
it 'returns integer id and 0 if initialization successful' do
|
43
|
+
id, status = dde_initialize(APPCLASS_STANDARD) {|*args| }
|
44
|
+
id.should be_an Integer
|
45
|
+
id.should_not == 0
|
46
|
+
status.should == DMLERR_NO_ERROR
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'returns error status if initialization unsuccessful' do
|
50
|
+
id, status = dde_initialize(1, APPCLASS_STANDARD) {|*args| }
|
51
|
+
status.should == DMLERR_INVALIDPARAMETER
|
52
|
+
id.should == nil
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'is able to reinitialize with correct id' do
|
56
|
+
id, status = dde_initialize(APPCLASS_STANDARD) {|*args| }
|
57
|
+
new_id, status = dde_initialize(id, APPCLASS_STANDARD) {|*args| }
|
58
|
+
status.should == DMLERR_NO_ERROR
|
59
|
+
new_id.should == id
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'returns nil if not able to initialize' do
|
63
|
+
pending
|
64
|
+
register_clipboard_format("").should == nil
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,181 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
require 'win/window'
|
3
|
+
require 'win/window/extra'
|
4
|
+
|
5
|
+
module WinWindowTest
|
6
|
+
include WinTest
|
7
|
+
include Win::Window
|
8
|
+
|
9
|
+
describe Win::Window, ' extra convenience/service methods' do
|
10
|
+
describe '#keystroke' do
|
11
|
+
spec{ use{ keystroke( vkey = 30, vkey = 30) }}
|
12
|
+
# this service method emulates combinations of (any amount of) keys pressed one after another (Ctrl+Alt+P) and then released
|
13
|
+
# vkey (int) - Specifies a virtual-key code. The code must be a value in the range 1 to 254. For a complete list, see msdn:Virtual Key Codes.
|
14
|
+
|
15
|
+
it 'emulates combinations of keys pressed (Ctrl+Alt+P+M, etc)' do
|
16
|
+
test_app do |app|
|
17
|
+
keystroke(VK_CONTROL, 'A'.ord)
|
18
|
+
keystroke(VK_SPACE)
|
19
|
+
app.textarea.text.should == ' '
|
20
|
+
2.times {keystroke(VK_CONTROL, 'Z'.ord)} # dirty hack!
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe '#type_in' do
|
26
|
+
spec{ use{ type_in(message = '') }}
|
27
|
+
# this service method types text message into window holding the focus
|
28
|
+
|
29
|
+
it 'types text message into window holding the focus' do
|
30
|
+
test_app do |app|
|
31
|
+
text = '123 456'
|
32
|
+
type_in(text)
|
33
|
+
app.textarea.text.should =~ Regexp.new(text)
|
34
|
+
7.times {keystroke(VK_CONTROL, 'Z'.ord)} # dirty hack!
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe 'dialog' do
|
40
|
+
spec{ use{ dialog( title ='Dialog Title', timeout_sec = 0.001, &any_block) }}
|
41
|
+
# me od finds top-level dialog window by title and yields found dialog window to block if given
|
42
|
+
|
43
|
+
it 'finds top-level dialog window by title' do
|
44
|
+
pending 'Some problems (?with timeouts?) leave window open ~half of the runs'
|
45
|
+
test_app do |app|
|
46
|
+
keystroke(VK_ALT, 'F'.ord, 'A'.ord)
|
47
|
+
@found = false
|
48
|
+
dialog('Save As', 0.5) do |dialog_window|
|
49
|
+
@found = true
|
50
|
+
keystroke(VK_ESCAPE)
|
51
|
+
dialog_window
|
52
|
+
end
|
53
|
+
@found.should == true
|
54
|
+
end
|
55
|
+
end
|
56
|
+
it 'yields found dialog window to a given block'
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
describe Win::Window::Window, ' wrapper class for window handle' do
|
62
|
+
before(:each) { @app = launch_test_app }
|
63
|
+
after(:each){ close_test_app }
|
64
|
+
|
65
|
+
context 'creating' do
|
66
|
+
it 'can be wrapped around any existing window' do
|
67
|
+
any_handle = find_window(nil, nil)
|
68
|
+
use{ Window.new any_handle }
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'can be wrapped around specific window' do
|
72
|
+
use{ Window.new @app.handle }
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context 'manipulating' do
|
77
|
+
|
78
|
+
it 'has handle property equal to underlying window handle' do
|
79
|
+
any_handle = find_window(nil, nil)
|
80
|
+
any = Window.new any_handle
|
81
|
+
any.handle.should == any_handle
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'has text property equal to underlying window text(title)' do
|
85
|
+
@app.text.should == TEST_WIN_TITLE
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'closes when asked nicely' do
|
89
|
+
@app.close
|
90
|
+
sleep TEST_SLEEP_DELAY # needed to ensure window had enough time to close down
|
91
|
+
find_window(nil, TEST_WIN_TITLE).should == nil #!!!!
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'waits f0r window to disappear (NB: this happens before handle is released!)' do
|
95
|
+
start = Time.now
|
96
|
+
@app.close
|
97
|
+
@app.wait_for_close
|
98
|
+
(Time.now - start).should be <= Win::Window::CLOSE_TIMEOUT
|
99
|
+
window_visible?(@app.handle).should be false
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
context '.top_level class method' do
|
104
|
+
it 'finds any top-level window (title = nil) and wraps it in a Window object' do
|
105
|
+
use { @win = Window.top_level(title = nil, timeout_sec = 3) }
|
106
|
+
Window.should === @win
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'finds top-level window by title and wraps it in a Window object' do
|
110
|
+
win = Window.top_level( TEST_WIN_TITLE, 1)
|
111
|
+
win.handle.should == @app.handle
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
context '#child' do
|
116
|
+
spec { use { @control = @app.child(title_class_id = nil) }}
|
117
|
+
|
118
|
+
it 'finds any child window(control) if given nil' do
|
119
|
+
@app.child(nil).should_not == nil
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'finds child window(control) by class' do
|
123
|
+
@app.child(TEST_TEXTAREA_CLASS).should_not == nil
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'finds child window(control) by name' do
|
127
|
+
pending 'Need to find control with short name'
|
128
|
+
@app.child(TEST_TEXTAREA_TEXT).should_not == nil
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'finds child window(control) by control ID' do
|
132
|
+
pending 'Need to find some control ID'
|
133
|
+
@app.child(TEST_TEXTAREA_ID).should_not == nil
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'raises error if wrong control is given' do
|
137
|
+
expect { @app.child('Impossible Control')}.to raise_error "Control 'Impossible Control' not found"
|
138
|
+
end
|
139
|
+
it 'substitutes & for _ when searching by title ("&Yes" type controls)'
|
140
|
+
|
141
|
+
end
|
142
|
+
|
143
|
+
context '#children' do
|
144
|
+
spec { use { children = @app.children }}
|
145
|
+
|
146
|
+
it 'returns an array' do
|
147
|
+
@app.children.should be_a_kind_of(Array)
|
148
|
+
end
|
149
|
+
|
150
|
+
it 'returns an array of all child windows to the given window ' do
|
151
|
+
children = @app.children
|
152
|
+
children.should be_a_kind_of Array
|
153
|
+
children.should_not be_empty
|
154
|
+
children.should have(2).elements
|
155
|
+
children.each{|child| child?(@app.handle, child.handle).should == true }
|
156
|
+
get_class_name(children.last.handle).should == TEST_TEXTAREA_CLASS
|
157
|
+
end
|
158
|
+
|
159
|
+
# it 'finds child window(control) by name' do
|
160
|
+
# pending 'Need to find control with short name'
|
161
|
+
# @app.child(TEST_TEXTAREA_TEXT).should_not == nil
|
162
|
+
# end
|
163
|
+
#
|
164
|
+
# it 'finds child window(control) by control ID' do
|
165
|
+
# pending 'Need to find some control ID'
|
166
|
+
# @app.child(TEST_TEXTAREA_ID).should_not == nil
|
167
|
+
# end
|
168
|
+
#
|
169
|
+
# it 'raises error if wrong control is given' do
|
170
|
+
# expect { @app.child('Impossible Control')}.to raise_error "Control 'Impossible Control' not found"
|
171
|
+
# end
|
172
|
+
# it 'substitutes & for _ when searching by title ("&Yes" type controls)'
|
173
|
+
|
174
|
+
end
|
175
|
+
|
176
|
+
context '#click' do
|
177
|
+
it 'emulates clicking of the control identified by id'
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
end
|
data/spec/win/window_spec.rb
CHANGED
@@ -9,7 +9,11 @@ module WinWindowTest
|
|
9
9
|
def launch_test_app
|
10
10
|
system TEST_APP_START
|
11
11
|
sleep TEST_SLEEP_DELAY until (handle = find_window(nil, TEST_WIN_TITLE))
|
12
|
+
|
12
13
|
@launched_test_app = Window.new handle
|
14
|
+
# app = "Test app" #need to get rid of Window for JRuby
|
15
|
+
# class << app; self; end.send( :define_method, :handle, &lambda {handle})
|
16
|
+
# @launched_test_app = app
|
13
17
|
end
|
14
18
|
|
15
19
|
def close_test_app(app = @launched_test_app)
|
@@ -30,7 +34,29 @@ module WinWindowTest
|
|
30
34
|
|
31
35
|
yield app
|
32
36
|
close_test_app
|
33
|
-
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def commands_should_show_window *cmds, tests
|
40
|
+
cmds.each do |cmd|
|
41
|
+
test_app do |app|
|
42
|
+
show_window(app.handle, cmd)
|
43
|
+
tests.each{|test, result| send(test.to_sym, app.handle).should == result}
|
44
|
+
|
45
|
+
hide_window(app.handle) # hiding window first
|
46
|
+
show_window(app.handle, cmd)
|
47
|
+
tests.each{|test, result| send(test.to_sym, app.handle).should == result}
|
48
|
+
|
49
|
+
show_window(app.handle, SW_MAXIMIZE) # now maximizing window
|
50
|
+
show_window(app.handle, cmd)
|
51
|
+
tests.each{|test, result| send(test.to_sym, app.handle).should == result}
|
52
|
+
|
53
|
+
show_window(app.handle, SW_MINIMIZE) # now minimizing window
|
54
|
+
show_window(app.handle, cmd)
|
55
|
+
tests.each{|test, result| send(test.to_sym, app.handle).should == result}
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
34
60
|
|
35
61
|
describe Win::Window, ' defines a set user32 API functions related to Window manipulation' do
|
36
62
|
describe '#window?' do
|
@@ -57,7 +83,7 @@ module WinWindowTest
|
|
57
83
|
window?(@ta_handle).should == false
|
58
84
|
end
|
59
85
|
end
|
60
|
-
|
86
|
+
|
61
87
|
describe '#window_visible?' do
|
62
88
|
spec{ use{ IsWindowVisible(any_handle) }}
|
63
89
|
spec{ use{ is_window_visible(any_handle) }}
|
@@ -105,7 +131,7 @@ module WinWindowTest
|
|
105
131
|
iconic?(app.handle).should == false
|
106
132
|
minimized?(app.handle).should == false
|
107
133
|
show_window(app.handle, SW_MINIMIZE)
|
108
|
-
iconic?(app.handle).should == true
|
134
|
+
iconic?(app.handle).should == true # !
|
109
135
|
minimized?(app.handle).should == true
|
110
136
|
end
|
111
137
|
end
|
@@ -271,9 +297,9 @@ module WinWindowTest
|
|
271
297
|
it 'returns correct window class name' do
|
272
298
|
test_app do |app|
|
273
299
|
get_class_name(app.handle).should == TEST_WIN_CLASS
|
274
|
-
get_class_name_w(app.handle).should == TEST_WIN_CLASS
|
300
|
+
get_class_name_w(app.handle).should == TEST_WIN_CLASS #!!!! nil?
|
301
|
+
class_name_w(app.handle).should == TEST_WIN_CLASS #!!!!!!! nil?
|
275
302
|
class_name(app.handle).should == TEST_WIN_CLASS
|
276
|
-
class_name_w(app.handle).should == TEST_WIN_CLASS
|
277
303
|
end
|
278
304
|
end
|
279
305
|
end
|
@@ -313,5 +339,206 @@ module WinWindowTest
|
|
313
339
|
end
|
314
340
|
end
|
315
341
|
|
342
|
+
describe '#show_window ', 'LI', 'I' do
|
343
|
+
spec{ use{ was_visible = show_window(handle = any_handle, cmd = SW_SHOWNA) }}
|
344
|
+
|
345
|
+
it 'was_visible = hide_window(handle = any_handle) # derived method (not a separate API function)' do
|
346
|
+
test_app do |app|
|
347
|
+
use{ @was_visible = hide_window(app.handle) }
|
348
|
+
@was_visible.should == true
|
349
|
+
visible?(app.handle).should == false
|
350
|
+
hide_window(app.handle).should == false
|
351
|
+
visible?(app.handle).should == false
|
352
|
+
end
|
353
|
+
end
|
354
|
+
|
355
|
+
it 'returns true if the window was PREVIOUSLY visible, false otherwise' do
|
356
|
+
test_app do |app|
|
357
|
+
show_window(app.handle, SW_HIDE).should == true
|
358
|
+
show_window(app.handle, SW_HIDE).should == false
|
359
|
+
end
|
360
|
+
end
|
361
|
+
|
362
|
+
it 'hides window with SW_HIDE command ' do
|
363
|
+
test_app do |app|
|
364
|
+
show_window(app.handle, SW_HIDE)
|
365
|
+
visible?(app.handle).should == false
|
366
|
+
end
|
367
|
+
end
|
368
|
+
|
369
|
+
it 'shows hidden window with SW_SHOW command' do
|
370
|
+
test_app do |app|
|
371
|
+
hide_window(app.handle)
|
372
|
+
show_window(app.handle, SW_SHOW)
|
373
|
+
visible?(app.handle).should == true
|
374
|
+
end
|
375
|
+
end
|
376
|
+
|
377
|
+
it 'SW_MAXIMIZE, SW_SHOWMAXIMIZED maximize window and activate it' do
|
378
|
+
commands_should_show_window SW_MAXIMIZE, SW_SHOWMAXIMIZED,
|
379
|
+
:minimized? => false, :maximized? => true, :visible? => true, :foreground? => true
|
380
|
+
end
|
381
|
+
|
382
|
+
it 'SW_MINIMIZE minimizes window and activates the next top-level window in the Z order' do
|
383
|
+
commands_should_show_window SW_MINIMIZE,
|
384
|
+
:minimized? => true, :maximized? => false, :visible? => true, :foreground? => false
|
385
|
+
end
|
386
|
+
|
387
|
+
it 'SW_SHOWMINNOACTIVE, SW_SHOWMINIMIZED displays the window as a minimized foreground window' do
|
388
|
+
commands_should_show_window SW_SHOWMINNOACTIVE, SW_SHOWMINIMIZED, #!
|
389
|
+
:minimized? => true, :maximized? => false, :visible? => true, :foreground? => true
|
390
|
+
end
|
391
|
+
|
392
|
+
it 'SW_SHOWNORMAL, SW_RESTORE, SW_SHOWNOACTIVATE activate/display a window(if min/maximized it is restored' do
|
393
|
+
commands_should_show_window SW_SHOWNORMAL, SW_RESTORE, SW_SHOWNOACTIVATE,
|
394
|
+
:minimized? => false, :maximized? => false, :visible? => true, :foreground? => true
|
395
|
+
end
|
396
|
+
|
397
|
+
it 'SW_SHOWNA displays the window in its current size and position (similar to SW_SHOW, but window is not activated)'
|
398
|
+
it 'SW_SHOWDEFAULT sets the show state based on the SW_ value specified in the STARTUPINFO structure passed to the CreateProcess function by the program that started the application'
|
399
|
+
it 'SW_FORCEMINIMIZE minimizes a window, even if the thread that owns the window is not responding - only Win2000/XP'
|
400
|
+
end
|
401
|
+
|
402
|
+
describe '#enum_windows' do
|
403
|
+
before(:all){@app = launch_test_app}
|
404
|
+
after(:all){close_test_app}
|
405
|
+
|
406
|
+
spec{ use{ handles = enum_windows(value = 13) }}
|
407
|
+
spec{ use{ enum_windows do |handle, message|
|
408
|
+
end }}
|
409
|
+
|
410
|
+
it 'iterates through all the top-level windows, passing each top level window handle and value to a given block' do
|
411
|
+
enum_windows(13) do |handle, message|
|
412
|
+
handle.should be_an Integer
|
413
|
+
handle.should be > 0
|
414
|
+
message.should == 13
|
415
|
+
end
|
416
|
+
end
|
417
|
+
|
418
|
+
it 'returns an array of top-level window handles if block is not given' do
|
419
|
+
enum = enum_windows(13)
|
420
|
+
enum.should be_a_kind_of Array
|
421
|
+
enum.should_not be_empty
|
422
|
+
enum.should have_at_least(50).elements # typical number of top windows in WinXP system?
|
423
|
+
enum.each do |handle|
|
424
|
+
handle.should be_an Integer
|
425
|
+
handle.should be > 0
|
426
|
+
end
|
427
|
+
enum.any?{|handle| handle == @app.handle}.should == true
|
428
|
+
end
|
429
|
+
|
430
|
+
it 'returned array that contains handle of launched test app' do
|
431
|
+
enum = enum_windows(13)
|
432
|
+
enum.any?{|handle| handle == @app.handle}.should == true
|
433
|
+
end
|
434
|
+
|
435
|
+
it 'defaults message to 0 if it is omitted from method call' do
|
436
|
+
enum_windows do |handle, message|
|
437
|
+
message.should == 0
|
438
|
+
end
|
439
|
+
end
|
440
|
+
end
|
441
|
+
|
442
|
+
describe '#enum_child_windows' do
|
443
|
+
before(:all){@app = launch_test_app}
|
444
|
+
after(:all){close_test_app}
|
445
|
+
|
446
|
+
spec{ use{ enum_child_windows(parent = any_handle, value = 13) }}
|
447
|
+
|
448
|
+
it 'return an array of child window handles if block is not given' do
|
449
|
+
enum = enum_child_windows(@app.handle, 13)
|
450
|
+
enum.should be_a_kind_of Array
|
451
|
+
enum.should have(2).elements
|
452
|
+
class_name(enum.first).should == TEST_STATUSBAR_CLASS
|
453
|
+
class_name(enum.last).should == TEST_TEXTAREA_CLASS
|
454
|
+
end
|
455
|
+
|
456
|
+
it 'loops through all children of given window, passing each found window handle and a message to a given block' do
|
457
|
+
enum = []
|
458
|
+
enum_child_windows(@app.handle, 13) do |handle, message|
|
459
|
+
enum << handle
|
460
|
+
message.should == 13
|
461
|
+
end
|
462
|
+
enum.should have(2).elements
|
463
|
+
class_name(enum.first).should == TEST_STATUSBAR_CLASS
|
464
|
+
class_name(enum.last).should == TEST_TEXTAREA_CLASS
|
465
|
+
end
|
466
|
+
|
467
|
+
it 'breaks loop if given block returns false' do
|
468
|
+
enum = []
|
469
|
+
enum_child_windows(@app.handle) do |handle, message|
|
470
|
+
enum << handle
|
471
|
+
false
|
472
|
+
end
|
473
|
+
enum.should have(1).element
|
474
|
+
class_name(enum.first).should == TEST_STATUSBAR_CLASS
|
475
|
+
end
|
476
|
+
|
477
|
+
it 'defaults message to 0 if it is omitted from method call' do
|
478
|
+
enum_child_windows(@app.handle) do |handle, message|
|
479
|
+
message.should == 0
|
480
|
+
end
|
481
|
+
end
|
482
|
+
end
|
483
|
+
|
484
|
+
describe '#keydb_event' do
|
485
|
+
spec{ use{ keybd_event(vkey = 0, bscan = 0, flags = 0, extra_info = 0) }}
|
486
|
+
|
487
|
+
it 'synthesizes a numeric keystrokes, emulating keyboard driver' do
|
488
|
+
test_app do |app|
|
489
|
+
text = '123 456'
|
490
|
+
text.upcase.each_byte do |b| # upcase needed since user32 keybd_event expects upper case chars
|
491
|
+
keybd_event(b.ord, 0, KEYEVENTF_KEYDOWN, 0)
|
492
|
+
sleep TEST_KEY_DELAY
|
493
|
+
keybd_event(b.ord, 0, KEYEVENTF_KEYUP, 0)
|
494
|
+
sleep TEST_KEY_DELAY
|
495
|
+
end
|
496
|
+
app.textarea.text.should =~ Regexp.new(text)
|
497
|
+
7.times {keystroke(VK_CONTROL, 'Z'.ord)} # dirty hack!
|
498
|
+
end
|
499
|
+
end
|
500
|
+
end
|
501
|
+
|
502
|
+
describe '#post_message' do
|
503
|
+
spec{ use{ success = post_message(handle = 0, msg = 0, w_param = 0, l_param = 0) }}
|
504
|
+
# handle (L) - Handle to the window whose window procedure will receive the message.
|
505
|
+
# If this parameter is HWND_BROADCAST, the message is sent to all top-level windows in the system, including disabled or
|
506
|
+
# invisible unowned windows, overlapped windows, and pop-up windows; but the message is not sent to child windows.
|
507
|
+
# msg (L) - Specifies the message to be posted.
|
508
|
+
# w_param (L) - Specifies additional message-specific information.
|
509
|
+
# l_param (L) - Specifies additional message-specific information.
|
510
|
+
# returns (L) - Nonzero if success, zero if function failed. To get extended error information, call GetLastError.
|
511
|
+
|
512
|
+
it 'places (posts) a message in the message queue associated with the thread that created the specified window'
|
513
|
+
it 'returns without waiting for the thread to process the message'
|
514
|
+
end
|
515
|
+
|
516
|
+
describe '#send_message' do
|
517
|
+
spec{ use{ success = send_message(handle = 0, msg = 0, w_param = 1024, l_param = "\x0"*1024) }}
|
518
|
+
# handle (L) - Handle to the window whose window procedure is to receive the message. The following values have special meanings.
|
519
|
+
# HWND_BROADCAST - The message is posted to all top-level windows in the system, including disabled or invisible unowned windows,
|
520
|
+
# overlapped windows, and pop-up windows. The message is not posted to child windows.
|
521
|
+
# NULL - The function behaves like a call to PostThreadMessage with the dwThreadId parameter set to the identifier of the current thread.
|
522
|
+
# msg (L) - Specifies the message to be posted.
|
523
|
+
# w_param (L) - Specifies additional message-specific information.
|
524
|
+
# l_param (L) - Specifies additional message-specific information.
|
525
|
+
# return (L) - Nonzero if success, zero if function failed. To get extended error information, call GetLastError.
|
526
|
+
|
527
|
+
it 'sends the specified message to a window or windows'
|
528
|
+
it 'calls the window procedure and does not return until the window procedure has processed the message'
|
529
|
+
end
|
530
|
+
|
531
|
+
describe '#get_dlg_item' do
|
532
|
+
spec{ use{ control_handle = get_dlg_item(handle = 0, item_id = 1) }}
|
533
|
+
# handle (L) - Handle of the dialog box that contains the control.
|
534
|
+
# item_id (I) - Specifies the identifier of the control to be retrieved.
|
535
|
+
# Returns (L) - handle of the specified control if success or nil for invalid dialog box handle or a nonexistent control.
|
536
|
+
# To get extended error information, call GetLastError.
|
537
|
+
# You can use the GetDlgItem function with any parent-child window pair, not just with dialog boxes. As long as the handle
|
538
|
+
# parameter specifies a parent window and the child window has a unique id (as specified by the hMenu parameter in the
|
539
|
+
# CreateWindow or CreateWindowEx function that created the child window), GetDlgItem returns a valid handle to the child window.
|
540
|
+
|
541
|
+
it 'returns handle to correctly specified control'
|
542
|
+
end
|
316
543
|
end
|
317
544
|
end
|
data/win.gemspec
CHANGED
@@ -5,12 +5,12 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{win}
|
8
|
-
s.version = "0.0.
|
8
|
+
s.version = "0.0.6"
|
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-02-
|
13
|
-
s.description = %q{A collection of Windows functions
|
12
|
+
s.date = %q{2010-02-14}
|
13
|
+
s.description = %q{A collection of pre-defined Windows API functions with Rubyesque interfaces}
|
14
14
|
s.email = %q{arvitallian@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
16
16
|
"LICENSE",
|
@@ -26,14 +26,18 @@ Gem::Specification.new do |s|
|
|
26
26
|
"features/step_definitions/win_steps.rb",
|
27
27
|
"features/support/env.rb",
|
28
28
|
"features/win.feature",
|
29
|
+
"lib/win/dde.rb",
|
29
30
|
"lib/win/extensions.rb",
|
30
31
|
"lib/win/library.rb",
|
31
32
|
"lib/win/window.rb",
|
33
|
+
"lib/win/window/extra.rb",
|
32
34
|
"spec/spec.opts",
|
33
35
|
"spec/spec_helper.rb",
|
34
36
|
"spec/test_apps/locknote/LockNote.exe",
|
37
|
+
"spec/win/dde_spec.rb",
|
35
38
|
"spec/win/extensions_spec.rb",
|
36
39
|
"spec/win/library_spec.rb",
|
40
|
+
"spec/win/window/extra_spec.rb",
|
37
41
|
"spec/win/window_spec.rb",
|
38
42
|
"win.gemspec"
|
39
43
|
]
|
@@ -41,11 +45,13 @@ Gem::Specification.new do |s|
|
|
41
45
|
s.rdoc_options = ["--charset=UTF-8"]
|
42
46
|
s.require_paths = ["lib"]
|
43
47
|
s.rubygems_version = %q{1.3.5}
|
44
|
-
s.summary = %q{A collection of Windows functions
|
48
|
+
s.summary = %q{A collection of pre-defined Windows API functions with Rubyesque interfaces}
|
45
49
|
s.test_files = [
|
46
50
|
"spec/spec_helper.rb",
|
51
|
+
"spec/win/dde_spec.rb",
|
47
52
|
"spec/win/extensions_spec.rb",
|
48
53
|
"spec/win/library_spec.rb",
|
54
|
+
"spec/win/window/extra_spec.rb",
|
49
55
|
"spec/win/window_spec.rb"
|
50
56
|
]
|
51
57
|
|
@@ -54,13 +60,16 @@ Gem::Specification.new do |s|
|
|
54
60
|
s.specification_version = 3
|
55
61
|
|
56
62
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
63
|
+
s.add_runtime_dependency(%q<ffi>, [">= 0.6.0"])
|
57
64
|
s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
|
58
65
|
s.add_development_dependency(%q<cucumber>, [">= 0"])
|
59
66
|
else
|
67
|
+
s.add_dependency(%q<ffi>, [">= 0.6.0"])
|
60
68
|
s.add_dependency(%q<rspec>, [">= 1.2.9"])
|
61
69
|
s.add_dependency(%q<cucumber>, [">= 0"])
|
62
70
|
end
|
63
71
|
else
|
72
|
+
s.add_dependency(%q<ffi>, [">= 0.6.0"])
|
64
73
|
s.add_dependency(%q<rspec>, [">= 1.2.9"])
|
65
74
|
s.add_dependency(%q<cucumber>, [">= 0"])
|
66
75
|
end
|
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.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- arvicco
|
@@ -9,9 +9,19 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-02-
|
12
|
+
date: 2010-02-14 00:00:00 +03:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: ffi
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.6.0
|
24
|
+
version:
|
15
25
|
- !ruby/object:Gem::Dependency
|
16
26
|
name: rspec
|
17
27
|
type: :development
|
@@ -32,7 +42,7 @@ dependencies:
|
|
32
42
|
- !ruby/object:Gem::Version
|
33
43
|
version: "0"
|
34
44
|
version:
|
35
|
-
description: A collection of Windows functions
|
45
|
+
description: A collection of pre-defined Windows API functions with Rubyesque interfaces
|
36
46
|
email: arvitallian@gmail.com
|
37
47
|
executables: []
|
38
48
|
|
@@ -51,14 +61,18 @@ files:
|
|
51
61
|
- features/step_definitions/win_steps.rb
|
52
62
|
- features/support/env.rb
|
53
63
|
- features/win.feature
|
64
|
+
- lib/win/dde.rb
|
54
65
|
- lib/win/extensions.rb
|
55
66
|
- lib/win/library.rb
|
56
67
|
- lib/win/window.rb
|
68
|
+
- lib/win/window/extra.rb
|
57
69
|
- spec/spec.opts
|
58
70
|
- spec/spec_helper.rb
|
59
71
|
- spec/test_apps/locknote/LockNote.exe
|
72
|
+
- spec/win/dde_spec.rb
|
60
73
|
- spec/win/extensions_spec.rb
|
61
74
|
- spec/win/library_spec.rb
|
75
|
+
- spec/win/window/extra_spec.rb
|
62
76
|
- spec/win/window_spec.rb
|
63
77
|
- win.gemspec
|
64
78
|
has_rdoc: true
|
@@ -88,9 +102,11 @@ rubyforge_project:
|
|
88
102
|
rubygems_version: 1.3.5
|
89
103
|
signing_key:
|
90
104
|
specification_version: 3
|
91
|
-
summary: A collection of Windows functions
|
105
|
+
summary: A collection of pre-defined Windows API functions with Rubyesque interfaces
|
92
106
|
test_files:
|
93
107
|
- spec/spec_helper.rb
|
108
|
+
- spec/win/dde_spec.rb
|
94
109
|
- spec/win/extensions_spec.rb
|
95
110
|
- spec/win/library_spec.rb
|
111
|
+
- spec/win/window/extra_spec.rb
|
96
112
|
- spec/win/window_spec.rb
|