win 0.0.6 → 0.1.0
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 +45 -20
- data/Rakefile +2 -2
- data/VERSION +1 -1
- data/lib/win/dde.rb +13 -15
- data/lib/win/extensions.rb +1 -1
- data/lib/win/gui/convenience.rb +142 -0
- data/lib/win/gui/dialog.rb +15 -0
- data/lib/win/gui/input.rb +255 -0
- data/lib/win/gui/message.rb +22 -0
- data/lib/win/gui/window.rb +497 -0
- data/lib/win/gui.rb +17 -0
- data/lib/win/library.rb +10 -9
- data/spec/spec_helper.rb +53 -15
- data/spec/win/dde_spec.rb +1 -0
- data/spec/win/extensions_spec.rb +1 -1
- data/spec/win/{window/extra_spec.rb → gui/convenience_spec.rb} +19 -23
- data/spec/win/gui/dialog_spec.rb +42 -0
- data/spec/win/gui/input_spec.rb +39 -0
- data/spec/win/gui/message_spec.rb +43 -0
- data/spec/win/{window_spec.rb → gui/window_spec.rb} +7 -97
- data/spec/win/library_spec.rb +3 -6
- data/win.gemspec +21 -11
- metadata +20 -10
- data/lib/win/window/extra.rb +0 -113
- data/lib/win/window.rb +0 -608
@@ -1,16 +1,15 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
-
require 'win/
|
3
|
-
require 'win/window/extra'
|
2
|
+
require 'win/gui/convenience'
|
4
3
|
|
5
|
-
module
|
6
|
-
include
|
7
|
-
include Win::Window
|
4
|
+
module WinGuiTest
|
5
|
+
include WinTestApp
|
6
|
+
include Win::Gui::Window
|
7
|
+
include Win::Gui::Input
|
8
|
+
include Win::Gui::Convenience
|
8
9
|
|
9
|
-
describe Win::
|
10
|
+
describe Win::Gui::Convenience, ' defines convenience/service methods on top of Windows API' do
|
10
11
|
describe '#keystroke' do
|
11
12
|
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
13
|
|
15
14
|
it 'emulates combinations of keys pressed (Ctrl+Alt+P+M, etc)' do
|
16
15
|
test_app do |app|
|
@@ -24,21 +23,19 @@ module WinWindowTest
|
|
24
23
|
|
25
24
|
describe '#type_in' do
|
26
25
|
spec{ use{ type_in(message = '') }}
|
27
|
-
# this service method types text message into window holding the focus
|
28
26
|
|
29
|
-
it 'types text message into window holding the focus' do
|
27
|
+
it 'types text message into the window holding the focus' do
|
30
28
|
test_app do |app|
|
31
|
-
text = '
|
29
|
+
text = '12 34'
|
32
30
|
type_in(text)
|
33
31
|
app.textarea.text.should =~ Regexp.new(text)
|
34
|
-
|
32
|
+
5.times {keystroke(VK_CONTROL, 'Z'.ord)} # dirty hack!
|
35
33
|
end
|
36
34
|
end
|
37
35
|
end
|
38
36
|
|
39
37
|
describe 'dialog' do
|
40
38
|
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
39
|
|
43
40
|
it 'finds top-level dialog window by title' do
|
44
41
|
pending 'Some problems (?with timeouts?) leave window open ~half of the runs'
|
@@ -58,18 +55,18 @@ module WinWindowTest
|
|
58
55
|
|
59
56
|
end
|
60
57
|
|
61
|
-
describe Win::
|
58
|
+
describe Win::Gui::Convenience::WrapWindow, ' thin wrapper class around window handle' do
|
62
59
|
before(:each) { @app = launch_test_app }
|
63
60
|
after(:each){ close_test_app }
|
64
61
|
|
65
62
|
context 'creating' do
|
66
63
|
it 'can be wrapped around any existing window' do
|
67
64
|
any_handle = find_window(nil, nil)
|
68
|
-
use{
|
65
|
+
use{ WrapWindow.new any_handle }
|
69
66
|
end
|
70
67
|
|
71
68
|
it 'can be wrapped around specific window' do
|
72
|
-
use{
|
69
|
+
use{ WrapWindow.new @app.handle }
|
73
70
|
end
|
74
71
|
end
|
75
72
|
|
@@ -77,7 +74,7 @@ module WinWindowTest
|
|
77
74
|
|
78
75
|
it 'has handle property equal to underlying window handle' do
|
79
76
|
any_handle = find_window(nil, nil)
|
80
|
-
any =
|
77
|
+
any = WrapWindow.new any_handle
|
81
78
|
any.handle.should == any_handle
|
82
79
|
end
|
83
80
|
|
@@ -88,26 +85,26 @@ module WinWindowTest
|
|
88
85
|
it 'closes when asked nicely' do
|
89
86
|
@app.close
|
90
87
|
sleep TEST_SLEEP_DELAY # needed to ensure window had enough time to close down
|
91
|
-
find_window(nil, TEST_WIN_TITLE).should == nil
|
88
|
+
find_window(nil, TEST_WIN_TITLE).should == nil #!!!!!
|
92
89
|
end
|
93
90
|
|
94
91
|
it 'waits f0r window to disappear (NB: this happens before handle is released!)' do
|
95
92
|
start = Time.now
|
96
93
|
@app.close
|
97
94
|
@app.wait_for_close
|
98
|
-
(Time.now - start).should be <= Win::
|
95
|
+
(Time.now - start).should be <= Win::Gui::Convenience::CLOSE_TIMEOUT
|
99
96
|
window_visible?(@app.handle).should be false
|
100
97
|
end
|
101
98
|
end
|
102
99
|
|
103
100
|
context '.top_level class method' do
|
104
101
|
it 'finds any top-level window (title = nil) and wraps it in a Window object' do
|
105
|
-
use { @win =
|
106
|
-
|
102
|
+
use { @win = WrapWindow.top_level(title = nil, timeout_sec = 3) }
|
103
|
+
@win.should be_a_kind_of WrapWindow
|
107
104
|
end
|
108
105
|
|
109
106
|
it 'finds top-level window by title and wraps it in a Window object' do
|
110
|
-
win =
|
107
|
+
win = WrapWindow.top_level( TEST_WIN_TITLE, 1)
|
111
108
|
win.handle.should == @app.handle
|
112
109
|
end
|
113
110
|
end
|
@@ -177,5 +174,4 @@ module WinWindowTest
|
|
177
174
|
it 'emulates clicking of the control identified by id'
|
178
175
|
end
|
179
176
|
end
|
180
|
-
|
181
177
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
require 'win/gui/input'
|
3
|
+
#require 'win/gui/window'
|
4
|
+
|
5
|
+
module WinWindowTest
|
6
|
+
|
7
|
+
include WinTestApp
|
8
|
+
include Win::Gui::Dialog
|
9
|
+
|
10
|
+
describe Win::Gui::Dialog do
|
11
|
+
|
12
|
+
describe '#get_dlg_item' do
|
13
|
+
spec{ use{ control_handle = get_dlg_item(handle = 0, item_id = 1) }}
|
14
|
+
# handle (L) - Handle of the dialog box that contains the control.
|
15
|
+
# item_id (I) - Specifies the identifier of the control to be retrieved.
|
16
|
+
# Returns (L) - handle of the specified control if success or nil for invalid dialog box handle or a nonexistent control.
|
17
|
+
# To get extended error information, call GetLastError.
|
18
|
+
# You can use the GetDlgItem function with any parent-child window pair, not just with dialog boxes. As long as the handle
|
19
|
+
# parameter specifies a parent window and the child window has a unique id (as specified by the hMenu parameter in the
|
20
|
+
# CreateWindow or CreateWindowEx function that created the child window), GetDlgItem returns a valid handle to the child window.
|
21
|
+
|
22
|
+
it 'returns handle to correctly specified control'
|
23
|
+
|
24
|
+
it 'does something else' do
|
25
|
+
pending
|
26
|
+
test_app do |app|
|
27
|
+
text = '123 456'
|
28
|
+
text.upcase.each_byte do |b| # upcase needed since user32 keybd_event expects upper case chars
|
29
|
+
keybd_event(b.ord, 0, KEYEVENTF_KEYDOWN, 0)
|
30
|
+
sleep TEST_KEY_DELAY
|
31
|
+
keybd_event(b.ord, 0, KEYEVENTF_KEYUP, 0)
|
32
|
+
sleep TEST_KEY_DELAY
|
33
|
+
end
|
34
|
+
app.textarea.text.should =~ Regexp.new(text)
|
35
|
+
7.times {keystroke(VK_CONTROL, 'Z'.ord)} # dirty hack!
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
require 'win/gui/input'
|
3
|
+
#require 'win/gui/window'
|
4
|
+
|
5
|
+
module WinWindowTest
|
6
|
+
|
7
|
+
include WinTestApp
|
8
|
+
include Win::Gui::Input
|
9
|
+
|
10
|
+
describe Win::Gui::Input do
|
11
|
+
|
12
|
+
describe '#keydb_event' do
|
13
|
+
spec{ use{ keybd_event(vkey = 0, bscan = 0, flags = 0, extra_info = 0) }}
|
14
|
+
|
15
|
+
it 'synthesizes a numeric keystrokes, emulating keyboard driver' do
|
16
|
+
test_app do |app|
|
17
|
+
text = '123 456'
|
18
|
+
text.upcase.each_byte do |b| # upcase needed since user32 keybd_event expects upper case chars
|
19
|
+
keybd_event(b.ord, 0, KEYEVENTF_KEYDOWN, 0)
|
20
|
+
sleep TEST_KEY_DELAY
|
21
|
+
keybd_event(b.ord, 0, KEYEVENTF_KEYUP, 0)
|
22
|
+
sleep TEST_KEY_DELAY
|
23
|
+
end
|
24
|
+
app.textarea.text.should =~ Regexp.new(text)
|
25
|
+
7.times {keystroke(VK_CONTROL, 'Z'.ord)} # dirty hack!
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe '#mouse_event' do
|
31
|
+
it 'Emulates Mouse clicks'
|
32
|
+
end
|
33
|
+
|
34
|
+
describe '#set_cursor_pos' do
|
35
|
+
it 'how to test set_cursor_pos?'
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
require 'win/gui/input'
|
3
|
+
#require 'win/gui/window'
|
4
|
+
|
5
|
+
module WinGuiMessageTest
|
6
|
+
|
7
|
+
include WinTestApp
|
8
|
+
include Win::Gui::Message
|
9
|
+
|
10
|
+
describe Win::Gui::Message do
|
11
|
+
|
12
|
+
describe '#post_message' do
|
13
|
+
spec{ use{ success = post_message(handle = 0, msg = 0, w_param = 0, l_param = 0) }}
|
14
|
+
# handle (L) - Handle to the window whose window procedure will receive the message.
|
15
|
+
# If this parameter is HWND_BROADCAST, the message is sent to all top-level windows in the system, including disabled or
|
16
|
+
# invisible unowned windows, overlapped windows, and pop-up windows; but the message is not sent to child windows.
|
17
|
+
# msg (L) - Specifies the message to be posted.
|
18
|
+
# w_param (L) - Specifies additional message-specific information.
|
19
|
+
# l_param (L) - Specifies additional message-specific information.
|
20
|
+
# returns (L) - Nonzero if success, zero if function failed. To get extended error information, call GetLastError.
|
21
|
+
|
22
|
+
it 'places (posts) a message in the message queue associated with the thread that created the specified window'
|
23
|
+
it 'returns without waiting for the thread to process the message'
|
24
|
+
end
|
25
|
+
|
26
|
+
describe '#send_message' do
|
27
|
+
spec{ use{ success = send_message(handle = 0, msg = 0, w_param = 1024, l_param = "\x0"*1024) }}
|
28
|
+
# handle (L) - Handle to the window whose window procedure is to receive the message. The following values have special meanings.
|
29
|
+
# HWND_BROADCAST - The message is posted to all top-level windows in the system, including disabled or invisible unowned windows,
|
30
|
+
# overlapped windows, and pop-up windows. The message is not posted to child windows.
|
31
|
+
# NULL - The function behaves like a call to PostThreadMessage with the dwThreadId parameter set to the identifier of the current thread.
|
32
|
+
# msg (L) - Specifies the message to be posted.
|
33
|
+
# w_param (L) - Specifies additional message-specific information.
|
34
|
+
# l_param (L) - Specifies additional message-specific information.
|
35
|
+
# return (L) - Nonzero if success, zero if function failed. To get extended error information, call GetLastError.
|
36
|
+
|
37
|
+
it 'sends the specified message to a window or windows'
|
38
|
+
it 'calls the window procedure and does not return until the window procedure has processed the message'
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
|
@@ -1,40 +1,10 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '
|
2
|
-
require 'win/window'
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
require 'win/gui/window'
|
3
3
|
|
4
4
|
module WinWindowTest
|
5
5
|
|
6
|
-
include
|
7
|
-
include Win::Window
|
8
|
-
|
9
|
-
def launch_test_app
|
10
|
-
system TEST_APP_START
|
11
|
-
sleep TEST_SLEEP_DELAY until (handle = find_window(nil, TEST_WIN_TITLE))
|
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
|
17
|
-
end
|
18
|
-
|
19
|
-
def close_test_app(app = @launched_test_app)
|
20
|
-
while app and app.respond_to? :handle and find_window(nil, TEST_WIN_TITLE)
|
21
|
-
post_message(app.handle, WM_SYSCOMMAND, SC_CLOSE, 0)
|
22
|
-
sleep TEST_SLEEP_DELAY
|
23
|
-
end
|
24
|
-
@launched_test_app = nil
|
25
|
-
end
|
26
|
-
|
27
|
-
# Creates test app object and yields it back to the block
|
28
|
-
def test_app
|
29
|
-
app = launch_test_app
|
30
|
-
|
31
|
-
def app.textarea #define singleton method retrieving app's text area
|
32
|
-
Window.new find_window_ex(self.handle, 0, TEST_TEXTAREA_CLASS, nil)
|
33
|
-
end
|
34
|
-
|
35
|
-
yield app
|
36
|
-
close_test_app
|
37
|
-
end
|
6
|
+
include WinTestApp
|
7
|
+
include Win::Gui::Window
|
38
8
|
|
39
9
|
def commands_should_show_window *cmds, tests
|
40
10
|
cmds.each do |cmd|
|
@@ -57,8 +27,7 @@ module WinWindowTest
|
|
57
27
|
end
|
58
28
|
end
|
59
29
|
|
60
|
-
|
61
|
-
describe Win::Window, ' defines a set user32 API functions related to Window manipulation' do
|
30
|
+
describe Win::Gui::Window, ' defines a set user32 API functions related to Window manipulation' do
|
62
31
|
describe '#window?' do
|
63
32
|
spec{ use{ IsWindow(any_handle) }}
|
64
33
|
spec{ use{ is_window(any_handle) }}
|
@@ -480,65 +449,6 @@ module WinWindowTest
|
|
480
449
|
end
|
481
450
|
end
|
482
451
|
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
|
543
452
|
end
|
544
|
-
end
|
453
|
+
end
|
454
|
+
|
data/spec/win/library_spec.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
2
|
require 'win/library'
|
3
3
|
|
4
|
-
module
|
4
|
+
module WinLibraryTest
|
5
|
+
|
6
|
+
include WinTest
|
5
7
|
|
6
8
|
module MyLib # namespace for defined functions
|
7
9
|
include Win::Library
|
@@ -40,10 +42,6 @@ module WinTest
|
|
40
42
|
find_window(nil, nil)
|
41
43
|
end
|
42
44
|
|
43
|
-
def not_a_handle
|
44
|
-
123
|
45
|
-
end
|
46
|
-
|
47
45
|
def redefined_methods
|
48
46
|
[:FindWindow, :IsWindow, :EnumWindows, :GetComputerName, :GetForegroundWindow]
|
49
47
|
end
|
@@ -366,6 +364,5 @@ module WinTest
|
|
366
364
|
expect { enum_windows('Message'){|handle, message| true } }.to_not raise_error
|
367
365
|
end
|
368
366
|
end
|
369
|
-
|
370
367
|
end
|
371
368
|
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.1.0"
|
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{
|
12
|
+
s.date = %q{2010-02-15}
|
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 = [
|
16
16
|
"LICENSE",
|
@@ -28,31 +28,41 @@ Gem::Specification.new do |s|
|
|
28
28
|
"features/win.feature",
|
29
29
|
"lib/win/dde.rb",
|
30
30
|
"lib/win/extensions.rb",
|
31
|
+
"lib/win/gui.rb",
|
32
|
+
"lib/win/gui/convenience.rb",
|
33
|
+
"lib/win/gui/dialog.rb",
|
34
|
+
"lib/win/gui/input.rb",
|
35
|
+
"lib/win/gui/message.rb",
|
36
|
+
"lib/win/gui/window.rb",
|
31
37
|
"lib/win/library.rb",
|
32
|
-
"lib/win/window.rb",
|
33
|
-
"lib/win/window/extra.rb",
|
34
38
|
"spec/spec.opts",
|
35
39
|
"spec/spec_helper.rb",
|
36
40
|
"spec/test_apps/locknote/LockNote.exe",
|
37
41
|
"spec/win/dde_spec.rb",
|
38
42
|
"spec/win/extensions_spec.rb",
|
43
|
+
"spec/win/gui/convenience_spec.rb",
|
44
|
+
"spec/win/gui/dialog_spec.rb",
|
45
|
+
"spec/win/gui/input_spec.rb",
|
46
|
+
"spec/win/gui/message_spec.rb",
|
47
|
+
"spec/win/gui/window_spec.rb",
|
39
48
|
"spec/win/library_spec.rb",
|
40
|
-
"spec/win/window/extra_spec.rb",
|
41
|
-
"spec/win/window_spec.rb",
|
42
49
|
"win.gemspec"
|
43
50
|
]
|
44
51
|
s.homepage = %q{http://github.com/arvicco/win}
|
45
52
|
s.rdoc_options = ["--charset=UTF-8"]
|
46
53
|
s.require_paths = ["lib"]
|
47
54
|
s.rubygems_version = %q{1.3.5}
|
48
|
-
s.summary = %q{
|
55
|
+
s.summary = %q{Rubyesque interfaces and wrappers for Windows API functions pre-defined using FFI}
|
49
56
|
s.test_files = [
|
50
57
|
"spec/spec_helper.rb",
|
51
58
|
"spec/win/dde_spec.rb",
|
52
59
|
"spec/win/extensions_spec.rb",
|
53
|
-
"spec/win/
|
54
|
-
"spec/win/
|
55
|
-
"spec/win/
|
60
|
+
"spec/win/gui/convenience_spec.rb",
|
61
|
+
"spec/win/gui/dialog_spec.rb",
|
62
|
+
"spec/win/gui/input_spec.rb",
|
63
|
+
"spec/win/gui/message_spec.rb",
|
64
|
+
"spec/win/gui/window_spec.rb",
|
65
|
+
"spec/win/library_spec.rb"
|
56
66
|
]
|
57
67
|
|
58
68
|
if s.respond_to? :specification_version then
|
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.1.0
|
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-02-
|
12
|
+
date: 2010-02-15 00:00:00 +03:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -42,7 +42,7 @@ dependencies:
|
|
42
42
|
- !ruby/object:Gem::Version
|
43
43
|
version: "0"
|
44
44
|
version:
|
45
|
-
description:
|
45
|
+
description: "Rubyesque interfaces and wrappers for Windows API functions pre-defined using FFI "
|
46
46
|
email: arvitallian@gmail.com
|
47
47
|
executables: []
|
48
48
|
|
@@ -63,17 +63,24 @@ files:
|
|
63
63
|
- features/win.feature
|
64
64
|
- lib/win/dde.rb
|
65
65
|
- lib/win/extensions.rb
|
66
|
+
- lib/win/gui.rb
|
67
|
+
- lib/win/gui/convenience.rb
|
68
|
+
- lib/win/gui/dialog.rb
|
69
|
+
- lib/win/gui/input.rb
|
70
|
+
- lib/win/gui/message.rb
|
71
|
+
- lib/win/gui/window.rb
|
66
72
|
- lib/win/library.rb
|
67
|
-
- lib/win/window.rb
|
68
|
-
- lib/win/window/extra.rb
|
69
73
|
- spec/spec.opts
|
70
74
|
- spec/spec_helper.rb
|
71
75
|
- spec/test_apps/locknote/LockNote.exe
|
72
76
|
- spec/win/dde_spec.rb
|
73
77
|
- spec/win/extensions_spec.rb
|
78
|
+
- spec/win/gui/convenience_spec.rb
|
79
|
+
- spec/win/gui/dialog_spec.rb
|
80
|
+
- spec/win/gui/input_spec.rb
|
81
|
+
- spec/win/gui/message_spec.rb
|
82
|
+
- spec/win/gui/window_spec.rb
|
74
83
|
- spec/win/library_spec.rb
|
75
|
-
- spec/win/window/extra_spec.rb
|
76
|
-
- spec/win/window_spec.rb
|
77
84
|
- win.gemspec
|
78
85
|
has_rdoc: true
|
79
86
|
homepage: http://github.com/arvicco/win
|
@@ -102,11 +109,14 @@ rubyforge_project:
|
|
102
109
|
rubygems_version: 1.3.5
|
103
110
|
signing_key:
|
104
111
|
specification_version: 3
|
105
|
-
summary:
|
112
|
+
summary: Rubyesque interfaces and wrappers for Windows API functions pre-defined using FFI
|
106
113
|
test_files:
|
107
114
|
- spec/spec_helper.rb
|
108
115
|
- spec/win/dde_spec.rb
|
109
116
|
- spec/win/extensions_spec.rb
|
117
|
+
- spec/win/gui/convenience_spec.rb
|
118
|
+
- spec/win/gui/dialog_spec.rb
|
119
|
+
- spec/win/gui/input_spec.rb
|
120
|
+
- spec/win/gui/message_spec.rb
|
121
|
+
- spec/win/gui/window_spec.rb
|
110
122
|
- spec/win/library_spec.rb
|
111
|
-
- spec/win/window/extra_spec.rb
|
112
|
-
- spec/win/window_spec.rb
|
data/lib/win/window/extra.rb
DELETED
@@ -1,113 +0,0 @@
|
|
1
|
-
require 'win/library'
|
2
|
-
require 'win/window'
|
3
|
-
|
4
|
-
module Win
|
5
|
-
module Window
|
6
|
-
# Wait delay quant
|
7
|
-
SLEEP_DELAY = 0.001
|
8
|
-
# Timeout waiting for Window to be closed
|
9
|
-
CLOSE_TIMEOUT = 1
|
10
|
-
|
11
|
-
# Convenience wrapper methods:
|
12
|
-
|
13
|
-
# emulates combinations of keys pressed (Ctrl+Alt+P+M, etc)
|
14
|
-
def keystroke(*keys)
|
15
|
-
return if keys.empty?
|
16
|
-
keybd_event keys.first, 0, KEYEVENTF_KEYDOWN, 0
|
17
|
-
sleep KEY_DELAY
|
18
|
-
keystroke *keys[1..-1]
|
19
|
-
sleep KEY_DELAY
|
20
|
-
keybd_event keys.first, 0, KEYEVENTF_KEYUP, 0
|
21
|
-
end
|
22
|
-
|
23
|
-
# types text message into window holding the focus
|
24
|
-
def type_in(message)
|
25
|
-
message.scan(/./m) do |char|
|
26
|
-
keystroke(*char.to_vkeys)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
# finds top-level dialog window by title and yields it to given block
|
31
|
-
def dialog(title, seconds=3)
|
32
|
-
d = begin
|
33
|
-
win = Window.top_level(title, seconds)
|
34
|
-
yield(win) ? win : nil
|
35
|
-
rescue TimeoutError
|
36
|
-
end
|
37
|
-
d.wait_for_close if d
|
38
|
-
return d
|
39
|
-
end
|
40
|
-
|
41
|
-
|
42
|
-
# Thin class is a thin wrapper around window handle
|
43
|
-
class Window
|
44
|
-
include Win::Window
|
45
|
-
extend Win::Window
|
46
|
-
|
47
|
-
attr_reader :handle
|
48
|
-
|
49
|
-
# find top level window by title, return wrapped Window object
|
50
|
-
def self.top_level(title, seconds=3)
|
51
|
-
@handle = timeout(seconds) do
|
52
|
-
sleep SLEEP_DELAY while (h = find_window nil, title) == nil; h
|
53
|
-
end
|
54
|
-
Window.new @handle
|
55
|
-
end
|
56
|
-
|
57
|
-
def initialize(handle)
|
58
|
-
@handle = handle
|
59
|
-
end
|
60
|
-
|
61
|
-
# find child window (control) by title, window class, or control ID:
|
62
|
-
def child(id)
|
63
|
-
result = case id
|
64
|
-
when String
|
65
|
-
by_title = find_window_ex @handle, 0, nil, id.gsub('_', '&' )
|
66
|
-
by_class = find_window_ex @handle, 0, id, nil
|
67
|
-
by_title ? by_title : by_class
|
68
|
-
when Fixnum
|
69
|
-
get_dlg_item @handle, id
|
70
|
-
when nil
|
71
|
-
find_window_ex @handle, 0, nil, nil
|
72
|
-
else
|
73
|
-
nil
|
74
|
-
end
|
75
|
-
raise "Control '#{id}' not found" unless result
|
76
|
-
Window.new result
|
77
|
-
end
|
78
|
-
|
79
|
-
def children
|
80
|
-
enum_child_windows(@handle).map{|child_handle| Window.new child_handle}
|
81
|
-
end
|
82
|
-
|
83
|
-
# emulate click of the control identified by id
|
84
|
-
def click(id)
|
85
|
-
h = child(id).handle
|
86
|
-
rectangle = [0, 0, 0, 0].pack 'LLLL'
|
87
|
-
get_window_rect h, rectangle
|
88
|
-
left, top, right, bottom = rectangle.unpack 'LLLL'
|
89
|
-
center = [(left + right) / 2, (top + bottom) / 2]
|
90
|
-
set_cursor_pos *center
|
91
|
-
mouse_event MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0
|
92
|
-
mouse_event MOUSEEVENTF_LEFTUP, 0, 0, 0, 0
|
93
|
-
end
|
94
|
-
|
95
|
-
def close
|
96
|
-
post_message @handle, WM_SYSCOMMAND, SC_CLOSE, 0
|
97
|
-
end
|
98
|
-
|
99
|
-
def wait_for_close
|
100
|
-
timeout(CLOSE_TIMEOUT) do
|
101
|
-
sleep SLEEP_DELAY while window_visible?(@handle)
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
def text
|
106
|
-
buffer = "\x0" * 2048
|
107
|
-
length = send_message @handle, WM_GETTEXT, buffer.length, buffer
|
108
|
-
length == 0 ? '' : buffer[0..length - 1]
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
end
|
113
|
-
end
|