win_gui 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +23 -7
- data/VERSION +1 -1
- data/lib/win_gui/def_api.rb +55 -0
- data/lib/win_gui/win_gui.rb +15 -44
- data/{exp/old → old}/windows_basics.rb +0 -0
- data/{exp/old → old}/wnote.rb +0 -0
- data/{exp/old → old}/wnote_spec.rb +0 -0
- data/spec/spec_helper.rb +4 -0
- data/spec/win_gui/def_api_spec.rb +242 -0
- data/spec/win_gui/win_gui_spec.rb +0 -250
- data/win_gui.gemspec +215 -0
- metadata +9 -10
- data/exp/exp.rb +0 -6
- data/exp/exp_encodings.rb +0 -40
- data/exp/exp_enum_windows.rb +0 -60
- data/exp/exp_quik.rb +0 -38
- data/exp/exp_wsh.rb +0 -115
data/README.rdoc
CHANGED
@@ -1,22 +1,38 @@
|
|
1
1
|
= win_gui
|
2
|
+
by: Arvicco
|
3
|
+
url: http://github.com/arvicco/git_hub
|
2
4
|
|
3
|
-
==
|
5
|
+
== DESCRIPTION:
|
4
6
|
|
5
7
|
Welcome to WinGui!
|
6
8
|
|
7
9
|
WinGui is a module that provides convenient wrapper methods for multiple Win32 API
|
8
|
-
functions (mostly from user32.dll) dealing with GUI manipulation/automation.
|
10
|
+
functions (mostly from user32.dll) dealing with Windows GUI manipulation/automation.
|
9
11
|
In addition to straightforward API wrappers, it also defines more Ruby-like
|
10
12
|
abstractions and convenience methods for manipulating windows and other GUI
|
11
13
|
elements (such as WinGui::Window class and its methods).
|
12
14
|
|
13
15
|
It is still work in progress, only a small number of API functions wrapped so far...
|
14
16
|
|
15
|
-
==
|
17
|
+
== DOCUMENTATION:
|
16
18
|
|
17
19
|
See WinGui and WinGui::Window for documentation
|
18
20
|
|
19
|
-
==
|
21
|
+
== REQUIREMENTS:
|
22
|
+
|
23
|
+
Only works with Ruby 1.9.1+ since it uses some of the most recent features (block
|
24
|
+
arguments given to block, etc...)
|
25
|
+
|
26
|
+
== FEATURES/PROBLEMS:
|
27
|
+
|
28
|
+
This project is quite new, so it's probably not ready for prime time just yet...
|
29
|
+
Contributors always welcome!
|
30
|
+
|
31
|
+
== INSTALL:
|
32
|
+
|
33
|
+
$ sudo gem install win_gui
|
34
|
+
|
35
|
+
== SYNOPSIS:
|
20
36
|
|
21
37
|
require 'win_gui'
|
22
38
|
include WinGui
|
@@ -33,11 +49,11 @@ More examples will follow as the code will be closer to production quality...
|
|
33
49
|
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
34
50
|
* Send me a pull request. Bonus points for topic branches.
|
35
51
|
|
36
|
-
==
|
52
|
+
== CREDITS:
|
37
53
|
|
38
54
|
This library started as an extension of ideas and code described in excellent book
|
39
55
|
"Scripted GUI Testing with Ruby" by Ian Dees.
|
40
56
|
|
41
|
-
==
|
57
|
+
== LICENSE:
|
42
58
|
|
43
|
-
Copyright (c)
|
59
|
+
Copyright (c) 2009 Arvicco. See LICENSE for details
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.1
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module WinGui
|
2
|
+
module DefApi
|
3
|
+
# Defines new instance method wrapper for Windows API function call. Converts CamelCase function name
|
4
|
+
# into snake_case method name, renames test functions according to Ruby convention (IsWindow -> window?)
|
5
|
+
# When the defined wrapper method is called, it executes underlying API function call, yields the result
|
6
|
+
# to attached block (if any) and (optionally) transforms the result before returning it.
|
7
|
+
#
|
8
|
+
# You may modify default defined method behavior by providing optional &define_block to def_api.
|
9
|
+
# If you do so, instead of directly calling API function, defined method yields callable api object, arguments
|
10
|
+
# and (optional) runtime block to &define_block that should define method content and return result.
|
11
|
+
#
|
12
|
+
# Accepts following options:
|
13
|
+
# :rename:: Use this name instead of standard (conventional) function name
|
14
|
+
# :alias(es):: Provides additional alias(es) for defined method
|
15
|
+
# :boolean:: Forces method to return true/false instead of nonzero/zero
|
16
|
+
# :zeronil:: Forces method to return nil if function result is zero
|
17
|
+
#
|
18
|
+
def def_api(function, params, returns, options={}, &define_block)
|
19
|
+
name = options[:rename] || function.snake_case
|
20
|
+
if name.sub!(/^is_/, '')
|
21
|
+
name << '?'
|
22
|
+
boolean = true
|
23
|
+
end
|
24
|
+
boolean ||= options[:boolean]
|
25
|
+
zeronil = options[:zeronil]
|
26
|
+
aliases = ([options[:alias]] + [options[:aliases]]).flatten.compact
|
27
|
+
proto = params.respond_to?(:join) ? params.join : params # Converts params into prototype string
|
28
|
+
api = Win32::API.new(function, proto.upcase, returns.upcase, options[:dll] || WG_DLL_DEFAULT)
|
29
|
+
|
30
|
+
define_method(name) do |*args, &runtime_block|
|
31
|
+
return api if args == [:api]
|
32
|
+
return define_block.call(api, *args, &runtime_block) if define_block
|
33
|
+
raise 'Invalid args count' unless args.size == params.size
|
34
|
+
result = api.call(*args)
|
35
|
+
yield result if runtime_block
|
36
|
+
return result != 0 if boolean # Boolean function returns true/false instead of nonzero/zero
|
37
|
+
return nil if zeronil && result == 0
|
38
|
+
result
|
39
|
+
end
|
40
|
+
aliases.each {|aliass| alias_method aliass, name } unless aliases == []
|
41
|
+
end
|
42
|
+
|
43
|
+
# Helper methods:
|
44
|
+
|
45
|
+
# Converts block into API::Callback object that can be used as API callback argument
|
46
|
+
def callback(params, returns, &block)
|
47
|
+
Win32::API::Callback.new(params, returns, &block)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Returns string buffer - used to supply string pointer reference to API functions
|
51
|
+
def buffer(size = 1024, code = "\x00")
|
52
|
+
code * size
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
data/lib/win_gui/win_gui.rb
CHANGED
@@ -1,48 +1,19 @@
|
|
1
1
|
require 'Win32/api'
|
2
2
|
require 'string_extensions'
|
3
3
|
require 'constants'
|
4
|
+
require 'def_api'
|
4
5
|
require 'window'
|
5
6
|
|
6
|
-
#TODO - When calling API functions, win_handle arg should default to instance var @handle of the host class
|
7
|
-
#TODO - Giving a hash of "named args" to def_api, like this:
|
8
|
-
#TODO def_api 'ShowWindow', 'LI' , 'I', :args=>{1=>:handle=>, 2=>[:cmd, :command]}
|
9
|
-
#TODO - Giving a hash of "defaults" to def_api, like this:
|
10
|
-
#TODO def_api 'ShowWindow', 'LI' , 'I', :defaults=>{1=>1234, 2=>'String2'}
|
11
|
-
#TODO - Option :class_method should define CLASS method instead of instance
|
7
|
+
# TODO - When calling API functions, win_handle arg should default to instance var @handle of the host class
|
8
|
+
# TODO - Giving a hash of "named args" to def_api, like this:
|
9
|
+
# TODO def_api 'ShowWindow', 'LI' , 'I', :args=>{1=>:handle=>, 2=>[:cmd, :command]}
|
10
|
+
# TODO - Giving a hash of "defaults" to def_api, like this:
|
11
|
+
# TODO def_api 'ShowWindow', 'LI' , 'I', :defaults=>{1=>1234, 2=>'String2'}
|
12
|
+
# TODO - Option :class_method should define CLASS method instead of instance
|
12
13
|
|
13
14
|
module WinGui
|
14
|
-
|
15
|
-
|
16
|
-
def self.def_api(function, params, returns, options={}, &define_block)
|
17
|
-
name = function.snake_case
|
18
|
-
name.sub!(/^is_/, '') << '?' if name =~ /^is_/
|
19
|
-
boolean = options[:boolean] || name =~ /\?$/ # Boolean function returns true/false instead of nonzero/zero
|
20
|
-
proto = params.respond_to?(:join) ? params.join : params # Converts params into prototype string
|
21
|
-
api = Win32::API.new(function, proto.upcase, returns.upcase, options[:dll] || WG_DLL_DEFAULT)
|
22
|
-
|
23
|
-
define_method(options[:rename] || name) do |*args, &runtime_block|
|
24
|
-
return api if args == [:api]
|
25
|
-
return define_block.call(api, *args, &runtime_block) if define_block
|
26
|
-
raise 'Invalid args count' unless args.size == params.size
|
27
|
-
result = api.call(*args)
|
28
|
-
yield result if runtime_block
|
29
|
-
return result != 0 if boolean
|
30
|
-
return nil if options[:zeronil] && result == 0
|
31
|
-
result
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
# Converts block into API::Callback object that can be used as API callback argument
|
36
|
-
def self.callback(params, returns, &block)
|
37
|
-
Win32::API::Callback.new(params, returns, &block)
|
38
|
-
end
|
39
|
-
|
40
|
-
# Helper methods:
|
41
|
-
# returns string buffer - used to supply string pointer reference to API functions
|
42
|
-
def self.buffer(size = 1024, code = "\x00")
|
43
|
-
code * size
|
44
|
-
end
|
45
|
-
|
15
|
+
self.extend DefApi
|
16
|
+
|
46
17
|
return_string_proc = lambda do |api, *args|
|
47
18
|
raise 'Invalid args count' unless args.size == api.prototype.size-2
|
48
19
|
args += [string = buffer, string.length]
|
@@ -72,23 +43,23 @@ module WinGui
|
|
72
43
|
handles
|
73
44
|
end
|
74
45
|
|
75
|
-
# Windows API definitions:
|
76
|
-
|
46
|
+
# Windows GUI API definitions:
|
47
|
+
|
77
48
|
# Tests whether the specified window handle identifies an existing window.
|
78
49
|
# A thread should not use IsWindow for a window that it did not create because the window could be destroyed after this
|
79
50
|
# function was called. Further, because window handles are recycled the handle could even point to a different window.
|
51
|
+
def_api 'IsWindow', 'L', 'L'
|
80
52
|
|
81
|
-
def_api 'IsWindowVisible', 'L', 'L'
|
82
|
-
alias visible? window_visible?
|
83
53
|
# Tests if the specified window, its parent window, its parent's parent window, and so forth, have the WS_VISIBLE style.
|
84
54
|
# Because the return value specifies whether the window has the WS_VISIBLE style, it may be true even if the window is totally obscured by other windows.
|
55
|
+
def_api 'IsWindowVisible', 'L', 'L'
|
56
|
+
alias visible? window_visible?
|
85
57
|
|
86
58
|
def_api 'IsZoomed', 'L', 'L'
|
87
59
|
alias maximized? zoomed?
|
88
60
|
# Tests whether the specified window is maximized.
|
89
61
|
|
90
|
-
def_api 'IsIconic', 'L', 'L'
|
91
|
-
alias minimized? iconic?
|
62
|
+
def_api 'IsIconic', 'L', 'L', :alias => :minimized?
|
92
63
|
# Tests whether the specified window is maximized.
|
93
64
|
|
94
65
|
def_api 'IsChild', 'LL', 'L'
|
File without changes
|
data/{exp/old → old}/wnote.rb
RENAMED
File without changes
|
File without changes
|
data/spec/spec_helper.rb
CHANGED
@@ -0,0 +1,242 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "..", "spec_helper" )
|
2
|
+
|
3
|
+
module GuiTest
|
4
|
+
|
5
|
+
# def enum_callback
|
6
|
+
# @enum_callback ||= WinGui.callback('LP', 'I'){|handle, message| true }
|
7
|
+
# end
|
8
|
+
|
9
|
+
describe WinGui::DefApi, 'defines wrappers for Win32::API functions' do
|
10
|
+
before(:each) { hide_method :find_window_w } # hide original method if it is defined
|
11
|
+
after(:each) { restore_method :find_window_w } # restore original method if it was hidden
|
12
|
+
|
13
|
+
context 'defining a valid API function' do
|
14
|
+
spec{ use{ WinGui.def_api('FindWindowW', 'PP', 'L', :rename => nil, :alias => nil, :boolean => nil, :zeronil => nil, &any_block) }}
|
15
|
+
|
16
|
+
it 'defines new instance method with appropriate name' do
|
17
|
+
WinGui.def_api 'FindWindowW', 'PP', 'L'
|
18
|
+
respond_to?(:find_window_w).should be_true
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'constructs argument prototype from uppercase string' do
|
22
|
+
expect { WinGui.def_api 'FindWindowW', 'PP', 'L' }.to_not raise_error
|
23
|
+
expect { find_window_w(nil) }.to raise_error 'Invalid args count'
|
24
|
+
expect { find_window_w(nil, nil) }.to_not raise_error 'Invalid args count'
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'constructs argument prototype from lowercase string' do
|
28
|
+
expect { WinGui.def_api 'FindWindowW', 'pp', 'l' }.to_not raise_error
|
29
|
+
expect { find_window_w(nil) }.to raise_error 'Invalid args count'
|
30
|
+
expect { find_window_w(nil, nil) }.to_not raise_error 'Invalid args count'
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'constructs argument prototype from (mixedcase) array' do
|
34
|
+
expect { WinGui.def_api 'FindWindowW', ['p', 'P'], 'L' }.to_not raise_error
|
35
|
+
expect { find_window_w(nil) }.to raise_error 'Invalid args count'
|
36
|
+
expect { find_window_w(nil, nil) }.to_not raise_error 'Invalid args count'
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'overrides standard name for defined method with :rename option' do
|
40
|
+
WinGui.def_api 'FindWindowW', 'PP', 'L', :rename=> 'my_own_find'
|
41
|
+
expect {find_window_w(nil, nil)}.to raise_error
|
42
|
+
expect {my_own_find(nil, nil)}.to_not raise_error
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'adds alias for defined method with :alias option' do
|
46
|
+
WinGui.def_api 'FindWindowW', 'PP', 'L', :alias => 'my_own_find'
|
47
|
+
expect {find_window_w(nil, nil)}.to_not raise_error
|
48
|
+
expect {my_own_find(nil, nil)}.to_not raise_error
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'adds aliases for defined method with :aliases option' do
|
52
|
+
WinGui.def_api 'FindWindowW', 'PP', 'L', :aliases => ['my_own_find', 'my_own_find1']
|
53
|
+
expect {find_window_w(nil, nil)}.to_not raise_error
|
54
|
+
expect {my_own_find(nil, nil)}.to_not raise_error
|
55
|
+
expect {my_own_find1(nil, nil)}.to_not raise_error
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'defined method works properly when called with a valid args' do
|
59
|
+
WinGui.def_api 'FindWindowW', 'PP', 'L'
|
60
|
+
expect {find_window_w(nil, nil)}.to_not raise_error
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'defined method returns expected value when called' do
|
64
|
+
WinGui.def_api 'FindWindowW', 'PP', 'L'
|
65
|
+
find_window_w(nil, nil).should_not == 0
|
66
|
+
find_window_w(nil, TEST_IMPOSSIBLE).should == 0
|
67
|
+
find_window_w(TEST_IMPOSSIBLE, nil).should == 0
|
68
|
+
find_window_w(TEST_IMPOSSIBLE, TEST_IMPOSSIBLE).should == 0
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'defined method enforces the argument count when called' do
|
72
|
+
WinGui.def_api 'FindWindowW', 'PP', 'L'
|
73
|
+
expect { find_window_w }.to raise_error 'Invalid args count'
|
74
|
+
expect { find_window_w(nil) }.to raise_error 'Invalid args count'
|
75
|
+
expect { find_window_w('Str') }.to raise_error 'Invalid args count'
|
76
|
+
expect { find_window_w([nil, nil]) }.to raise_error 'Invalid args count'
|
77
|
+
expect { find_window_w('Str', 'Str', 'Str') }.to raise_error 'Invalid args count'
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'returns underlying Win32::API object if defined method is called with (:api) argument ' do
|
81
|
+
WinGui.def_api 'FindWindowW', 'PP', 'L'
|
82
|
+
expect {@api = find_window_w(:api)}.to_not raise_error
|
83
|
+
@api.dll_name.should == 'user32' # The name of the DLL that exports the API function
|
84
|
+
@api.effective_function_name.should == 'FindWindowW' # Actual function returned by the constructor: 'GetUserName' ->'GetUserNameA' or 'GetUserNameW'
|
85
|
+
@api.function_name.should == 'FindWindowW' # The name of the function passed to the constructor
|
86
|
+
@api.prototype.should == ['P', 'P'] # The prototype, returned as an array of characters
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
context 'auto-defining Ruby-like boolean methods if API function name starts with "Is_"' do
|
91
|
+
before(:each) do
|
92
|
+
hide_method :window?
|
93
|
+
WinGui.def_api 'IsWindow', 'L', 'L'
|
94
|
+
end
|
95
|
+
after(:each) { restore_method :window? }
|
96
|
+
|
97
|
+
it 'defines new instance method name dropping Is_ and adding ?' do
|
98
|
+
respond_to?(:window?).should be_true
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'defined method returns false/true instead of zero/non-zero' do
|
102
|
+
window?(any_handle).should == true
|
103
|
+
window?(not_a_handle).should == false
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'defined method enforces the argument count' do
|
107
|
+
expect {window?}.to raise_error 'Invalid args count'
|
108
|
+
expect {window?(not_a_handle, nil)}.to raise_error 'Invalid args count'
|
109
|
+
expect {window?(nil, nil)}.to raise_error 'Invalid args count'
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
context 'defining API with :boolean option converts result to boolean' do
|
114
|
+
before(:each) do
|
115
|
+
WinGui.def_api 'FindWindowW', 'PP', 'L', :boolean => true
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'defines new instance method' do
|
119
|
+
respond_to?(:find_window_w).should be_true
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'defined method returns false/true instead of zero/non-zero' do
|
123
|
+
find_window_w(nil, nil).should == true
|
124
|
+
find_window_w(nil, TEST_IMPOSSIBLE).should == false
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'defined method enforces the argument count' do
|
128
|
+
expect {find_window_w}.to raise_error 'Invalid args count'
|
129
|
+
expect {find_window_w(nil, nil, nil)}.to raise_error 'Invalid args count'
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
context 'defining API with :zeronil option converts zero result to nil' do
|
134
|
+
before(:each) do
|
135
|
+
WinGui.def_api 'FindWindowW', 'PP', 'L', :zeronil => true
|
136
|
+
end
|
137
|
+
|
138
|
+
it 'defines new instance method' do
|
139
|
+
respond_to?(:find_window_w).should be_true
|
140
|
+
end
|
141
|
+
|
142
|
+
it 'defined method returns nil (but NOT false) instead of zero' do
|
143
|
+
find_window_w(nil, TEST_IMPOSSIBLE).should_not == false
|
144
|
+
find_window_w(nil, TEST_IMPOSSIBLE).should == nil
|
145
|
+
end
|
146
|
+
|
147
|
+
it 'defined method does not return true when result is non-zero' do
|
148
|
+
find_window_w(nil, nil).should_not == true
|
149
|
+
find_window_w(nil, nil).should_not == 0
|
150
|
+
end
|
151
|
+
|
152
|
+
it 'defined method enforces the argument count' do
|
153
|
+
expect {find_window_w}.to raise_error 'Invalid args count'
|
154
|
+
expect {find_window_w(nil, nil, nil)}.to raise_error 'Invalid args count'
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
context 'trying to define an invalid API function' do
|
159
|
+
it 'raises error when trying to define function with a wrong function name' do
|
160
|
+
expect { WinGui.def_api 'FindWindowImpossible', 'PP', 'L' }.
|
161
|
+
to raise_error( /Unable to load function 'FindWindowImpossible'/ )
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
context 'defining API function using definition blocks' do
|
166
|
+
|
167
|
+
it 'defines new instance method' do
|
168
|
+
WinGui.def_api( 'FindWindowW', 'PP', 'L' ){|api, *args|}
|
169
|
+
respond_to?(:find_window_w).should be_true
|
170
|
+
end
|
171
|
+
|
172
|
+
it 'does not enforce argument count outside of block' do
|
173
|
+
WinGui.def_api( 'FindWindowW', 'PP', 'L' ){|api, *args|}
|
174
|
+
expect { find_window_w }.to_not raise_error 'Invalid args count'
|
175
|
+
expect { find_window_w(nil) }.to_not raise_error 'Invalid args count'
|
176
|
+
expect { find_window_w(nil, 'Str') }.to_not raise_error 'Invalid args count'
|
177
|
+
end
|
178
|
+
|
179
|
+
it 'returns block return value when defined method is called' do
|
180
|
+
WinGui.def_api( 'FindWindowW', 'PP', 'L' ){|api, *args| 'Value'}
|
181
|
+
find_window_w(nil).should == 'Value'
|
182
|
+
end
|
183
|
+
|
184
|
+
it 'passes arguments and underlying Win32::API object to the block' do
|
185
|
+
WinGui.def_api( 'FindWindowW', 'PP', 'L' ) do |api, *args|
|
186
|
+
@api = api
|
187
|
+
@args = args
|
188
|
+
end
|
189
|
+
find_window_w(1, 2, 3)
|
190
|
+
@args.should == [1, 2, 3]
|
191
|
+
@api.function_name.should == 'FindWindowW' # The name of the function passed to the constructor
|
192
|
+
end
|
193
|
+
|
194
|
+
it ':rename option overrides standard name for defined method' do
|
195
|
+
WinGui.def_api( 'FindWindowW', 'PP', 'L', :rename => 'my_own_find' ){|api, *args|}
|
196
|
+
expect {find_window_w(nil, nil, nil)}.to raise_error
|
197
|
+
expect {my_own_find(nil, nil)}.to_not raise_error
|
198
|
+
end
|
199
|
+
it 'adds alias for defined method with :alias option' do
|
200
|
+
WinGui.def_api( 'FindWindowW', 'PP', 'L', :alias => 'my_own_find' ){|api, *args|}
|
201
|
+
expect {find_window_w(nil, nil)}.to_not raise_error
|
202
|
+
expect {my_own_find(nil, nil)}.to_not raise_error
|
203
|
+
end
|
204
|
+
|
205
|
+
it 'adds aliases for defined method with :aliases option' do
|
206
|
+
WinGui.def_api( 'FindWindowW', 'PP', 'L', :aliases => ['my_own_find', 'my_own_find1'] ) {|api, *args|}
|
207
|
+
expect {find_window_w(nil, nil)}.to_not raise_error
|
208
|
+
expect {my_own_find(nil, nil)}.to_not raise_error
|
209
|
+
expect {my_own_find1(nil, nil)}.to_not raise_error
|
210
|
+
end
|
211
|
+
|
212
|
+
it 'returns underlying Win32::API object if defined method is called with (:api) argument ' do
|
213
|
+
WinGui.def_api( 'FindWindowW', 'PP', 'L' ){|api, *args|}
|
214
|
+
expect {@api = find_window_w(:api)}.to_not raise_error
|
215
|
+
@api.dll_name.should == 'user32' # The name of the DLL that exports the API function
|
216
|
+
@api.effective_function_name.should == 'FindWindowW' # Actual function returned by the constructor: 'GetUserName' ->'GetUserNameA' or 'GetUserNameW'
|
217
|
+
@api.function_name.should == 'FindWindowW' # The name of the function passed to the constructor
|
218
|
+
@api.prototype.should == ['P', 'P'] # The prototype, returned as an array of characters
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
context 'providing API function with callback' do
|
223
|
+
before(:each) { hide_method :enum_windows } # hide original find_window method if it is defined
|
224
|
+
after(:each) { restore_method :enum_windows } # restore original find_window method if it was hidden
|
225
|
+
|
226
|
+
it '#callback method creates a valid callback object' do
|
227
|
+
expect { @callback = WinGui.callback('LP', 'I') {|handle, message| true} }.to_not raise_error
|
228
|
+
@callback.should be_a_kind_of(Win32::API::Callback)
|
229
|
+
end
|
230
|
+
|
231
|
+
it 'created callback object can be used as a valid arg of API function expecting callback' do
|
232
|
+
WinGui.def_api 'EnumWindows', 'KP', 'L'
|
233
|
+
@enum_callback ||= WinGui.callback('LP', 'I'){|handle, message| true }
|
234
|
+
expect { enum_windows(@enum_callback, 'Message') }.to_not raise_error
|
235
|
+
end
|
236
|
+
|
237
|
+
it 'defined API functions expecting callback recognize/accept blocks' do
|
238
|
+
pending ' API is not exactly clear atm (what about prototype?)(.with_callback method?)'
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
@@ -1,256 +1,6 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), "..", "spec_helper" )
|
2
2
|
|
3
3
|
module GuiTest
|
4
|
-
|
5
|
-
# def enum_callback
|
6
|
-
# @enum_callback ||= callback('LP', 'I'){|handle, message| true }
|
7
|
-
# end
|
8
|
-
|
9
|
-
describe WinGui, ' defines wrappers for Win32::API functions' do
|
10
|
-
|
11
|
-
context 'defining a valid API function' do
|
12
|
-
before(:each) { hide_method :find_window_w } # hide original method if it is defined
|
13
|
-
after(:each) { restore_method :find_window_w } # restore original method if it was hidden
|
14
|
-
|
15
|
-
spec{ use{ WinGui.def_api('FindWindowW', 'PP', 'L', :rename => nil, :boolean => nil, :zeronil => nil, &any_block) }}
|
16
|
-
|
17
|
-
it 'defines new instance method with appropriate name' do
|
18
|
-
WinGui.def_api 'FindWindowW', 'PP', 'L'
|
19
|
-
respond_to?(:find_window_w).should be_true
|
20
|
-
end
|
21
|
-
|
22
|
-
it 'constructs argument prototype from uppercase string' do
|
23
|
-
expect { WinGui.def_api 'FindWindowW', 'PP', 'L' }.to_not raise_error
|
24
|
-
expect { find_window_w(nil) }.to raise_error 'Invalid args count'
|
25
|
-
expect { find_window_w(nil, nil) }.to_not raise_error 'Invalid args count'
|
26
|
-
end
|
27
|
-
|
28
|
-
it 'constructs argument prototype from lowercase string' do
|
29
|
-
expect { WinGui.def_api 'FindWindowW', 'pp', 'l' }.to_not raise_error
|
30
|
-
expect { find_window_w(nil) }.to raise_error 'Invalid args count'
|
31
|
-
expect { find_window_w(nil, nil) }.to_not raise_error 'Invalid args count'
|
32
|
-
end
|
33
|
-
|
34
|
-
it 'constructs argument prototype from (mixedcase) array' do
|
35
|
-
expect { WinGui.def_api 'FindWindowW', ['p', 'P'], 'L' }.to_not raise_error
|
36
|
-
expect { find_window_w(nil) }.to raise_error 'Invalid args count'
|
37
|
-
expect { find_window_w(nil, nil) }.to_not raise_error 'Invalid args count'
|
38
|
-
end
|
39
|
-
|
40
|
-
it ':rename option overrides standard name for defined method' do
|
41
|
-
WinGui.def_api 'FindWindowW', 'PP', 'L', :rename=> 'my_own_find'
|
42
|
-
expect {find_window_w(nil, nil)}.to raise_error
|
43
|
-
expect {my_own_find(nil, nil)}.to_not raise_error
|
44
|
-
end
|
45
|
-
|
46
|
-
it 'defined method works properly when called with a valid args' do
|
47
|
-
WinGui.def_api 'FindWindowW', 'PP', 'L'
|
48
|
-
expect {find_window_w(nil, nil)}.to_not raise_error
|
49
|
-
end
|
50
|
-
|
51
|
-
it 'defined method returns expected value when called' do
|
52
|
-
WinGui.def_api 'FindWindowW', 'PP', 'L'
|
53
|
-
test_app do |app|
|
54
|
-
find_window_w(nil, TEST_WIN_TITLE.to_w).should_not == 0
|
55
|
-
find_window_w(TEST_WIN_CLASS.to_w, nil).should_not == 0
|
56
|
-
end
|
57
|
-
find_window_w(nil, nil).should_not == 0
|
58
|
-
find_window_w(nil, TEST_IMPOSSIBLE).should == 0
|
59
|
-
find_window_w(TEST_IMPOSSIBLE, nil).should == 0
|
60
|
-
find_window_w(TEST_IMPOSSIBLE, TEST_IMPOSSIBLE).should == 0
|
61
|
-
end
|
62
|
-
|
63
|
-
it 'defined method enforces the argument count when called' do
|
64
|
-
WinGui.def_api 'FindWindowW', 'PP', 'L'
|
65
|
-
expect { find_window_w }.to raise_error 'Invalid args count'
|
66
|
-
expect { find_window_w(nil) }.to raise_error 'Invalid args count'
|
67
|
-
expect { find_window_w('Str') }.to raise_error 'Invalid args count'
|
68
|
-
expect { find_window_w([nil, nil]) }.to raise_error 'Invalid args count'
|
69
|
-
expect { find_window_w('Str', 'Str', 'Str') }.to raise_error 'Invalid args count'
|
70
|
-
end
|
71
|
-
|
72
|
-
it 'defined method called with (:api) argument returns underlying Win32::API object' do
|
73
|
-
WinGui.def_api 'FindWindowW', 'PP', 'L'
|
74
|
-
expect {@api = find_window_w(:api)}.to_not raise_error
|
75
|
-
@api.dll_name.should == 'user32' # The name of the DLL that exports the API function
|
76
|
-
@api.effective_function_name.should == 'FindWindowW' # Actual function returned by the constructor: 'GetUserName' ->'GetUserNameA' or 'GetUserNameW'
|
77
|
-
@api.function_name.should == 'FindWindowW' # The name of the function passed to the constructor
|
78
|
-
@api.prototype.should == ['P', 'P'] # The prototype, returned as an array of characters
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
context 'auto-defining Ruby-like boolean methods if API function name starts with "Is_"' do
|
83
|
-
before(:each) do
|
84
|
-
hide_method :window?
|
85
|
-
WinGui.def_api 'IsWindow', 'L', 'L'
|
86
|
-
end
|
87
|
-
after(:each) { restore_method :window? }
|
88
|
-
|
89
|
-
it 'defines new instance method name dropping Is_ and adding ?' do
|
90
|
-
respond_to?(:window?).should be_true
|
91
|
-
end
|
92
|
-
|
93
|
-
it 'defined method returns true instead of non-zero' do
|
94
|
-
window?(any_handle).should == true
|
95
|
-
end
|
96
|
-
|
97
|
-
it 'defined method returns false instead of zero' do
|
98
|
-
window?(123).should == false
|
99
|
-
end
|
100
|
-
|
101
|
-
it 'defined method enforces the argument count' do
|
102
|
-
expect {window?}.to raise_error 'Invalid args count'
|
103
|
-
expect {window?(123, nil)}.to raise_error 'Invalid args count'
|
104
|
-
expect {window?(nil, nil)}.to raise_error 'Invalid args count'
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
context 'defining API with :boolean option converts result to boolean' do
|
109
|
-
before(:each) do
|
110
|
-
hide_method :show_window
|
111
|
-
WinGui.def_api 'ShowWindow', 'LI', 'I', :boolean => true
|
112
|
-
end
|
113
|
-
after(:each) { restore_method :show_window }
|
114
|
-
|
115
|
-
it 'defines new instance method' do
|
116
|
-
respond_to?(:show_window).should be_true
|
117
|
-
end
|
118
|
-
|
119
|
-
it 'defined method returns true instead of non-zero' do
|
120
|
-
test_app {|app| show_window(app.handle, SW_SHOWNA).should == true }
|
121
|
-
end
|
122
|
-
|
123
|
-
it 'defined method returns false instead of zero' do
|
124
|
-
test_app do |app|
|
125
|
-
show_window(app.handle, SW_HIDE)
|
126
|
-
show_window(app.handle, SW_HIDE).should == false
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
it 'defined method enforces the argument count' do
|
131
|
-
test_app do |app|
|
132
|
-
expect {show_window}.to raise_error 'Invalid args count'
|
133
|
-
expect {show_window(app.handle, SW_HIDE, nil)}.to raise_error 'Invalid args count'
|
134
|
-
end
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
|
-
context 'defining API with :zeronil option converts zero result to nil' do
|
139
|
-
before(:each) do
|
140
|
-
hide_method :show_window
|
141
|
-
WinGui.def_api 'ShowWindow', 'LI', 'I', :zeronil => true
|
142
|
-
end
|
143
|
-
after(:each) { restore_method :show_window }
|
144
|
-
|
145
|
-
it 'defines new instance method' do
|
146
|
-
respond_to?(:show_window).should be_true
|
147
|
-
end
|
148
|
-
|
149
|
-
it 'defined method returns nil (but NOT false) instead of zero' do
|
150
|
-
test_app do |app|
|
151
|
-
show_window(app.handle, SW_HIDE)
|
152
|
-
show_window(app.handle, SW_HIDE).should == nil
|
153
|
-
show_window(app.handle, SW_HIDE).should_not == false
|
154
|
-
end
|
155
|
-
end
|
156
|
-
|
157
|
-
it 'defined method does not return true when result is non-zero' do
|
158
|
-
test_app do |app|
|
159
|
-
result = show_window(app.handle, SW_SHOWNA)
|
160
|
-
result.should_not == 0
|
161
|
-
result.should_not == true
|
162
|
-
end
|
163
|
-
end
|
164
|
-
|
165
|
-
it 'defined method enforces the argument count' do
|
166
|
-
test_app do |app|
|
167
|
-
expect {show_window}.to raise_error 'Invalid args count'
|
168
|
-
expect {show_window(app.handle, SW_HIDE, nil)}.to raise_error 'Invalid args count'
|
169
|
-
end
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
|
-
context 'trying to define an invalid API function' do
|
174
|
-
it 'raises error when trying to define function with a wrong function name' do
|
175
|
-
expect { WinGui.def_api 'FindWindowImpossible', 'PP', 'L' }.
|
176
|
-
to raise_error( /Unable to load function 'FindWindowImpossible'/ )
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
context 'defining API function using definition blocks' do
|
181
|
-
before(:each) { hide_method :get_window_text } # hide original method if it is defined
|
182
|
-
after(:each) { restore_method :get_window_text } # restore original method if it was hidden
|
183
|
-
|
184
|
-
it 'defines new instance method' do
|
185
|
-
WinGui.def_api 'GetWindowText', 'LPL', 'L' do |api, *args|
|
186
|
-
end
|
187
|
-
respond_to?(:get_window_text).should be_true
|
188
|
-
end
|
189
|
-
|
190
|
-
it 'does not enforce argument count outside of block' do
|
191
|
-
WinGui.def_api 'GetWindowText', 'LPL', 'L' do |api, *args|
|
192
|
-
end
|
193
|
-
expect { get_window_text }.to_not raise_error 'Invalid args count'
|
194
|
-
expect { get_window_text(nil) }.to_not raise_error 'Invalid args count'
|
195
|
-
expect { get_window_text(nil, 'Str') }.to_not raise_error 'Invalid args count'
|
196
|
-
end
|
197
|
-
|
198
|
-
it 'returns block return value when defined method is called' do
|
199
|
-
WinGui.def_api 'GetWindowText', 'LPL', 'L' do |api, *args|
|
200
|
-
'Value'
|
201
|
-
end
|
202
|
-
get_window_text(nil).should == 'Value'
|
203
|
-
end
|
204
|
-
|
205
|
-
it 'passes arguments and underlying Win32::API object to the block' do
|
206
|
-
WinGui.def_api 'GetWindowText', 'LPL', 'L' do |api, *args|
|
207
|
-
@api=api; @args = args
|
208
|
-
end
|
209
|
-
get_window_text(1, 2, 3)
|
210
|
-
@args.should == [1, 2, 3]
|
211
|
-
@api.function_name.should == 'GetWindowText' # The name of the function passed to the constructor
|
212
|
-
end
|
213
|
-
|
214
|
-
it ':rename option overrides standard name for defined method' do
|
215
|
-
WinGui.def_api 'GetWindowText', 'LPL', 'L', :rename => 'my_name' do |api, *args|
|
216
|
-
end
|
217
|
-
expect {get_window_text(nil, nil, nil)}.to raise_error
|
218
|
-
expect {my_name(nil, nil)}.to_not raise_error
|
219
|
-
end
|
220
|
-
|
221
|
-
it 'calling defined method with (:api) argument returns underlying Win32::API object' do
|
222
|
-
WinGui.def_api 'GetWindowText', 'LPL', 'L' do |api, *args|
|
223
|
-
end
|
224
|
-
expect {@api = get_window_text(:api)}.to_not raise_error
|
225
|
-
@api.dll_name.should == 'user32' # The name of the DLL that exports the API function
|
226
|
-
@api.effective_function_name.should == 'GetWindowTextA' # Actual function returned by the constructor: 'GetUserName' ->'GetUserNameA' or 'GetUserNameW'
|
227
|
-
@api.function_name.should == 'GetWindowText' # The name of the function passed to the constructor
|
228
|
-
@api.prototype.should == ['L', 'P', 'L'] # The prototype, returned as an array of characters
|
229
|
-
end
|
230
|
-
end
|
231
|
-
|
232
|
-
context 'providing API function with callback' do
|
233
|
-
# before(:each) { hide_method :enum_windows } # hide original find_window method if it is defined
|
234
|
-
# after(:each) { restore_method :enum_window } # restore original find_window method if it was hidden
|
235
|
-
#
|
236
|
-
it '#callback method creates a valid callback object' do
|
237
|
-
pending 'callback is now a class method of WinGui, not available here (exept through module_eval)'
|
238
|
-
expect { @callback = callback('LP', 'I') {|handle, message| true} }.to_not raise_error
|
239
|
-
@callback.should be_a_kind_of(Win32::API::Callback)
|
240
|
-
end
|
241
|
-
|
242
|
-
it 'created callback object can be used as a valid arg of API function expecting callback' do
|
243
|
-
pending 'API changed - callback arg is no longer valid, block is used instead'
|
244
|
-
# WinGui.def_api 'EnumWindows', 'KP', 'L'
|
245
|
-
expect { enum_windows(enum_callback, 'Message') }.to_not raise_error
|
246
|
-
end
|
247
|
-
|
248
|
-
it 'defined API functions expecting callback recognize/accept blocks' do
|
249
|
-
pending ' API is not exactly clear atm (what about prototype?)(.with_callback method?)'
|
250
|
-
end
|
251
|
-
end
|
252
|
-
end
|
253
|
-
|
254
4
|
describe WinGui, ' contains a set of pre-defined GUI functions' do
|
255
5
|
describe '#window?' do
|
256
6
|
spec{ use{ window?(handle = 0) }}
|
data/win_gui.gemspec
ADDED
@@ -0,0 +1,215 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{win_gui}
|
8
|
+
s.version = "0.1.1"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["arvicco"]
|
12
|
+
s.date = %q{2010-01-26}
|
13
|
+
s.description = %q{Rubyesque interfaces and wrappers for Win32 API GUI functions}
|
14
|
+
s.email = %q{arvitallian@gmail.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
".gitignore",
|
22
|
+
"LICENSE",
|
23
|
+
"README.rdoc",
|
24
|
+
"Rakefile",
|
25
|
+
"VERSION",
|
26
|
+
"book_code/early_success/bundle.rb",
|
27
|
+
"book_code/early_success/english.txt",
|
28
|
+
"book_code/early_success/jruby_basics.rb",
|
29
|
+
"book_code/early_success/windows_basics.rb",
|
30
|
+
"book_code/guessing/locknote.rb",
|
31
|
+
"book_code/guessing/monkeyshines.rb",
|
32
|
+
"book_code/guessing/note.rb",
|
33
|
+
"book_code/guessing/note_spec.rb",
|
34
|
+
"book_code/guessing/replay.rb",
|
35
|
+
"book_code/guessing/seed.rb",
|
36
|
+
"book_code/guessing/spec_helper.rb",
|
37
|
+
"book_code/guessing/windows_gui.rb",
|
38
|
+
"book_code/home_stretch/junquenote.rb",
|
39
|
+
"book_code/home_stretch/locknote.rb",
|
40
|
+
"book_code/home_stretch/note.rb",
|
41
|
+
"book_code/home_stretch/note_spec.rb",
|
42
|
+
"book_code/home_stretch/spec_helper.rb",
|
43
|
+
"book_code/home_stretch/swing_gui.rb",
|
44
|
+
"book_code/home_stretch/windows_gui.rb",
|
45
|
+
"book_code/junquenote/exports.sh",
|
46
|
+
"book_code/junquenote/jruby_mac.sh",
|
47
|
+
"book_code/junquenote/junquenote_app.rb",
|
48
|
+
"book_code/novite/Rakefile",
|
49
|
+
"book_code/novite/app/controllers/application.rb",
|
50
|
+
"book_code/novite/app/controllers/guests_controller.rb",
|
51
|
+
"book_code/novite/app/controllers/parties_controller.rb",
|
52
|
+
"book_code/novite/app/helpers/application_helper.rb",
|
53
|
+
"book_code/novite/app/helpers/guests_helper.rb",
|
54
|
+
"book_code/novite/app/helpers/parties_helper.rb",
|
55
|
+
"book_code/novite/app/models/guest.rb",
|
56
|
+
"book_code/novite/app/models/party.rb",
|
57
|
+
"book_code/novite/app/models/party_mailer.rb",
|
58
|
+
"book_code/novite/app/views/layouts/application.rhtml",
|
59
|
+
"book_code/novite/app/views/parties/new.html.erb",
|
60
|
+
"book_code/novite/app/views/parties/show.html.erb",
|
61
|
+
"book_code/novite/app/views/party_mailer/invite.erb",
|
62
|
+
"book_code/novite/config/boot.rb",
|
63
|
+
"book_code/novite/config/database.yml",
|
64
|
+
"book_code/novite/config/environment.rb",
|
65
|
+
"book_code/novite/config/environments/development.rb",
|
66
|
+
"book_code/novite/config/environments/production.rb",
|
67
|
+
"book_code/novite/config/environments/test.rb",
|
68
|
+
"book_code/novite/config/initializers/inflections.rb",
|
69
|
+
"book_code/novite/config/initializers/mime_types.rb",
|
70
|
+
"book_code/novite/config/routes.rb",
|
71
|
+
"book_code/novite/db/migrate/001_create_parties.rb",
|
72
|
+
"book_code/novite/db/migrate/002_create_guests.rb",
|
73
|
+
"book_code/novite/db/schema.rb",
|
74
|
+
"book_code/novite/log/empty.txt",
|
75
|
+
"book_code/novite/public/.htaccess",
|
76
|
+
"book_code/novite/public/404.html",
|
77
|
+
"book_code/novite/public/422.html",
|
78
|
+
"book_code/novite/public/500.html",
|
79
|
+
"book_code/novite/public/dispatch.cgi",
|
80
|
+
"book_code/novite/public/dispatch.fcgi",
|
81
|
+
"book_code/novite/public/dispatch.rb",
|
82
|
+
"book_code/novite/public/favicon.ico",
|
83
|
+
"book_code/novite/public/images/rails.png",
|
84
|
+
"book_code/novite/public/index.html",
|
85
|
+
"book_code/novite/public/javascripts/application.js",
|
86
|
+
"book_code/novite/public/javascripts/controls.js",
|
87
|
+
"book_code/novite/public/javascripts/dragdrop.js",
|
88
|
+
"book_code/novite/public/javascripts/effects.js",
|
89
|
+
"book_code/novite/public/javascripts/prototype.js",
|
90
|
+
"book_code/novite/public/robots.txt",
|
91
|
+
"book_code/novite/script/about",
|
92
|
+
"book_code/novite/script/console",
|
93
|
+
"book_code/novite/script/destroy",
|
94
|
+
"book_code/novite/script/generate",
|
95
|
+
"book_code/novite/script/performance/benchmarker",
|
96
|
+
"book_code/novite/script/performance/profiler",
|
97
|
+
"book_code/novite/script/performance/request",
|
98
|
+
"book_code/novite/script/plugin",
|
99
|
+
"book_code/novite/script/process/inspector",
|
100
|
+
"book_code/novite/script/process/reaper",
|
101
|
+
"book_code/novite/script/process/spawner",
|
102
|
+
"book_code/novite/script/runner",
|
103
|
+
"book_code/novite/script/server",
|
104
|
+
"book_code/novite/test/test_helper.rb",
|
105
|
+
"book_code/one_more_thing/applescript.rb",
|
106
|
+
"book_code/one_more_thing/note_spec.rb",
|
107
|
+
"book_code/one_more_thing/spec_helper.rb",
|
108
|
+
"book_code/one_more_thing/textedit-pure.rb",
|
109
|
+
"book_code/one_more_thing/textedit.applescript",
|
110
|
+
"book_code/one_more_thing/textedit.rb",
|
111
|
+
"book_code/one_more_thing/textnote.rb",
|
112
|
+
"book_code/simplify/junquenote.rb",
|
113
|
+
"book_code/simplify/locknote.rb",
|
114
|
+
"book_code/simplify/note.rb",
|
115
|
+
"book_code/simplify/note_spec.rb",
|
116
|
+
"book_code/simplify/swing_gui.rb",
|
117
|
+
"book_code/simplify/windows_gui.rb",
|
118
|
+
"book_code/simplify/windows_gui_spec.rb",
|
119
|
+
"book_code/story/invite.story",
|
120
|
+
"book_code/story/journal.txt",
|
121
|
+
"book_code/story/novite_stories.rb",
|
122
|
+
"book_code/story/party.rb",
|
123
|
+
"book_code/story/password.rb",
|
124
|
+
"book_code/story/password.story",
|
125
|
+
"book_code/story/rsvp.story",
|
126
|
+
"book_code/tables/TestTime.html",
|
127
|
+
"book_code/tables/TestTimeSample.html",
|
128
|
+
"book_code/tables/calculate_time.rb",
|
129
|
+
"book_code/tables/calculator.rb",
|
130
|
+
"book_code/tables/calculator_actions.rb",
|
131
|
+
"book_code/tables/calculator_spec.rb",
|
132
|
+
"book_code/tables/fit.rb",
|
133
|
+
"book_code/tables/matrix.rb",
|
134
|
+
"book_code/tables/pseudocode.rb",
|
135
|
+
"book_code/tubes/book_selenium.rb",
|
136
|
+
"book_code/tubes/book_watir.rb",
|
137
|
+
"book_code/tubes/dragdrop.html",
|
138
|
+
"book_code/tubes/html_capture.rb",
|
139
|
+
"book_code/tubes/joke_list.rb",
|
140
|
+
"book_code/tubes/list_spec.rb",
|
141
|
+
"book_code/tubes/search_spec.rb",
|
142
|
+
"book_code/tubes/selenium_example.rb",
|
143
|
+
"book_code/tubes/selenium_link.rb",
|
144
|
+
"book_code/tubes/web_server.rb",
|
145
|
+
"book_code/windows/wgui.rb",
|
146
|
+
"book_code/windows/wobj.rb",
|
147
|
+
"book_code/windows/wsh.rb",
|
148
|
+
"book_code/with_rspec/empty_spec.rb",
|
149
|
+
"book_code/with_rspec/junquenote.rb",
|
150
|
+
"book_code/with_rspec/locknote.rb",
|
151
|
+
"book_code/with_rspec/note_spec.rb",
|
152
|
+
"book_code/with_rspec/should_examples.rb",
|
153
|
+
"features/step_definitions/win_gui_steps.rb",
|
154
|
+
"features/support/env.rb",
|
155
|
+
"features/win_gui.feature",
|
156
|
+
"lib/note.rb",
|
157
|
+
"lib/note/java/jemmy.jar",
|
158
|
+
"lib/note/java/jnote.rb",
|
159
|
+
"lib/note/java/jruby_basics.rb",
|
160
|
+
"lib/note/java/junquenote_app.rb",
|
161
|
+
"lib/note/java/note_spec.rb",
|
162
|
+
"lib/note/win/locknote.rb",
|
163
|
+
"lib/win_gui.rb",
|
164
|
+
"lib/win_gui/constants.rb",
|
165
|
+
"lib/win_gui/def_api.rb",
|
166
|
+
"lib/win_gui/string_extensions.rb",
|
167
|
+
"lib/win_gui/win_gui.rb",
|
168
|
+
"lib/win_gui/window.rb",
|
169
|
+
"old/windows_basics.rb",
|
170
|
+
"old/wnote.rb",
|
171
|
+
"old/wnote_spec.rb",
|
172
|
+
"spec/note/win/locknote_spec.rb",
|
173
|
+
"spec/spec.opts",
|
174
|
+
"spec/spec_helper.rb",
|
175
|
+
"spec/test_apps/locknote/LockNote.exe",
|
176
|
+
"spec/win_gui/def_api_spec.rb",
|
177
|
+
"spec/win_gui/string_extensions_spec.rb",
|
178
|
+
"spec/win_gui/win_gui_spec.rb",
|
179
|
+
"spec/win_gui/window_spec.rb",
|
180
|
+
"win_gui.gemspec"
|
181
|
+
]
|
182
|
+
s.homepage = %q{http://github.com/arvicco/win_gui}
|
183
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
184
|
+
s.require_paths = ["lib"]
|
185
|
+
s.rubygems_version = %q{1.3.5}
|
186
|
+
s.summary = %q{Rubyesque interfaces and wrappers for Win32 API GUI functions}
|
187
|
+
s.test_files = [
|
188
|
+
"spec/note/win/locknote_spec.rb",
|
189
|
+
"spec/spec_helper.rb",
|
190
|
+
"spec/win_gui/def_api_spec.rb",
|
191
|
+
"spec/win_gui/string_extensions_spec.rb",
|
192
|
+
"spec/win_gui/window_spec.rb",
|
193
|
+
"spec/win_gui/win_gui_spec.rb"
|
194
|
+
]
|
195
|
+
|
196
|
+
if s.respond_to? :specification_version then
|
197
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
198
|
+
s.specification_version = 3
|
199
|
+
|
200
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
201
|
+
s.add_runtime_dependency(%q<win32-api>, [">= 1.4.5"])
|
202
|
+
s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
|
203
|
+
s.add_development_dependency(%q<cucumber>, [">= 0"])
|
204
|
+
else
|
205
|
+
s.add_dependency(%q<win32-api>, [">= 1.4.5"])
|
206
|
+
s.add_dependency(%q<rspec>, [">= 1.2.9"])
|
207
|
+
s.add_dependency(%q<cucumber>, [">= 0"])
|
208
|
+
end
|
209
|
+
else
|
210
|
+
s.add_dependency(%q<win32-api>, [">= 1.4.5"])
|
211
|
+
s.add_dependency(%q<rspec>, [">= 1.2.9"])
|
212
|
+
s.add_dependency(%q<cucumber>, [">= 0"])
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: win_gui
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
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-01-
|
12
|
+
date: 2010-01-26 00:00:00 +03:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -185,14 +185,6 @@ files:
|
|
185
185
|
- book_code/with_rspec/locknote.rb
|
186
186
|
- book_code/with_rspec/note_spec.rb
|
187
187
|
- book_code/with_rspec/should_examples.rb
|
188
|
-
- exp/exp.rb
|
189
|
-
- exp/exp_encodings.rb
|
190
|
-
- exp/exp_enum_windows.rb
|
191
|
-
- exp/exp_quik.rb
|
192
|
-
- exp/exp_wsh.rb
|
193
|
-
- exp/old/windows_basics.rb
|
194
|
-
- exp/old/wnote.rb
|
195
|
-
- exp/old/wnote_spec.rb
|
196
188
|
- features/step_definitions/win_gui_steps.rb
|
197
189
|
- features/support/env.rb
|
198
190
|
- features/win_gui.feature
|
@@ -205,16 +197,22 @@ files:
|
|
205
197
|
- lib/note/win/locknote.rb
|
206
198
|
- lib/win_gui.rb
|
207
199
|
- lib/win_gui/constants.rb
|
200
|
+
- lib/win_gui/def_api.rb
|
208
201
|
- lib/win_gui/string_extensions.rb
|
209
202
|
- lib/win_gui/win_gui.rb
|
210
203
|
- lib/win_gui/window.rb
|
204
|
+
- old/windows_basics.rb
|
205
|
+
- old/wnote.rb
|
206
|
+
- old/wnote_spec.rb
|
211
207
|
- spec/note/win/locknote_spec.rb
|
212
208
|
- spec/spec.opts
|
213
209
|
- spec/spec_helper.rb
|
214
210
|
- spec/test_apps/locknote/LockNote.exe
|
211
|
+
- spec/win_gui/def_api_spec.rb
|
215
212
|
- spec/win_gui/string_extensions_spec.rb
|
216
213
|
- spec/win_gui/win_gui_spec.rb
|
217
214
|
- spec/win_gui/window_spec.rb
|
215
|
+
- win_gui.gemspec
|
218
216
|
has_rdoc: true
|
219
217
|
homepage: http://github.com/arvicco/win_gui
|
220
218
|
licenses: []
|
@@ -246,6 +244,7 @@ summary: Rubyesque interfaces and wrappers for Win32 API GUI functions
|
|
246
244
|
test_files:
|
247
245
|
- spec/note/win/locknote_spec.rb
|
248
246
|
- spec/spec_helper.rb
|
247
|
+
- spec/win_gui/def_api_spec.rb
|
249
248
|
- spec/win_gui/string_extensions_spec.rb
|
250
249
|
- spec/win_gui/window_spec.rb
|
251
250
|
- spec/win_gui/win_gui_spec.rb
|
data/exp/exp.rb
DELETED
data/exp/exp_encodings.rb
DELETED
@@ -1,40 +0,0 @@
|
|
1
|
-
# encoding: CP1251
|
2
|
-
Encoding.default_internal, Encoding.default_external = ['utf-8'] * 2
|
3
|
-
t = '��������� �����������!'
|
4
|
-
d = t.encode('CP866')
|
5
|
-
utf8 = t.encode('utf-8')
|
6
|
-
|
7
|
-
puts '��������� �����������!', t, utf8, "#{d} #{d.encoding}"
|
8
|
-
|
9
|
-
str = "\xE2\x80\x93"
|
10
|
-
puts "Str: #{str}, #{str.encoding}"
|
11
|
-
|
12
|
-
p "Source encoding: #{__ENCODING__}"
|
13
|
-
p "String encoding: #{t.encoding}"
|
14
|
-
p "Def ext encoding: #{Encoding.default_external}"
|
15
|
-
p "Def int encoding: #{Encoding.default_internal}"
|
16
|
-
|
17
|
-
puts
|
18
|
-
|
19
|
-
puts 'Playing with encodings: setting default to utf-8'
|
20
|
-
Encoding.default_internal, Encoding.default_external = ['utf-8'] * 2
|
21
|
-
p "Source encoding: #{__ENCODING__}"
|
22
|
-
p "Def ext encoding: #{Encoding.default_external}"
|
23
|
-
p "Def int encoding: #{Encoding.default_internal}"
|
24
|
-
zhopa ='Yes, ��� ����!!'
|
25
|
-
puts zhopa
|
26
|
-
p "String encoding: #{zhopa.encoding}"
|
27
|
-
puts zhopa.encode!('CP866', :undef => :replace)
|
28
|
-
p "String encoding: #{zhopa.encoding}"
|
29
|
-
|
30
|
-
puts
|
31
|
-
puts 'Playing with encodings: setting default to cp866'
|
32
|
-
Encoding.default_internal, Encoding.default_external = ['cp866'] * 2
|
33
|
-
p "Source encoding: #{__ENCODING__}"
|
34
|
-
p "Def ext encoding: #{Encoding.default_external}"
|
35
|
-
p "Def int encoding: #{Encoding.default_internal}"
|
36
|
-
zhopa ='Yes, ��� ����!!'
|
37
|
-
puts zhopa
|
38
|
-
p "String encoding: #{zhopa.encoding}"
|
39
|
-
puts zhopa.encode!('CP866', :undef => :replace)
|
40
|
-
p "String encoding: #{zhopa.encoding}"
|
data/exp/exp_enum_windows.rb
DELETED
@@ -1,60 +0,0 @@
|
|
1
|
-
#encoding: utf-8
|
2
|
-
|
3
|
-
|
4
|
-
# When using API functions returning ANSI strings (get_window_text), force_encoding('cp1251') and encode('cp866', :undef => :replace) to display correctly
|
5
|
-
# When using API functions returning "wide" Unicode strings (get_window_text_w), force_encoding('utf-16LE') and encode('cp866', :undef => :replace) to display correctly
|
6
|
-
|
7
|
-
libdir = File.join(File.dirname(__FILE__),"lib" )
|
8
|
-
$LOAD_PATH.unshift libdir unless $LOAD_PATH.include?(libdir)
|
9
|
-
require 'spec/spec_helper'
|
10
|
-
|
11
|
-
include WinGui
|
12
|
-
include GuiTest
|
13
|
-
|
14
|
-
@child_handles = []
|
15
|
-
app = launch_test_app
|
16
|
-
#keystroke(VK_ALT, 'F'.ord)
|
17
|
-
print_callback = lambda do |handle, message|
|
18
|
-
name = get_window_text(handle)
|
19
|
-
class_name = get_class_name(handle)
|
20
|
-
thread, process = get_window_thread_process_id(handle)
|
21
|
-
puts "#{message} #{process} #{thread} #{handle} #{class_name.rstrip} #{name.force_encoding('cp1251').encode('cp866', :undef => :replace).rstrip}"
|
22
|
-
@child_handles << handle if message == 'CHILD'
|
23
|
-
true
|
24
|
-
end
|
25
|
-
|
26
|
-
@windows = []
|
27
|
-
@num = 0
|
28
|
-
map_callback = lambda do |handle, message|
|
29
|
-
name = get_window_text_w(handle)
|
30
|
-
class_name = get_class_name(handle)
|
31
|
-
thread, process = get_window_thread_process_id(handle)
|
32
|
-
@windows << { :message => message, :process => process, :thread => thread, :handle => handle, :klass => class_name.rstrip,
|
33
|
-
:name => name.encode('cp866', :undef => :replace).rstrip}
|
34
|
-
@num +=1
|
35
|
-
true
|
36
|
-
end
|
37
|
-
|
38
|
-
#print_callback = callback('LP', 'I', &print_proc)
|
39
|
-
#map_callback = callback('LP', 'I', &map_proc)
|
40
|
-
|
41
|
-
puts "Top-level Windows:"
|
42
|
-
enum_windows 'TOP', &print_callback
|
43
|
-
|
44
|
-
puts
|
45
|
-
puts "Note Windows:"
|
46
|
-
print_callback[app.handle, 'NOTE']
|
47
|
-
enum_child_windows app.handle, 'CHILD', &print_callback
|
48
|
-
|
49
|
-
@child_handles.each do |handle|
|
50
|
-
enum_child_windows handle, 'CHILD', &print_callback
|
51
|
-
end
|
52
|
-
|
53
|
-
enum_windows 'TOP', &map_callback
|
54
|
-
enum_child_windows app.handle, 'CHILD', &map_callback
|
55
|
-
puts
|
56
|
-
puts "Sorted Windows:"
|
57
|
-
puts @windows.sort_by{|w| [w[:process], w[:thread], w[:handle]]}.map{|w|w.values.join(' ')}
|
58
|
-
puts "Total #{@num} Windows"
|
59
|
-
|
60
|
-
close_test_app
|
data/exp/exp_quik.rb
DELETED
@@ -1,38 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
libdir = File.join(File.dirname(__FILE__), "lib" )
|
3
|
-
$LOAD_PATH.unshift libdir unless $LOAD_PATH.include?(libdir)
|
4
|
-
require 'spec/spec_helper'
|
5
|
-
|
6
|
-
module Quik
|
7
|
-
include WinGui
|
8
|
-
extend WinGui
|
9
|
-
include GuiTest
|
10
|
-
|
11
|
-
QUIK_APP_PATH = ['C:\Program Files\Info', '\info.exe']
|
12
|
-
QUIK_APP_START = 'start "" "' + QUIK_APP_PATH.join + '"'
|
13
|
-
QUIK_MAIN_CLASS = 'InfoClass'
|
14
|
-
QUIK_DIALOG_CLASS = '#32770'
|
15
|
-
QUIK_DIALOG_TITLE = 'Идентификация пользователя'
|
16
|
-
system 'cd "' + QUIK_APP_PATH.first + '"'
|
17
|
-
system QUIK_APP_START
|
18
|
-
handle = 0
|
19
|
-
timeout(20) do
|
20
|
-
sleep TEST_SLEEP_DELAY until (handle = find_window(QUIK_MAIN_CLASS, nil))
|
21
|
-
end
|
22
|
-
p handle
|
23
|
-
quik = Window.new handle
|
24
|
-
sleep 1
|
25
|
-
p visible? quik.handle
|
26
|
-
# hide_window(quik.handle)
|
27
|
-
p window? quik.handle
|
28
|
-
p visible? quik.handle
|
29
|
-
p QUIK_DIALOG_TITLE#.force_encoding('CP1251')
|
30
|
-
p title = QUIK_DIALOG_TITLE.encode('CP1251')
|
31
|
-
dialog( title, 1) do |dlg|
|
32
|
-
child = dlg.child 'ComboLBox'
|
33
|
-
p 'Found!', child.handle
|
34
|
-
end
|
35
|
-
# quik.close
|
36
|
-
# quik.wait_for_close
|
37
|
-
|
38
|
-
end
|
data/exp/exp_wsh.rb
DELETED
@@ -1,115 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
require 'win32ole'
|
3
|
-
|
4
|
-
p WIN32OLE.codepage
|
5
|
-
|
6
|
-
def show ole, name = 'ole_obj'
|
7
|
-
puts " #{name} is: #{ole.ole_type.inspect}" if ole.respond_to? :ole_type
|
8
|
-
puts " #{name}'s Additonal methods:"
|
9
|
-
p (ole.methods - Object.methods).map(&:to_s).uniq.sort
|
10
|
-
if ole.respond_to? :ole_methods
|
11
|
-
puts " #{name}'s OLE methods:"
|
12
|
-
#p ole.ole_methods.map(&:to_s).uniq.sort
|
13
|
-
methods = ole.ole_methods.select{ |m| m.visible? }.sort{|a, b| a.to_s<=>b.to_s}
|
14
|
-
puts methods.map {|meth| signature_for meth }
|
15
|
-
end
|
16
|
-
puts
|
17
|
-
end
|
18
|
-
|
19
|
-
def signature_for meth
|
20
|
-
sig = "#{meth.return_type} "
|
21
|
-
sig += "#{meth.return_type_detail} " unless meth.return_type_detail.size == 1
|
22
|
-
sig += "#{meth.name}("
|
23
|
-
sig += meth.params.map {|param| param_for param}.join(", ") unless meth.params.empty?
|
24
|
-
sig += ")"
|
25
|
-
end
|
26
|
-
|
27
|
-
def param_for param
|
28
|
-
if param.default
|
29
|
-
"#{param.ole_type} #{param.name}=#{param.default}"
|
30
|
-
else
|
31
|
-
"#{param.ole_type} #{param.name}"
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
# Object WScript.Shell
|
36
|
-
show wsh = WIN32OLE.new('Wscript.Shell'), 'Wscript.Shell'
|
37
|
-
|
38
|
-
#wsh.Popup( 'message', 0, 'title', 1 ) # Pop-up, Doh
|
39
|
-
#puts wsh.CurrentDirectory()
|
40
|
-
show env = wsh.Environment, "wsh.Environment"
|
41
|
-
env.each {|env_item| puts " - #{env_item}"}
|
42
|
-
puts
|
43
|
-
|
44
|
-
# Echo?
|
45
|
-
#e = WIN32OLE.new('WScript.Echo "Hello World!"')
|
46
|
-
|
47
|
-
show shell = WIN32OLE.new('Shell.Application'), 'Shell.Application'
|
48
|
-
# Must be either IE or Windows Explorer
|
49
|
-
show windows = shell.Windows, 'shell.Windows'
|
50
|
-
|
51
|
-
puts "# of windows: #{windows.count.inspect}"
|
52
|
-
show windows.ole_method('GetTypeInfo'), "ole_method('GetTypeInfo')"
|
53
|
-
|
54
|
-
show expl = windows.Item(0), "windows.Item(0)"
|
55
|
-
|
56
|
-
# Playing with CD-ROM
|
57
|
-
show my_computer = shell.NameSpace(17), 'shell.NameSpace(17) - my computer'
|
58
|
-
|
59
|
-
show cdrom = my_computer.ParseName("D:\\"), 'ParseName("D:\\") - cdrom'
|
60
|
-
|
61
|
-
cdrom.Verbs.each do |verb|
|
62
|
-
show verb, verb.Name
|
63
|
-
#verb.doIt if verb.Name == "E&ject"
|
64
|
-
end
|
65
|
-
|
66
|
-
## Documenting Win32OLE
|
67
|
-
#my_com_object = WIN32OLE.new("Library.Class")
|
68
|
-
#
|
69
|
-
## Set my_com_object = GetObject("Library.Class")
|
70
|
-
#com_collection_object = WIN32OLE.connect("Library.Class")
|
71
|
-
#
|
72
|
-
## For Each com_object In com_collection_object
|
73
|
-
## '...
|
74
|
-
## Next
|
75
|
-
#for com_object in com_collection_object
|
76
|
-
# p com_object.ole_methods
|
77
|
-
##...
|
78
|
-
#end
|
79
|
-
|
80
|
-
exit 0
|
81
|
-
|
82
|
-
# Playing with Folder
|
83
|
-
time = Time.now.to_s
|
84
|
-
if wsh.AppActivate('Фолдор')
|
85
|
-
wsh.SendKeys("%FWFRB#{time}{ENTER}")
|
86
|
-
end
|
87
|
-
|
88
|
-
# Creating new Notepad window:
|
89
|
-
if not wsh.AppActivate('Notepad')
|
90
|
-
wsh.Run('Notepad')
|
91
|
-
sleep 1
|
92
|
-
end
|
93
|
-
|
94
|
-
# Playing with created Notepad window:
|
95
|
-
if wsh.AppActivate('Notepad')
|
96
|
-
sleep 1
|
97
|
-
p 'Inside'
|
98
|
-
# Enter text into Notepad:
|
99
|
-
wsh.SendKeys('Ruby{TAB}on{TAB}Windows{ENTER}')
|
100
|
-
wsh.SendKeys("#{time}")
|
101
|
-
# ALT-F to pull down File menu, then A to select Save As...:
|
102
|
-
wsh.SendKeys('%FA')
|
103
|
-
sleep 1
|
104
|
-
wsh.SendKeys('C:\dev\apps\filename.txt{ENTER}')
|
105
|
-
sleep 1
|
106
|
-
# If prompted to overwrite existing file:
|
107
|
-
|
108
|
-
if wsh.AppActivate('Save As')
|
109
|
-
sleep 1
|
110
|
-
# Enter 'Y':
|
111
|
-
wsh.SendKeys('Y')
|
112
|
-
end
|
113
|
-
# Quit Notepad with ALT-F4:
|
114
|
-
wsh.SendKeys('%{F4}')
|
115
|
-
end
|