win_gui 0.1.0 → 0.1.1
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 +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
|