win_gui 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +7 -7
- data/VERSION +1 -1
- data/lib/win_gui/constants.rb +16 -11
- data/lib/win_gui/def_api.rb +38 -2
- data/lib/win_gui/win_gui.rb +130 -120
- data/spec/win_gui/def_api_spec.rb +38 -7
- data/spec/win_gui/win_gui_spec.rb +0 -5
- data/win_gui.gemspec +1 -1
- metadata +1 -1
data/README.rdoc
CHANGED
@@ -37,10 +37,15 @@ Contributors always welcome!
|
|
37
37
|
require 'win_gui'
|
38
38
|
include WinGui
|
39
39
|
|
40
|
-
More examples will follow
|
40
|
+
More examples will follow when the code is closer to production quality...
|
41
|
+
|
42
|
+
== CREDITS:
|
43
|
+
|
44
|
+
This library started as an extension of ideas and code described in excellent book
|
45
|
+
"Scripted GUI Testing with Ruby" by Ian Dees.
|
41
46
|
|
42
47
|
== Note on Patches/Pull Requests
|
43
|
-
|
48
|
+
|
44
49
|
* Fork the project.
|
45
50
|
* Make your feature addition or bug fix.
|
46
51
|
* Add tests for it. This is important so I don't break it in a
|
@@ -49,11 +54,6 @@ More examples will follow as the code will be closer to production quality...
|
|
49
54
|
(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)
|
50
55
|
* Send me a pull request. Bonus points for topic branches.
|
51
56
|
|
52
|
-
== CREDITS:
|
53
|
-
|
54
|
-
This library started as an extension of ideas and code described in excellent book
|
55
|
-
"Scripted GUI Testing with Ruby" by Ian Dees.
|
56
|
-
|
57
57
|
== LICENSE:
|
58
58
|
|
59
59
|
Copyright (c) 2009 Arvicco. See LICENSE for details
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.2
|
data/lib/win_gui/constants.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module WinGui
|
2
2
|
|
3
3
|
# WinGui Module internal Constants:
|
4
|
-
|
4
|
+
|
5
5
|
WG_KEY_DELAY = 0.00001
|
6
6
|
WG_SLEEP_DELAY = 0.001
|
7
7
|
WG_CLOSE_TIMEOUT = 1
|
@@ -9,19 +9,20 @@ module WinGui
|
|
9
9
|
|
10
10
|
# Windows keyboard-related Constants:
|
11
11
|
# Virtual key codes:
|
12
|
+
|
12
13
|
VK_CANCEL = 0x03 # Control-break processing
|
13
14
|
VK_BACK = 0x08
|
14
15
|
VK_TAB = 0x09
|
15
16
|
VK_SHIFT = 0x10
|
16
17
|
VK_CONTROL = 0x11
|
17
|
-
VK_RETURN = 0x0D
|
18
|
-
VK_ALT = 0x12
|
19
|
-
VK_MENU = 0x12
|
20
|
-
VK_PAUSE = 0x13
|
21
|
-
VK_CAPITAL = 0x14
|
22
|
-
VK_ESCAPE = 0x1B
|
23
|
-
VK_SPACE = 0x20
|
24
|
-
VK_PRIOR = 0x21
|
18
|
+
VK_RETURN = 0x0D # ENTER key
|
19
|
+
VK_ALT = 0x12 # ALT key
|
20
|
+
VK_MENU = 0x12 # ALT key alias
|
21
|
+
VK_PAUSE = 0x13 # PAUSE key
|
22
|
+
VK_CAPITAL = 0x14 # CAPS LOCK key
|
23
|
+
VK_ESCAPE = 0x1B # ESC key
|
24
|
+
VK_SPACE = 0x20 # SPACEBAR
|
25
|
+
VK_PRIOR = 0x21 # PAGE UP key
|
25
26
|
VK_NEXT = 0x22 # PAGE DOWN key
|
26
27
|
VK_END = 0x23 # END key
|
27
28
|
VK_HOME = 0x24 # HOME key
|
@@ -36,11 +37,14 @@ module WinGui
|
|
36
37
|
VK_INSERT = 0x2D # INS key
|
37
38
|
VK_DELETE = 0x2E # DEL key
|
38
39
|
VK_HELP = 0x2F # HELP key
|
40
|
+
|
39
41
|
# Key events:
|
40
|
-
|
42
|
+
|
43
|
+
KEYEVENTF_KEYDOWN = 0
|
41
44
|
KEYEVENTF_KEYUP = 2
|
42
45
|
|
43
|
-
#
|
46
|
+
# Show Window Commands:
|
47
|
+
|
44
48
|
SW_HIDE = 0
|
45
49
|
SW_NORMAL = 1
|
46
50
|
SW_SHOWNORMAL = 1
|
@@ -57,6 +61,7 @@ module WinGui
|
|
57
61
|
SW_FORCEMINIMIZE = 11
|
58
62
|
|
59
63
|
# Windows Messages Constants:
|
64
|
+
|
60
65
|
WM_GETTEXT = 0x000D
|
61
66
|
WM_SYSCOMMAND = 0x0112
|
62
67
|
SC_CLOSE = 0xF060
|
data/lib/win_gui/def_api.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
module WinGui
|
2
2
|
module DefApi
|
3
|
+
DEFAULT_DLL = 'user32'
|
4
|
+
|
3
5
|
# Defines new instance method wrapper for Windows API function call. Converts CamelCase function name
|
4
6
|
# into snake_case method name, renames test functions according to Ruby convention (IsWindow -> window?)
|
5
7
|
# When the defined wrapper method is called, it executes underlying API function call, yields the result
|
@@ -10,6 +12,7 @@ module WinGui
|
|
10
12
|
# and (optional) runtime block to &define_block that should define method content and return result.
|
11
13
|
#
|
12
14
|
# Accepts following options:
|
15
|
+
# :dll:: Use this dll instead of default 'user32'
|
13
16
|
# :rename:: Use this name instead of standard (conventional) function name
|
14
17
|
# :alias(es):: Provides additional alias(es) for defined method
|
15
18
|
# :boolean:: Forces method to return true/false instead of nonzero/zero
|
@@ -25,9 +28,9 @@ module WinGui
|
|
25
28
|
zeronil = options[:zeronil]
|
26
29
|
aliases = ([options[:alias]] + [options[:aliases]]).flatten.compact
|
27
30
|
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] ||
|
31
|
+
api = Win32::API.new(function, proto.upcase, returns.upcase, options[:dll] || DEFAULT_DLL)
|
29
32
|
|
30
|
-
define_method(name) do |*args, &runtime_block|
|
33
|
+
define_method(name) do |*args, &runtime_block|
|
31
34
|
return api if args == [:api]
|
32
35
|
return define_block.call(api, *args, &runtime_block) if define_block
|
33
36
|
raise 'Invalid args count' unless args.size == params.size
|
@@ -51,5 +54,38 @@ module WinGui
|
|
51
54
|
def buffer(size = 1024, code = "\x00")
|
52
55
|
code * size
|
53
56
|
end
|
57
|
+
|
58
|
+
# Procedure that returns (possibly encoded) string as a result of api function call
|
59
|
+
def return_string( encode = nil )
|
60
|
+
lambda do |api, *args|
|
61
|
+
raise 'Invalid args count' unless args.size == api.prototype.size-2
|
62
|
+
args += [string = buffer, string.length]
|
63
|
+
num_chars = api.call(*args) # num_chars not used
|
64
|
+
string = string.force_encoding('utf-16LE').encode(encode) if encode
|
65
|
+
string.rstrip
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# Procedure that calls api function expecting a callback. If runtime block is given
|
70
|
+
# it is converted into callback, otherwise procedure returns an array of all handles
|
71
|
+
# pushed into callback by api enumeration
|
72
|
+
def return_enum
|
73
|
+
lambda do |api, *args, &block|
|
74
|
+
raise 'Invalid args count' unless args.size == api.prototype.size-1
|
75
|
+
handles = []
|
76
|
+
cb = if block
|
77
|
+
callback('LP', 'I', &block)
|
78
|
+
else
|
79
|
+
callback('LP', 'I') do |handle, message|
|
80
|
+
handles << handle
|
81
|
+
true
|
82
|
+
end
|
83
|
+
end
|
84
|
+
args[api.prototype.find_index('K'), 0] = cb # Insert callback into appropriate place of args Array
|
85
|
+
api.call *args
|
86
|
+
handles
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
54
90
|
end
|
55
91
|
end
|
data/lib/win_gui/win_gui.rb
CHANGED
@@ -13,108 +13,98 @@ require 'window'
|
|
13
13
|
|
14
14
|
module WinGui
|
15
15
|
self.extend DefApi
|
16
|
-
|
17
|
-
return_string_proc = lambda do |api, *args|
|
18
|
-
raise 'Invalid args count' unless args.size == api.prototype.size-2
|
19
|
-
args += [string = buffer, string.length]
|
20
|
-
num_chars = api.call(*args) # num_chars not used
|
21
|
-
string.rstrip
|
22
|
-
end
|
23
|
-
|
24
|
-
return_utf_string_proc = lambda do |api, *args|
|
25
|
-
raise 'Invalid args count' unless args.size == api.prototype.size-2
|
26
|
-
args += [string = buffer, string.length]
|
27
|
-
num_chars = api.call(*args) # num_chars not used
|
28
|
-
string.force_encoding('utf-16LE').encode('utf-8').rstrip
|
29
|
-
end
|
30
|
-
|
31
|
-
return_enum_proc = Proc.new do |api, *args, &block|
|
32
|
-
raise 'Invalid args count' unless args.size == api.prototype.size-1
|
33
|
-
handles = []
|
34
|
-
cb = if block
|
35
|
-
callback('LP', 'I', &block)
|
36
|
-
else
|
37
|
-
callback('LP', 'I') do |handle, message|
|
38
|
-
handles << handle
|
39
|
-
true
|
40
|
-
end
|
41
|
-
end
|
42
|
-
api.call *(args.size == 1 ? [cb, args.first] : [args.first, cb, args.last])
|
43
|
-
handles
|
44
|
-
end
|
45
16
|
|
46
17
|
# Windows GUI API definitions:
|
47
18
|
|
48
19
|
# Tests whether the specified window handle identifies an existing window.
|
49
|
-
# A thread should not use IsWindow for a window that it did not create because the window
|
50
|
-
# function was called. Further, because window handles are
|
20
|
+
# A thread should not use IsWindow for a window that it did not create because the window
|
21
|
+
# could be destroyed after this function was called. Further, because window handles are
|
22
|
+
# recycled the handle could even point to a different window.
|
23
|
+
#
|
51
24
|
def_api 'IsWindow', 'L', 'L'
|
52
25
|
|
53
|
-
# Tests if the specified window, its parent window, its parent's parent window, and so forth,
|
54
|
-
# Because the return value specifies whether the window has the
|
55
|
-
|
56
|
-
|
26
|
+
# Tests if the specified window, its parent window, its parent's parent window, and so forth,
|
27
|
+
# have the WS_VISIBLE style. Because the return value specifies whether the window has the
|
28
|
+
# WS_VISIBLE style, it may be true even if the window is totally obscured by other windows.
|
29
|
+
#
|
30
|
+
def_api 'IsWindowVisible', 'L', 'L', :alias => :visible?
|
57
31
|
|
58
|
-
def_api 'IsZoomed', 'L', 'L'
|
59
|
-
alias maximized? zoomed?
|
60
32
|
# Tests whether the specified window is maximized.
|
33
|
+
#
|
34
|
+
def_api 'IsZoomed', 'L', 'L', :alias => :maximized?
|
61
35
|
|
62
|
-
def_api 'IsIconic', 'L', 'L', :alias => :minimized?
|
63
36
|
# Tests whether the specified window is maximized.
|
37
|
+
#
|
38
|
+
def_api 'IsIconic', 'L', 'L', :alias => :minimized?
|
64
39
|
|
40
|
+
# Tests whether a window is a child (or descendant) window of a specified parent window.
|
41
|
+
# A child window is the direct descendant of a specified parent window if that parent window
|
42
|
+
# is in the chain of parent windows; the chain of parent windows leads from the original overlapped
|
43
|
+
# or pop-up window to the child window.
|
44
|
+
#
|
65
45
|
def_api 'IsChild', 'LL', 'L'
|
66
|
-
# Tests whether a window is a child (or descendant) window of a specified parent window. A child window is the direct descendant
|
67
|
-
# of a specified parent window if that parent window is in the chain of parent windows; the chain of parent windows leads from
|
68
|
-
# the original overlapped or pop-up window to the child window.
|
69
46
|
|
70
|
-
|
71
|
-
# Retrieves a handle to the top-level window whose class name and window name match the specified strings.
|
47
|
+
# Retrieves a handle to the top-level window whose class and window name match the specified strings.
|
72
48
|
# This function does not search child windows. This function does not perform a case-sensitive search.
|
73
|
-
# class_name (P) - String that specifies (window) class name
|
74
|
-
# The atom must be in the low-order word of class_name;
|
75
|
-
# The class name can be any name registered with RegisterClass(Ex),
|
76
|
-
# If this parameter is nil, it finds any window whose
|
77
|
-
#
|
49
|
+
# class_name (P) - String that specifies (window) class name OR class atom created by a previous
|
50
|
+
# call to the RegisterClass(Ex) function. The atom must be in the low-order word of class_name;
|
51
|
+
# the high-order word must be zero. The class name can be any name registered with RegisterClass(Ex),
|
52
|
+
# or any of the predefined control-class names. If this parameter is nil, it finds any window whose
|
53
|
+
# title matches the win_title parameter.
|
54
|
+
# win_name (P) - String that specifies the window name (title). If nil, all names match.
|
78
55
|
# returns (L) found window handle or NIL if nothing found
|
56
|
+
#
|
57
|
+
def_api 'FindWindow', 'PP', 'L', :zeronil => true
|
79
58
|
|
80
|
-
def_api 'FindWindowW', 'PP', 'L', :zeronil => true
|
81
59
|
# Unicode version of find_window (strings must be encoded as utf-16LE AND terminate with "\x00\x00")
|
60
|
+
#
|
61
|
+
def_api 'FindWindowW', 'PP', 'L', :zeronil => true
|
82
62
|
|
83
|
-
|
84
|
-
#
|
85
|
-
#
|
63
|
+
# Retrieves a handle to a CHILD window whose class name and window name match the specified strings.
|
64
|
+
# The function searches child windows, beginning with the one following the specified child window.
|
65
|
+
# This function does NOT perform a case-sensitive search.
|
86
66
|
# parent (L) - Handle to the parent window whose child windows are to be searched.
|
87
67
|
# If nil, the function uses the desktop window as the parent window.
|
88
68
|
# The function searches among windows that are child windows of the desktop.
|
89
|
-
# after_child (L) - Handle to a child window.
|
69
|
+
# after_child (L) - Handle to a child window. Search begins with the NEXT child window in the Z order.
|
90
70
|
# The child window must be a direct child window of parent, not just a descendant window.
|
91
71
|
# If after_child is nil, the search begins with the first child window of parent.
|
92
|
-
# win_class (P), win_title (P) - Strings that specify window class and name(title). If
|
72
|
+
# win_class (P), win_title (P) - Strings that specify window class and name(title). If nil, anything matches.
|
93
73
|
# Returns (L) - found child window (control) handle or NIL if nothing found
|
74
|
+
#
|
75
|
+
def_api 'FindWindowEx', 'LLPP', 'L', :zeronil => true
|
94
76
|
|
95
|
-
|
96
|
-
#
|
97
|
-
#
|
98
|
-
# API improved to require only win_handle and return rstripped
|
77
|
+
# Returns the text of the specified window's title bar (if it has one). If the specified window is
|
78
|
+
# a control, the text of the control is copied. However, GetWindowText cannot retrieve the text of
|
79
|
+
# a control in another application.
|
80
|
+
# API improved to require only win_handle and return rstripped text
|
99
81
|
# win_handle (L) - Handle to the window and, indirectly, the class to which the window belongs.
|
100
|
-
# buffer (P) - Pointer to the buffer that will receive the text. If the string is as long or longer
|
101
|
-
# the string is truncated and terminated with a NULL character.
|
102
|
-
# count (L) Specifies the maximum number of characters to copy to the buffer, including the NULL character.
|
82
|
+
# buffer (P) - Pointer to the buffer that will receive the text. If the string is as long or longer
|
83
|
+
# than the buffer, the string is truncated and terminated with a NULL character.
|
84
|
+
# count (L) Specifies the maximum number of characters to copy to the buffer, including the NULL character.
|
85
|
+
# If the text exceeds this limit, it is truncated.
|
103
86
|
# Returns (L) length, in characters, of the copied string, not including the terminating NULL character.
|
104
|
-
# If the window has no title bar or text, if the title bar is empty, or if the window or control handle
|
87
|
+
# If the window has no title bar or text, if the title bar is empty, or if the window or control handle
|
88
|
+
# is invalid, the return value is zero.
|
105
89
|
# To get extended error information, call GetLastError.
|
90
|
+
#
|
106
91
|
# Remarks: This function CANNOT retrieve the text of an edit control in ANOTHER app.
|
107
|
-
# If the target window is owned by the current process, GetWindowText causes a WM_GETTEXT message to
|
108
|
-
# If the target window is owned by another process and has
|
109
|
-
#
|
110
|
-
#
|
111
|
-
#
|
92
|
+
# If the target window is owned by the current process, GetWindowText causes a WM_GETTEXT message to
|
93
|
+
# be sent to the specified window or control. If the target window is owned by another process and has
|
94
|
+
# a caption, GetWindowText retrieves the window caption text. If the window does not have a caption,
|
95
|
+
# the return value is a null string. This allows to call GetWindowText without becoming unresponsive
|
96
|
+
# if the target window owner process is not responding. However, if the unresponsive target window
|
97
|
+
# belongs to the calling app, GetWindowText will cause the calling app to become unresponsive.
|
98
|
+
# To retrieve the text of a control in another process, send a WM_GETTEXT message directly instead
|
99
|
+
# of calling GetWindowText.
|
100
|
+
#
|
101
|
+
def_api 'GetWindowText', 'LPI', 'L', &return_string
|
112
102
|
|
113
|
-
def_api 'GetWindowTextW', 'LPI', 'L', &return_utf_string_proc
|
114
103
|
# Unicode version of get_window_text (returns rstripped utf-8 string)
|
115
104
|
# API improved to require only win_handle and return rstripped string
|
105
|
+
#
|
106
|
+
def_api 'GetWindowTextW', 'LPI', 'L', &return_string('utf-8')
|
116
107
|
|
117
|
-
def_api 'GetClassName', 'LPI', 'I', &return_string_proc
|
118
108
|
# Retrieves the name of the class to which the specified window belongs.
|
119
109
|
# API improved to require only win_handle and return rstripped string
|
120
110
|
# win_handle (L) - Handle to the window and, indirectly, the class to which the window belongs.
|
@@ -123,56 +113,72 @@ module WinGui
|
|
123
113
|
# The class name string is truncated if it is longer than the buffer and is always null-terminated.
|
124
114
|
# Returns (I) - number of TCHAR copied to the specified buffer, if the function succeeds.
|
125
115
|
# Returns zero if function fails. To get extended error information, call GetLastError.
|
116
|
+
#
|
117
|
+
def_api 'GetClassName', 'LPI', 'I', &return_string
|
126
118
|
|
127
|
-
def_api 'GetClassNameW', 'LPI', 'I', &return_utf_string_proc
|
128
119
|
# Unicode version of get_class_name (returns rstripped utf-8 string)
|
129
120
|
# API improved to require only win_handle and return rstripped string
|
121
|
+
#
|
122
|
+
def_api 'GetClassNameW', 'LPI', 'I', &return_string('utf-8')
|
130
123
|
|
124
|
+
# Retrieves the identifier of the thread that created the specified window and, optionally, the identifier
|
125
|
+
# of the process that created the window.
|
126
|
+
# API improved to accept window handle as a single arg and return a pair of [thread, process] ids
|
127
|
+
# handle (L) - Handle to the window.
|
128
|
+
# process (P) - A POINTER to a (Long) variable that receives the process identifier.
|
129
|
+
# Returns (L) - Identifier of the thread that created the window.
|
130
|
+
#
|
131
131
|
def_api 'GetWindowThreadProcessId', 'LP', 'L' do |api, *args|
|
132
|
-
# Retrieves the identifier of the thread that created the specified window and, optionally, the identifier of the process that created the window.
|
133
|
-
# API improved to accept window handle as a single arg and return a pair of [thread, process] ids
|
134
|
-
# handle (L) - Handle to the window.
|
135
|
-
# process (P) - A POINTER to a (Long) variable that receives the process identifier. If it is nil, nothing happens.
|
136
|
-
# Otherwise, GetWindowThreadProcessId copies the identifier of the process to the variable.
|
137
|
-
# Returns (L) - Identifier of the thread that created the window.
|
138
132
|
raise 'Invalid args count' unless args.size == api.prototype.size-1
|
139
133
|
thread = api.call(args.first, process = [1].pack('L'))
|
140
134
|
[thread] + process.unpack('L')
|
141
135
|
end
|
142
136
|
|
143
|
-
|
137
|
+
# Shows and hides windows.
|
144
138
|
# handle (L) - Handle to the window.
|
145
|
-
# cmd (I) - Specifies how the window is to be shown. This parameter is ignored the first time an
|
146
|
-
# if the program that launched the application provides a STARTUPINFO
|
147
|
-
#
|
148
|
-
#
|
149
|
-
#
|
150
|
-
#
|
151
|
-
#
|
152
|
-
#
|
153
|
-
#
|
154
|
-
#
|
155
|
-
#
|
156
|
-
#
|
157
|
-
#
|
158
|
-
#
|
159
|
-
#
|
160
|
-
#
|
161
|
-
#
|
162
|
-
#
|
163
|
-
#
|
164
|
-
#
|
139
|
+
# cmd (I) - Specifies how the window is to be shown. This parameter is ignored the first time an
|
140
|
+
# application calls ShowWindow, if the program that launched the application provides a STARTUPINFO
|
141
|
+
# structure. Otherwise, the first time ShowWindow is called, the value should be the value obtained
|
142
|
+
# by the WinMain function in its nCmdShow parameter. In subsequent calls, cmd may be:
|
143
|
+
# SW_HIDE - Hides the window and activates another window.
|
144
|
+
# SW_MAXIMIZE - Maximizes the specified window.
|
145
|
+
# SW_MINIMIZE - Minimizes the specified window, activates the next top-level window in the Z order.
|
146
|
+
# SW_SHOW - Activates the window and displays it in its current size and position.
|
147
|
+
# SW_SHOWMAXIMIZED - Activates the window and displays it as a maximized window.
|
148
|
+
# SW_SHOWMINIMIZED - Activates the window and displays it as a minimized window.
|
149
|
+
# SW_SHOWMINNOACTIVE Displays the window as a minimized window. This value is similar to
|
150
|
+
# SW_SHOWMINIMIZED, except the window is not activated.
|
151
|
+
# SW_SHOWNA - Displays the window in its current size and position. This value is similar to
|
152
|
+
# SW_SHOW, except the window is not activated.
|
153
|
+
# SW_SHOWNOACTIVATE- Displays a window in its most recent size and position. This value is similar to
|
154
|
+
# SW_SHOWNORMAL, except the window is not actived.
|
155
|
+
# SW_SHOWNORMAL - Activates and displays a window. If the window is minimized or maximized,
|
156
|
+
# the system restores it to its original size and position. An application should
|
157
|
+
# specify this flag when displaying the window for the first time.
|
158
|
+
# SW_RESTORE - Activates and displays the window. If the window is minimized or maximized,
|
159
|
+
# the system restores it to its original size and position. An application should
|
160
|
+
# specify this flag when restoring a minimized window.
|
161
|
+
# SW_SHOWDEFAULT - Sets the show state based on the SW_ value specified in the STARTUPINFO structure
|
162
|
+
# passed to the CreateProcess function by the program that started the application.
|
163
|
+
# SW_FORCEMINIMIZE - Windows 2000/XP: Minimizes a window, even if the thread that owns the window
|
164
|
+
# is not responding. Only use this flag when minimizing windows from a different thread.
|
165
165
|
# Returns (I) - True if the window was PREVIOUSLY visible, otherwise false
|
166
|
+
#
|
167
|
+
def_api 'ShowWindow', 'LI', 'I', :boolean => true
|
168
|
+
|
166
169
|
def hide_window(handle)
|
167
170
|
show_window(handle, SW_HIDE)
|
168
171
|
end
|
169
172
|
|
173
|
+
# Retrieves the dimensions of the specified window bounding rectangle. Dimensions are given relative
|
174
|
+
# to the upper-left corner of the screen.
|
175
|
+
# API improved to accept only window handle and return 4-member dimensions array (left, top, right, bottom)
|
176
|
+
# handle (L) - Handle to the window, rectangle - pointer to 4-long array for coordinates
|
177
|
+
#
|
178
|
+
# Remarks: As a convention for the RECT structure, the bottom-right coordinates of the returned rectangle
|
179
|
+
# are exclusive. In other words, the pixel at (right, bottom) lies immediately outside the rectangle.
|
180
|
+
#
|
170
181
|
def_api 'GetWindowRect', 'LP', 'I' do |api, *args|
|
171
|
-
# Retrieves the dimensions of the specified window bounding rectangle. Dimensions are given relative to the upper-left corner of the screen.
|
172
|
-
# API improved to accept only window handle and return 4-member dimensions array (left, top, right, bottom)
|
173
|
-
# handle (L) - Handle to the window, rectangle - pointer to 4-long array for coordinates
|
174
|
-
# Remarks: In conformance with conventions for the RECT structure, the bottom-right coordinates of the returned rectangle are exclusive.
|
175
|
-
# In other words, the pixel at (right, bottom) lies immediately outside the rectangle.
|
176
182
|
raise 'Invalid args count' unless args.size == api.prototype.size-1
|
177
183
|
rectangle = [0, 0, 0, 0].pack 'L*'
|
178
184
|
api.call args.first, rectangle
|
@@ -183,31 +189,35 @@ module WinGui
|
|
183
189
|
def_api 'PostMessage', 'LLLL', 'L'
|
184
190
|
def_api 'SendMessage', 'LLLP', 'L'
|
185
191
|
def_api 'GetDlgItem', 'LL', 'L'
|
186
|
-
|
187
|
-
# The EnumWindows function enumerates all top-level windows on the screen by passing the handle to
|
188
|
-
# in turn, to an application-defined callback function. EnumWindows continues until
|
189
|
-
# enumerated or the callback function returns FALSE.
|
192
|
+
|
193
|
+
# The EnumWindows function enumerates all top-level windows on the screen by passing the handle to
|
194
|
+
# each window, in turn, to an application-defined callback function. EnumWindows continues until
|
195
|
+
# the last top-level window is enumerated or the callback function returns FALSE.
|
190
196
|
# API improved to accept blocks (instead of callback objects) and message as a single arg
|
191
|
-
# callback [K] - Pointer to an application-defined callback function
|
197
|
+
# callback [K] - Pointer to an application-defined callback function (see EnumWindowsProc).
|
192
198
|
# message [P] - Specifies an application-defined value(message) to be passed to the callback function.
|
193
|
-
# Returns: Nonzero if the function succeeds, zero if the function fails
|
194
|
-
# If callback returns zero, the return value is also zero. In this case, the callback function should
|
195
|
-
# SetLastError to obtain a meaningful error code to be returned to the caller of EnumWindows.
|
196
|
-
#
|
197
|
-
#
|
198
|
-
#
|
199
|
-
#
|
200
|
-
|
201
|
-
|
199
|
+
# Returns: Nonzero if the function succeeds, zero if the function fails (GetLastError for more error info).
|
200
|
+
# If callback returns zero, the return value is also zero. In this case, the callback function should
|
201
|
+
# call SetLastError to obtain a meaningful error code to be returned to the caller of EnumWindows.
|
202
|
+
#
|
203
|
+
# Remarks: The EnumWindows function does not enumerate child windows, with the exception of a few top-level
|
204
|
+
# windows owned by the system that have the WS_CHILD style. This function is more reliable than calling
|
205
|
+
# the GetWindow function in a loop. An application that calls GetWindow to perform this task risks being
|
206
|
+
# caught in an infinite loop or referencing a handle to a window that has been destroyed.
|
207
|
+
#
|
208
|
+
def_api 'EnumWindows', 'KP', 'L', &return_enum
|
209
|
+
|
210
|
+
# Enumerates child windows to a given window.
|
202
211
|
# parent (L) - Handle to the parent window whose child windows are to be enumerated.
|
203
212
|
# If it is nil, this function is equivalent to EnumWindows. Windows 95/98/Me: parent cannot be NULL.
|
204
|
-
# API improved to accept blocks (instead of callback objects) and two args: parent handle and message
|
205
|
-
# callback (K) - Pointer to an application-defined callback function
|
206
|
-
# message (P) - Specifies an application-defined value to be passed to the callback function.
|
207
|
-
# Returns (
|
213
|
+
# API improved to accept blocks (instead of callback objects) and two args: parent handle and message.
|
214
|
+
# callback (K) - Pointer to an application-defined callback function (see EnumChildProc).
|
215
|
+
# message (P) - Specifies an application-defined value(message) to be passed to the callback function.
|
216
|
+
# Returns (L) - Not used (?!)
|
208
217
|
# If a child window has created child windows of its own, EnumChildWindows enumerates those windows as well.
|
209
218
|
# A child window that is moved or repositioned in the Z order during the enumeration process will be properly enumerated.
|
210
219
|
# The function does not enumerate a child window that is destroyed before being enumerated or that is created during the enumeration process.
|
220
|
+
def_api 'EnumChildWindows', 'LKP', 'L', &return_enum
|
211
221
|
|
212
222
|
def_api 'GetForegroundWindow', 'V', 'L'
|
213
223
|
def_api 'GetActiveWindow', 'V', 'L'
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), "..", "spec_helper" )
|
2
2
|
|
3
|
-
module GuiTest
|
3
|
+
module GuiTest
|
4
4
|
|
5
5
|
# def enum_callback
|
6
6
|
# @enum_callback ||= WinGui.callback('LP', 'I'){|handle, message| true }
|
@@ -36,6 +36,15 @@ module GuiTest
|
|
36
36
|
expect { find_window_w(nil, nil) }.to_not raise_error 'Invalid args count'
|
37
37
|
end
|
38
38
|
|
39
|
+
it 'overrides standard dll name with :dll option' do
|
40
|
+
|
41
|
+
WinGui.def_api 'GetComputerName', ['P', 'P'], 'I', :dll=> 'kernel32'
|
42
|
+
sys_name = `echo %COMPUTERNAME%`.strip
|
43
|
+
name = " " * 128
|
44
|
+
get_computer_name(name, "128")
|
45
|
+
name.unpack("A*").first.should == sys_name
|
46
|
+
end
|
47
|
+
|
39
48
|
it 'overrides standard name for defined method with :rename option' do
|
40
49
|
WinGui.def_api 'FindWindowW', 'PP', 'L', :rename=> 'my_own_find'
|
41
50
|
expect {find_window_w(nil, nil)}.to raise_error
|
@@ -155,6 +164,26 @@ module GuiTest
|
|
155
164
|
end
|
156
165
|
end
|
157
166
|
|
167
|
+
context 'using DLL other than default user32 with :dll option' do
|
168
|
+
before(:each) do
|
169
|
+
hide_method :get_computer_name # hide original method if it is defined
|
170
|
+
WinGui.def_api 'GetComputerName', ['P', 'P'], 'I', :dll=> 'kernel32'
|
171
|
+
end
|
172
|
+
after(:each) { restore_method :get_computer_name } # restore original method if it was hidden
|
173
|
+
|
174
|
+
it 'defines new instance method with appropriate name' do
|
175
|
+
respond_to?(:get_computer_name).should be_true
|
176
|
+
end
|
177
|
+
|
178
|
+
it 'returns expected result' do
|
179
|
+
WinGui.def_api 'GetComputerName', ['P', 'P'], 'I', :dll=> 'kernel32'
|
180
|
+
hostname = `hostname`.strip.upcase
|
181
|
+
name = " " * 128
|
182
|
+
get_computer_name(name, "128")
|
183
|
+
name.unpack("A*").first.should == hostname
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
158
187
|
context 'trying to define an invalid API function' do
|
159
188
|
it 'raises error when trying to define function with a wrong function name' do
|
160
189
|
expect { WinGui.def_api 'FindWindowImpossible', 'PP', 'L' }.
|
@@ -162,7 +191,7 @@ module GuiTest
|
|
162
191
|
end
|
163
192
|
end
|
164
193
|
|
165
|
-
context 'defining API function using definition
|
194
|
+
context 'defining API function using definition block' do
|
166
195
|
|
167
196
|
it 'defines new instance method' do
|
168
197
|
WinGui.def_api( 'FindWindowW', 'PP', 'L' ){|api, *args|}
|
@@ -188,7 +217,7 @@ module GuiTest
|
|
188
217
|
end
|
189
218
|
find_window_w(1, 2, 3)
|
190
219
|
@args.should == [1, 2, 3]
|
191
|
-
@api.function_name.should == 'FindWindowW' # The name of the function passed to the
|
220
|
+
@api.function_name.should == 'FindWindowW' # The name of the api function passed to the block
|
192
221
|
end
|
193
222
|
|
194
223
|
it ':rename option overrides standard name for defined method' do
|
@@ -230,12 +259,14 @@ module GuiTest
|
|
230
259
|
|
231
260
|
it 'created callback object can be used as a valid arg of API function expecting callback' do
|
232
261
|
WinGui.def_api 'EnumWindows', 'KP', 'L'
|
233
|
-
@
|
234
|
-
expect { enum_windows(@
|
262
|
+
@callback = WinGui.callback('LP', 'I'){|handle, message| true }
|
263
|
+
expect { enum_windows(@callback, 'Message') }.to_not raise_error
|
235
264
|
end
|
236
265
|
|
237
|
-
it 'defined API functions expecting callback
|
238
|
-
pending ' API is not exactly clear atm (
|
266
|
+
it 'defined API functions expecting callback convert given block into callback' do
|
267
|
+
pending ' What about prototype!? API is not exactly clear atm (.with_callback method?)'
|
268
|
+
WinGui.def_api 'EnumWindows', 'KP', 'L'
|
269
|
+
expect { enum_windows('Message'){|handle, message| true } }.to_not raise_error
|
239
270
|
end
|
240
271
|
end
|
241
272
|
end
|
@@ -4,9 +4,6 @@ module GuiTest
|
|
4
4
|
describe WinGui, ' contains a set of pre-defined GUI functions' do
|
5
5
|
describe '#window?' do
|
6
6
|
spec{ use{ window?(handle = 0) }}
|
7
|
-
# Tests whether the specified window handle identifies an existing window.
|
8
|
-
# A thread should not use IsWindow for a window that it did not create because the window could be destroyed after this
|
9
|
-
# function was called. Further, because window handles are recycled the handle could even point to a different window.
|
10
7
|
|
11
8
|
it 'returns true if window exists' do
|
12
9
|
test_app do |app|
|
@@ -28,8 +25,6 @@ module GuiTest
|
|
28
25
|
describe '#window_visible?' do
|
29
26
|
spec{ use{ window_visible?(handle = any_handle) }}
|
30
27
|
spec{ use{ visible?(handle = any_handle) }}
|
31
|
-
# Tests if the specified window, its parent window, its parent's parent window, and so forth, have the WS_VISIBLE style.
|
32
|
-
# 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.
|
33
28
|
|
34
29
|
it 'returns true if window is visible' do
|
35
30
|
test_app do |app|
|
data/win_gui.gemspec
CHANGED