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