au3 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/AutoItX3/au3.rb +291 -0
- data/lib/AutoItX3/control.rb +545 -0
- data/lib/AutoItX3/filedir.rb +99 -0
- data/lib/AutoItX3/graphic.rb +32 -0
- data/lib/AutoItX3/keyboard.rb +166 -0
- data/lib/AutoItX3/misc.rb +105 -0
- data/lib/AutoItX3/mouse.rb +130 -0
- data/lib/AutoItX3/process.rb +152 -0
- data/lib/AutoItX3/window.rb +411 -0
- data/lib/HISTORY.rdoc +19 -0
- data/lib/README.rdoc +71 -0
- data/lib/au3.rb +2 -0
- data/test/test_clipboard.rb +19 -0
- data/test/test_ini.rb +48 -0
- data/test/test_keyboard.rb +61 -0
- data/test/test_mouse.rb +43 -0
- data/test/test_process.rb +50 -0
- data/test/test_tray.rb +29 -0
- data/test/test_window.rb +104 -0
- metadata +101 -0
data/lib/AutoItX3/au3.rb
ADDED
@@ -0,0 +1,291 @@
|
|
1
|
+
#Encoding: UTF-8
|
2
|
+
#This file is part of au3.
|
3
|
+
#Copyright © 2009 Marvin Gülker
|
4
|
+
#
|
5
|
+
#au3 is published under the same terms as Ruby.
|
6
|
+
#See http://www.ruby-lang.org/en/LICENSE.txt
|
7
|
+
#
|
8
|
+
#===au3.rb
|
9
|
+
#This is au3's main file.
|
10
|
+
require "win32/api"
|
11
|
+
#(See the end of this file for more require statements)
|
12
|
+
|
13
|
+
#Added some methods to the build-in String class.
|
14
|
+
class String
|
15
|
+
|
16
|
+
#The AutoItX3 API requires wchar_t * (or LPCWSTR) typed strings instead of the usual char *.
|
17
|
+
#After some web research I found out that this type is a UTF-16 encoded string,
|
18
|
+
#that has to be terminated with a double NUL character; I tried to encode the
|
19
|
+
#string UTF-16BE, then UTF-16LE and added the extra NUL to it, and found out
|
20
|
+
#it worked. That's what this method does.
|
21
|
+
def wide
|
22
|
+
(self + "\0").encode("UTF-16LE")
|
23
|
+
end
|
24
|
+
alias to_wchar_t wide
|
25
|
+
|
26
|
+
#Self-modifying version of #wide.
|
27
|
+
def wide!
|
28
|
+
self << "\0"
|
29
|
+
encode!("UTF-16LE")
|
30
|
+
end
|
31
|
+
|
32
|
+
#The AutoItX3 API returns wchar_t * (or LPCSWSTR) typed strings instead of the usual char *.
|
33
|
+
#This method should only be used for strings that have been created by #wide or by the au3 API
|
34
|
+
#(which uses #wide internally). Keep in mind that this method removes unconvertable characters.
|
35
|
+
#
|
36
|
+
#Returns an +encoding+ encoded string that has been a wchar_t * (LPCWSTR) type.
|
37
|
+
def normal(encoding = "UTF-8")
|
38
|
+
encode(encoding, :invalid => :replace, :undef => :replace, :replace => "").gsub("\0", "").gsub("\r\n", "\n")
|
39
|
+
end
|
40
|
+
alias to_char normal
|
41
|
+
|
42
|
+
#Self-modifying version of #normal.
|
43
|
+
def normal!(encoding = "UTF-8")
|
44
|
+
encode!(encoding, :invalid => :replace, :undef => :replace, :replace => "")
|
45
|
+
gsub!("\0", "")
|
46
|
+
gsub!("\r\n", "\n")
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
#This module encapsulates all methods to interact with
|
52
|
+
#AutoItX3. Every method is documented, so you should't have
|
53
|
+
#problems with using them. However, a few notes:
|
54
|
+
#==Mouse Functions
|
55
|
+
#Many mouse functions take an argument called +button+. This can be one
|
56
|
+
#of the following strings:
|
57
|
+
# String | Normal result | Swapped buttons
|
58
|
+
# ====================+=================+================
|
59
|
+
# "" (empty string) | Left | Left
|
60
|
+
# --------------------+-----------------+----------------
|
61
|
+
# Left | Left | Left
|
62
|
+
# --------------------+-----------------+----------------
|
63
|
+
# Right | Right | Right
|
64
|
+
# --------------------+-----------------+----------------
|
65
|
+
# Middle | Middle | Middle
|
66
|
+
# --------------------+-----------------+----------------
|
67
|
+
# Primary | Left | Right
|
68
|
+
# --------------------+-----------------+----------------
|
69
|
+
# Secondary | Right | Left
|
70
|
+
# --------------------+-----------------+----------------
|
71
|
+
# Main | Left | Right
|
72
|
+
# --------------------+-----------------+----------------
|
73
|
+
# Menu | Right | Left
|
74
|
+
#==Process Functions
|
75
|
+
#The +pid+ parameter of many process functions
|
76
|
+
#needn't to be a process identification number, you can
|
77
|
+
#also pass in the name of the process. Please note, that
|
78
|
+
#in that case the first process with +pid+ in its name is
|
79
|
+
#assumed to be the correct one.
|
80
|
+
module AutoItX3
|
81
|
+
|
82
|
+
#The smallest value AutoIt can handle. Used for *some* parameter defaults.
|
83
|
+
INTDEFAULT = -2147483647
|
84
|
+
|
85
|
+
#The version of this au3 library.
|
86
|
+
VERSION = "0.1.0"
|
87
|
+
|
88
|
+
#This is the buffer size used for AutoItX3's text "returning" functions.
|
89
|
+
#It will be subtracted by 1 due to the trailing 0 of wchar_t * type strings.
|
90
|
+
BUFFER_SIZE = 100_000
|
91
|
+
|
92
|
+
#This is used to store the Win32::API objects.
|
93
|
+
@functions = {}
|
94
|
+
|
95
|
+
#This hash is used for the #set_option method.
|
96
|
+
@options = {
|
97
|
+
"CaretCoordMode" => 2,
|
98
|
+
"ColorMode" => 0,
|
99
|
+
"MouseClickDelay" => 10,
|
100
|
+
"MouseClickDownDelay" => 10,
|
101
|
+
"MouseClickDragDelay" => 250,
|
102
|
+
"MouseCoordMode" => 1,
|
103
|
+
"PixelCoordMode" => 1,
|
104
|
+
"SendAttachMode" => 0,
|
105
|
+
"SendCapslockMode" => 1,
|
106
|
+
"SendKeyDelay" => 5,
|
107
|
+
"SendKeyDownDelay" => 1,
|
108
|
+
"WinDetectHiddenText" => 0,
|
109
|
+
"WinSearchChildren" => 0,
|
110
|
+
"WinTextMatchMode" => 1,
|
111
|
+
"WinTitleMatchMode" => 1,
|
112
|
+
"WinWaitDelay" => 250
|
113
|
+
}
|
114
|
+
|
115
|
+
def self.functions
|
116
|
+
@functions
|
117
|
+
end
|
118
|
+
|
119
|
+
def self.functions=(val)
|
120
|
+
@functions = val
|
121
|
+
end
|
122
|
+
|
123
|
+
#This class is used for errors in this library.
|
124
|
+
class Au3Error < StandardError
|
125
|
+
end
|
126
|
+
|
127
|
+
#This subclass of Win32::API is only used internally to make it a bit easier
|
128
|
+
#to create bindings the functions of AutoItX3.
|
129
|
+
class AU3_Function < Win32::API
|
130
|
+
|
131
|
+
#Creates a new AU3_Function object. Takes the +name+, the +arguments+ and the +returnvalue+ of
|
132
|
+
#the function. +name+ will be prefixed by "AU3_" and the DLL is set to "AutoItX3.dll".
|
133
|
+
#If you ommit the returnvalue, it's assumed to be of void type ('V').
|
134
|
+
def initialize(name, arguments, returnvalue = 'V')
|
135
|
+
super("AU3_#{name}", arguments, returnvalue, "AutoItX3.dll")
|
136
|
+
end
|
137
|
+
|
138
|
+
end
|
139
|
+
|
140
|
+
class << self
|
141
|
+
|
142
|
+
#This hash is used for the #set_option method.
|
143
|
+
#Use the #set_option method to configure it.
|
144
|
+
attr_reader :options
|
145
|
+
|
146
|
+
#Returns the error code of the last called AutoItX3 function, which is 0 if
|
147
|
+
#everything worked fine.
|
148
|
+
def last_error
|
149
|
+
@functions[__method__] ||= AU3_Function.new("error", '', 'L')
|
150
|
+
@functions[__method__].call
|
151
|
+
end
|
152
|
+
|
153
|
+
#call-seq:
|
154
|
+
# set_option( option , value ) ==> anInteger
|
155
|
+
# set_option( option , value) {...} ==> anObject
|
156
|
+
# opt( option , value ) ==> anInteger
|
157
|
+
# opt( option , value ) {...} ==> anObject
|
158
|
+
#
|
159
|
+
#Sets an option that changes the behaviour of AutoIt. If you choose the block form, the
|
160
|
+
#option will be resetted after the block finished.
|
161
|
+
#The block form returns the last expression, the normal form the previously set option.
|
162
|
+
#
|
163
|
+
#The following options are possible (copied from the AutoItX3 help file):
|
164
|
+
# Option | Description
|
165
|
+
# ====================+============================================================
|
166
|
+
# CaretCoordMode | Sets the way coords are used in the caret functions,
|
167
|
+
# | either absolute coords or coords relative to the current
|
168
|
+
# | active window:
|
169
|
+
# | 0 = relative coords to the active window
|
170
|
+
# | 1 = absolute screen coordinates (default)
|
171
|
+
# | 2 = relative coords to the client area of the active window
|
172
|
+
# --------------------+------------------------------------------------------------
|
173
|
+
# ColorMode | Sets the way colors are defined, either RGB or BGR. RGB is
|
174
|
+
# | the default but in previous versions of AutoIt (pre 3.0.102)
|
175
|
+
# | BGR was the default:
|
176
|
+
# | 0 = Colors are defined as RGB (0xRRGGBB) (default)
|
177
|
+
# | 1 = Colors are defined as BGR (0xBBGGRR) (the mode used in
|
178
|
+
# | older versions of AutoIt)
|
179
|
+
# --------------------+------------------------------------------------------------
|
180
|
+
# MouseClickDelay | Alters the length of the brief pause in between mouse
|
181
|
+
# | clicks.
|
182
|
+
# | Time in milliseconds to pause (default=10).
|
183
|
+
# --------------------+------------------------------------------------------------
|
184
|
+
# MouseClickDownDelay | Alters the length a click is held down before release.
|
185
|
+
# | Time in milliseconds to pause (default=10).
|
186
|
+
# --------------------+------------------------------------------------------------
|
187
|
+
# MouseClickDragDelay | Alters the length of the brief pause at the start and
|
188
|
+
# | end of a mouse drag operation.
|
189
|
+
# | Time in milliseconds to pause (default=250).
|
190
|
+
# --------------------+------------------------------------------------------------
|
191
|
+
# MouseCoordMode | Sets the way coords are used in the mouse functions,
|
192
|
+
# | either absolute coords or coords relative to the current
|
193
|
+
# | active window:
|
194
|
+
# | 0 = relative coords to the active window
|
195
|
+
# | 1 = absolute screen coordinates (default)
|
196
|
+
# | 2 = relative coords to the client area of the active window
|
197
|
+
# --------------------+------------------------------------------------------------
|
198
|
+
# PixelCoordMode | Sets the way coords are used in the pixel functions,
|
199
|
+
# | either absolute coords or coords relative to the current
|
200
|
+
# | active window:
|
201
|
+
# | 0 = relative coords to the active window
|
202
|
+
# | 1 = absolute screen coordinates (default)
|
203
|
+
# | 2 = relative coords to the client area of the active window
|
204
|
+
# --------------------+------------------------------------------------------------
|
205
|
+
# SendAttachMode | Specifies if AutoIt attaches input threads when using then
|
206
|
+
# | Send() function. When not attaching (default mode=0)
|
207
|
+
# | detecting the state of capslock/scrolllock and numlock
|
208
|
+
# | can be unreliable under NT4. However, when you specify
|
209
|
+
# | attach mode=1 the Send("{... down/up}") syntax will not
|
210
|
+
# | work and there may be problems with sending keys to "hung"
|
211
|
+
# | windows. ControlSend() ALWAYS attaches and is not affected
|
212
|
+
# | by this mode.
|
213
|
+
# | 0 = don't attach (default)
|
214
|
+
# | 1 = attach
|
215
|
+
# --------------------+------------------------------------------------------------
|
216
|
+
# SendCapslockMode | Specifies if AutoIt should store the state of capslock
|
217
|
+
# | before a Send function and restore it afterwards.
|
218
|
+
# | 0 = don't store/restore
|
219
|
+
# | 1 = store and restore (default)
|
220
|
+
# --------------------+------------------------------------------------------------
|
221
|
+
# SendKeyDelay | Alters the the length of the brief pause in between
|
222
|
+
# | sent keystrokes.
|
223
|
+
# | Time in milliseconds to pause (default=5). Sometimes a
|
224
|
+
# | value of 0 does not work; use 1 instead.
|
225
|
+
# --------------------+------------------------------------------------------------
|
226
|
+
# SendKeyDownDelay | Alters the length of time a key is held down before
|
227
|
+
# | released during a keystroke. For applications that
|
228
|
+
# | take a while to register keypresses (and many games)
|
229
|
+
# | you may need to raise this value from the default.
|
230
|
+
# | Time in milliseconds to pause (default=1).
|
231
|
+
# --------------------+------------------------------------------------------------
|
232
|
+
# WinDetectHiddenText | Specifies if hidden window text can be "seen" by the
|
233
|
+
# | window matching functions.
|
234
|
+
# | 0 = Do not detect hidden text (default)
|
235
|
+
# | 1 = Detect hidden text
|
236
|
+
# --------------------+------------------------------------------------------------
|
237
|
+
# WinSearchChildren | Allows the window search routines to search child windows
|
238
|
+
# | as well as top-level windows.
|
239
|
+
# | 0 = Only search top-level windows (default)
|
240
|
+
# | 1 = Search top-level and child windows
|
241
|
+
# --------------------+------------------------------------------------------------
|
242
|
+
# WinTextMatchMode | Alters the method that is used to match window text
|
243
|
+
# | during search operations.
|
244
|
+
# | 1 = Complete / Slow mode (default)
|
245
|
+
# | 2 = Quick mode
|
246
|
+
# | In quick mode AutoIt can usually only "see" dialog text,
|
247
|
+
# | button text and the captions of some controls. In the
|
248
|
+
# | default mode much more text can be seen (for instance the
|
249
|
+
# | contents of the Notepad window).
|
250
|
+
# | If you are having performance problems when performing
|
251
|
+
# | many window searches then changing to the "quick" mode may
|
252
|
+
# | help.
|
253
|
+
# --------------------+------------------------------------------------------------
|
254
|
+
# WinTitleMatchMode | Alters the method that is used to match window titles
|
255
|
+
# | during search operations.
|
256
|
+
# | 1 = Match the title from the start (default)
|
257
|
+
# | 2 = Match any substring in the title
|
258
|
+
# | 3 = Exact title match
|
259
|
+
# | 4 = Advanced mode, see the AutoItX3 help.
|
260
|
+
# --------------------+------------------------------------------------------------
|
261
|
+
# WinWaitDelay | Alters how long a script should briefly pause after a
|
262
|
+
# | successful window-related operation.
|
263
|
+
# | Time in milliseconds to pause (default=250).
|
264
|
+
def set_option(option, value)
|
265
|
+
raise(ArgumentError, "Unknown option '#{option}'!") unless @options.include? option
|
266
|
+
@functions[__method__] ||= AU3_Function.new("AutoItSetOption", 'PL', 'L')
|
267
|
+
if block_given?
|
268
|
+
previous = @options[option]
|
269
|
+
@functions[__method__].call(option.to_wchar_t, value)
|
270
|
+
ret = yield
|
271
|
+
@functions[__method__].call(option.to_wchar_t, previous)
|
272
|
+
else
|
273
|
+
ret = @functions[__method__].call(option.to_wchar_t, value)
|
274
|
+
@options[option] = ret
|
275
|
+
end
|
276
|
+
ret
|
277
|
+
end
|
278
|
+
alias opt set_option
|
279
|
+
|
280
|
+
end
|
281
|
+
|
282
|
+
end #AutoItX3
|
283
|
+
|
284
|
+
require_relative("./misc.rb")
|
285
|
+
require_relative("./filedir.rb")
|
286
|
+
require_relative("./graphic.rb")
|
287
|
+
require_relative("./keyboard.rb")
|
288
|
+
require_relative("./mouse.rb")
|
289
|
+
require_relative("./process.rb")
|
290
|
+
require_relative("./window.rb")
|
291
|
+
require_relative("./control.rb")
|
@@ -0,0 +1,545 @@
|
|
1
|
+
#Encoding: UTF-8
|
2
|
+
|
3
|
+
module AutoItX3
|
4
|
+
|
5
|
+
#This is the superclass for all controls. If you don't find
|
6
|
+
#a subclass of Control that matches your specific control,
|
7
|
+
#you can use the Control class itself (and if you call
|
8
|
+
#Window#focused_control, you *will* have to use it,
|
9
|
+
#since that method retuns a Control and not a subclass).
|
10
|
+
class Control
|
11
|
+
|
12
|
+
@functions = {}
|
13
|
+
|
14
|
+
class << self
|
15
|
+
|
16
|
+
def functions
|
17
|
+
@functions
|
18
|
+
end
|
19
|
+
|
20
|
+
def functions=(hsh)
|
21
|
+
@functions = hsh
|
22
|
+
end
|
23
|
+
|
24
|
+
#Generates a control by using another control.
|
25
|
+
#This function is meant to be used with subclasses of Control, so you can do
|
26
|
+
#things like this:
|
27
|
+
# #...
|
28
|
+
# ctrl = window.focused_control #This returns a Control instance
|
29
|
+
# #If you're sure it's an Edit, transform it into one:
|
30
|
+
# ctrl = AutoItX3::Edit.from_control(ctrl)
|
31
|
+
# p ctrl.lines
|
32
|
+
def from_control(ctrl)
|
33
|
+
raise(ArgumentError, "Argument has to be a Control!") unless ctrl.kind_of? Control
|
34
|
+
new(ctrl.instance_eval{@title}, ctrl.instance_eval{@text}, ctrl.instance_eval{@c_id})
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
#Creates a new Control object. Pass in the title and text of
|
40
|
+
#the window holding the control (or "" if you don't want to specify one of them)
|
41
|
+
#and the ID of the control. Instead of the ID you may use the name of the
|
42
|
+
#control in combination width the occurence number of it, like "Edit1" and "Edit2".
|
43
|
+
def initialize(title, text, control_id)
|
44
|
+
@title = title
|
45
|
+
@text = text
|
46
|
+
@c_id = control_id.to_s
|
47
|
+
end
|
48
|
+
|
49
|
+
#Clicks +self+ with the given mouse +button+ (<tt>"Primary"</tt> by default)
|
50
|
+
#+click+ times (1 by default) at the given position (middle by default).
|
51
|
+
def click(button = "Primary", clicks = 1, x = INTDEFAULT, y = INTDEFAULT)
|
52
|
+
Control.functions[__method__] ||= AU3_Function.new("ControlClick", 'SSSSLLL', 'L')
|
53
|
+
res = Control.functions[__method__].call(@title.wide, @text.wide, @c_id.wide, button.wide, clicks, x, y)
|
54
|
+
if res == 0
|
55
|
+
raise(Au3Error, "Could not click control '#{@c_id}' in '#{@title}' for some reason!")
|
56
|
+
end
|
57
|
+
nil
|
58
|
+
end
|
59
|
+
|
60
|
+
#Disables ("grays out") +self+.
|
61
|
+
def disable
|
62
|
+
Control.functions[__method__] ||= AU3_Function.new("ControlDisable", 'SSS', 'L')
|
63
|
+
res = Control.functions[__method__].call(@title.wide, @text.wide, @c_id.wide)
|
64
|
+
if res == 0
|
65
|
+
raise(Au3Error, "Could not disable control '#{@c_id}' in '#{@title}'!")
|
66
|
+
end
|
67
|
+
nil
|
68
|
+
end
|
69
|
+
|
70
|
+
#Enables +self+ (i.e. make it accept user actions).
|
71
|
+
def enable
|
72
|
+
Control.functions[__method__] ||= AU3_Function.new("ControlEnable", 'SSS', 'L')
|
73
|
+
res = Control.functions[__method__].call(@title.wide, @text.wide, @c_id.wide)
|
74
|
+
if res == 0
|
75
|
+
raise(Au3Error, "Could not enable control '#{@c_id}' in '#{@title}'!")
|
76
|
+
end
|
77
|
+
nil
|
78
|
+
end
|
79
|
+
|
80
|
+
#Gives the input focus to +self+.
|
81
|
+
def focus
|
82
|
+
Control.functions[__method__] ||= AU3_Functino.new("ControlFocus", 'SSS', 'L')
|
83
|
+
res = Control.functions[__method__].call(@title.wide, @text.wide, @c_id.wide)
|
84
|
+
if res == 0
|
85
|
+
raise(Au3Error, "Could not focus control '#{@c_id}' in '#{@title}!")
|
86
|
+
end
|
87
|
+
nil
|
88
|
+
end
|
89
|
+
|
90
|
+
#Returns the internal window handle of +self+. It can be used in
|
91
|
+
#advanced window mode or directly in Win32 API calls (but you have
|
92
|
+
#to call #to_i on the string than).
|
93
|
+
def handle
|
94
|
+
Control.functions[__method__] ||= AU3_Function.new("ControlGetHandle", 'SSSPI')
|
95
|
+
buffer = " " * BUFFER_SIZE
|
96
|
+
buffer.wide!
|
97
|
+
Control.functions[__method__].call(@title.wide, @text.wide, @c_id.wide, buffer, BUFFER_SIZE - 1)
|
98
|
+
raise_unfound if AutoItX3.last_error == 1
|
99
|
+
buffer.normal.strip
|
100
|
+
end
|
101
|
+
|
102
|
+
#Returns a 4-element array containing the control's position and size.
|
103
|
+
#Form is: <tt>[ x , y , width , height ]</tt>.
|
104
|
+
def rect
|
105
|
+
Control.functions[:c_x] ||= AU3_Function.new("ControlGetPosX", 'SSS', 'L')
|
106
|
+
Control.functions[:c_y] ||= AU3_Function.new("ControlGetPosY", 'SSS', 'L')
|
107
|
+
Control.functions[:c_width] ||= AU3_Function.new("ControlGetPosWidth", 'SSS', 'L')
|
108
|
+
Control.functions[:c_height] ||= AU3_Function.new("ControlGetPosHeight", 'SSS', 'L')
|
109
|
+
|
110
|
+
params = [@title.wide, @text.wide, @c_id.wide]
|
111
|
+
rectangle = [
|
112
|
+
Control.functions[:c_x].call(*params),
|
113
|
+
Control.functions[:c_y].call(*params),
|
114
|
+
Control.functions[:c_width].call(*params),
|
115
|
+
Control.functions[:c_height].call(*params)
|
116
|
+
]
|
117
|
+
raise_unfound if AutoItX3.last_error == 1
|
118
|
+
rectangle
|
119
|
+
end
|
120
|
+
|
121
|
+
#Returns the +self+'s text.
|
122
|
+
def text
|
123
|
+
Control.functions[__method__] ||= AU3_Function.new("ControlGetText", 'SSSPI')
|
124
|
+
buffer = " " * BUFFER_SIZE
|
125
|
+
buffer.wide!
|
126
|
+
Control.functions[__method__].call(@title.wide, @text.wide, @c_id.wide, buffer, BUFFER_SIZE - 1)
|
127
|
+
raise_unfound if AutoItX3.last_error == 1
|
128
|
+
buffer.normal.strip
|
129
|
+
end
|
130
|
+
|
131
|
+
#Hides +self+.
|
132
|
+
def hide
|
133
|
+
Control.functions[__method__] ||= AU3_Function.new("ControlHide", 'SSS', 'L')
|
134
|
+
res = Control.functions[__method__].call(@title.wide, @text.wide, @c_id.wide)
|
135
|
+
raise_unfound if res == 0
|
136
|
+
nil
|
137
|
+
end
|
138
|
+
|
139
|
+
#Moves a control and optionally resizes it.
|
140
|
+
def move(x, y, width = -1, height = -1)
|
141
|
+
Control.functions[__method__] ||= AU3_Function.new("ControlMove", 'SSSLLLL', 'L')
|
142
|
+
res = Control.functions[__method__].call(@title.wide, @text.wide, @c_id.wide, x, y, width, height)
|
143
|
+
raise_unfound if res == 0
|
144
|
+
nil
|
145
|
+
end
|
146
|
+
|
147
|
+
#Simulates user input to a control. This works normally even on
|
148
|
+
#hidden and inactive windows. Please note that this method cannot
|
149
|
+
#send every keystroke AutoItX3.send_keys can, notably [ALT] combinations.
|
150
|
+
def send_keys(str, flag = 0)
|
151
|
+
Control.functions[__method__] ||= AU3_Function.new("ControlSend", 'SSSSI', 'L')
|
152
|
+
res = Control.functions[__method__].call(@title.wide, @text.wide, @c_id.wide, str.wide, flag)
|
153
|
+
raise_unfound if res == 0
|
154
|
+
nil
|
155
|
+
end
|
156
|
+
|
157
|
+
#Sets the text of a control directly.
|
158
|
+
def text=(text)
|
159
|
+
Control.functions[__method__] ||= AU3_Function.new("ControlSetText", 'SSSS', 'L')
|
160
|
+
res = Control.functions[__method__].call(@title.wide, @text.wide, @c_id.wide, text.wide)
|
161
|
+
raise_unfound if res == 0
|
162
|
+
text
|
163
|
+
end
|
164
|
+
|
165
|
+
#Shows a hidden control.
|
166
|
+
def show
|
167
|
+
Control.functions[__method__] ||= AU3_Function.new("ControlShow", 'SSS', 'L')
|
168
|
+
res = Control.functions[__method__].call(@title.wide, @text.wide, @c_id.wide)
|
169
|
+
raise_unfound if res == 0
|
170
|
+
nil
|
171
|
+
end
|
172
|
+
|
173
|
+
#Sends a command to a control. You won't need to use this method, since all commands
|
174
|
+
#are wrapped into methods. It's only used internally.
|
175
|
+
def send_command_to_control(command, arg = "")
|
176
|
+
Control.functions[__method__] ||= AU3_Function.new("ControlCommand", 'SSSSSPI')
|
177
|
+
buffer = " " * BUFFER_SIZE
|
178
|
+
buffer.wide!
|
179
|
+
Control.functions[__method__].call(@title.wide, @text.wide, @c_id.wide, command.wide, arg.to_s.wide, buffer, BUFFER_SIZE - 1)
|
180
|
+
raise_unfound if AutoItX3.last_error == 1
|
181
|
+
buffer.normal.strip
|
182
|
+
end
|
183
|
+
|
184
|
+
#Returns wheather or not a control is visible.
|
185
|
+
def visible?
|
186
|
+
send_command_to_control("IsVisible") == 1
|
187
|
+
end
|
188
|
+
|
189
|
+
#Returns true if a control can interact with the user (i.e. it's not "grayed out").
|
190
|
+
def enabled?
|
191
|
+
send_command_to_control("IsEnabled") == 1
|
192
|
+
end
|
193
|
+
|
194
|
+
private
|
195
|
+
|
196
|
+
def raise_unfound
|
197
|
+
raise(Au3Error, "The control '#{@c_id}' was not found in the window '#{@title}' (or the window was not found)!", caller)
|
198
|
+
end
|
199
|
+
|
200
|
+
end
|
201
|
+
|
202
|
+
#List boxes are controls in which you can select one
|
203
|
+
#or multiple items by clicking on it. ListBox is also
|
204
|
+
#the superclass of ComboBox.
|
205
|
+
class ListBox < Control
|
206
|
+
|
207
|
+
#call-seq:
|
208
|
+
# AutoItX3::ListBox#add( item ) ==> item
|
209
|
+
# AutoItX3::ListBox#<< item ==> self
|
210
|
+
#
|
211
|
+
#Adds an entry to an existing combo or list box.
|
212
|
+
#If you use the << form, you can do a chain call like:
|
213
|
+
# ctrl << "a" << "b" << "c"
|
214
|
+
def add_item(string)
|
215
|
+
send_command_to_control("AddString", string)
|
216
|
+
string
|
217
|
+
end
|
218
|
+
|
219
|
+
def <<(string) # :nodoc:
|
220
|
+
add_item(string)
|
221
|
+
self
|
222
|
+
end
|
223
|
+
|
224
|
+
#Delete item +no+.
|
225
|
+
def delete(item_number)
|
226
|
+
send_command_to_control("DelString", item.to_s).to_i
|
227
|
+
end
|
228
|
+
|
229
|
+
#Finds the item number of +item+ in +self+.
|
230
|
+
def find(item)
|
231
|
+
send_command_to_control("FindString", item).to_i
|
232
|
+
end
|
233
|
+
|
234
|
+
#Sets the current selection of a combo box to item +num+.
|
235
|
+
#The index is zero-based. Raises an Au3Error if +num+ is out
|
236
|
+
#of range.
|
237
|
+
def current_selection=(num)
|
238
|
+
send_command_to_control("SetCurrentSelection", num.to_i)
|
239
|
+
num
|
240
|
+
end
|
241
|
+
|
242
|
+
#Sets +self+'s selection to the first occurence of +str+.
|
243
|
+
#Raises an Au3Error if +str+ cannot be found.
|
244
|
+
def select_string(str)
|
245
|
+
send_command_to_control("SelectString", str)
|
246
|
+
string
|
247
|
+
end
|
248
|
+
|
249
|
+
#Returns the currently selected string.
|
250
|
+
def current_selection
|
251
|
+
send_command_to_control("GetCurrentSelection")
|
252
|
+
end
|
253
|
+
|
254
|
+
end
|
255
|
+
|
256
|
+
#A combo box is a control on which you click
|
257
|
+
#and then select a single item from the droped
|
258
|
+
#list box.
|
259
|
+
class ComboBox < ListBox
|
260
|
+
|
261
|
+
#Drops down a combo box.
|
262
|
+
def drop
|
263
|
+
send_command_to_control("ShowDropDown")
|
264
|
+
end
|
265
|
+
|
266
|
+
#call-seq:
|
267
|
+
# undrop
|
268
|
+
# close
|
269
|
+
#
|
270
|
+
#Undrops or closes a combo box.
|
271
|
+
def undrop
|
272
|
+
send_command_to_control("HideDropDown")
|
273
|
+
end
|
274
|
+
alias close undrop
|
275
|
+
|
276
|
+
end
|
277
|
+
|
278
|
+
#A button is a control on which you can click and than something happens.
|
279
|
+
#Even if that's quite correct, that isn't all: check and radio boxes
|
280
|
+
#are handled by Windows as buttons, so they fall into the scope of this class.
|
281
|
+
class Button < Control
|
282
|
+
|
283
|
+
#Returns wheather +self+ is checked or not.
|
284
|
+
#Only useful for radio and check buttons.
|
285
|
+
def checked?
|
286
|
+
send_command_to_control("IsChecked") == 1
|
287
|
+
end
|
288
|
+
|
289
|
+
#Checks +self+ if it's a radio or check button.
|
290
|
+
def check
|
291
|
+
send_command_to_control("Check")
|
292
|
+
end
|
293
|
+
|
294
|
+
#Unchecks +self+ if it's a radio or check button.
|
295
|
+
def uncheck
|
296
|
+
send_command_to_control("UnCheck")
|
297
|
+
end
|
298
|
+
|
299
|
+
end
|
300
|
+
|
301
|
+
#An edit control is a single- or multiline input control in which you can
|
302
|
+
#type text. For example, notepad consists mainly of a big edit control.
|
303
|
+
class Edit < Control
|
304
|
+
|
305
|
+
#Returns the current caret position in a 2-element array
|
306
|
+
#of form <tt>[line, column]</tt>.
|
307
|
+
def caret_pos
|
308
|
+
x = send_command_to_control("GetCurrentLine").to_i
|
309
|
+
y = send_command_to_control("GetCurrentCol").to_i
|
310
|
+
[x, y]
|
311
|
+
end
|
312
|
+
|
313
|
+
#Returns the number of lines in +self+.
|
314
|
+
def lines
|
315
|
+
send_command_to_control("GetLineCount").to_i
|
316
|
+
end
|
317
|
+
|
318
|
+
#Returns the currently selected text.
|
319
|
+
def selected_text
|
320
|
+
send_command_to_control("GetSelected")
|
321
|
+
end
|
322
|
+
|
323
|
+
#"Pastes" +str+ at +self+'s current caret position.
|
324
|
+
def paste(str)
|
325
|
+
send_command_to_control("EditPaste", str)
|
326
|
+
end
|
327
|
+
|
328
|
+
end
|
329
|
+
|
330
|
+
#A tab book or tab bar is a control that shows up most often
|
331
|
+
#at the top of a window and lets you choice between different
|
332
|
+
#contents within the same window.
|
333
|
+
class TabBook < Control
|
334
|
+
|
335
|
+
#Returns the currently shown tab.
|
336
|
+
def current
|
337
|
+
send_command_to_control("CurrentTab").to_i
|
338
|
+
end
|
339
|
+
|
340
|
+
#Shows the tab right to the current one and returns the number
|
341
|
+
#of the now shown tab.
|
342
|
+
def right
|
343
|
+
send_command_to_control("TabRight")
|
344
|
+
current
|
345
|
+
end
|
346
|
+
|
347
|
+
#Shows the tab left to the current one and returns the number
|
348
|
+
#of the now shown tab.
|
349
|
+
def left
|
350
|
+
send_command_to_control("TabLeft")
|
351
|
+
current
|
352
|
+
end
|
353
|
+
|
354
|
+
end
|
355
|
+
|
356
|
+
#A list view is a list which can contain many different
|
357
|
+
#columns of data.
|
358
|
+
class ListView < Control
|
359
|
+
|
360
|
+
#Ordinary list view
|
361
|
+
LIST = "list"
|
362
|
+
#Detailed view
|
363
|
+
DETAILS = "details"
|
364
|
+
#View with small icons
|
365
|
+
SMALL_ICONS = "smallicons"
|
366
|
+
#View with large icons
|
367
|
+
LARGE_ICONS = "largeicons"
|
368
|
+
|
369
|
+
#Sends +cmd+ to +self+. This method is only used internally.
|
370
|
+
def send_command_to_list_view(command, arg1 = "", arg2 = "")
|
371
|
+
Control.functions[__method__] ||= AU3_Function.new("ControlListView", 'SSSSSSPI')
|
372
|
+
buffer = " " * BUFFER_SIZE
|
373
|
+
buffer.wide!
|
374
|
+
Control.functions[__method__].call(@title.wide, @text.wide, @c_id.wide, command.wide, arg1.to_s.wide, arg2.to_s.wide, buffer, BUFFER_SIZE - 1)
|
375
|
+
raise(Au3Error, "Unknown error occured when sending '#{command}' to '#{@c_id}' in '#{@title}'! Maybe an invalid window?") if AutoItX3.last_error == 1
|
376
|
+
buffer.normal.strip
|
377
|
+
end
|
378
|
+
|
379
|
+
#Deselects the given item(s).
|
380
|
+
def deselect(from, to = "")
|
381
|
+
send_command_to_list_view("DeSelect", from, to)
|
382
|
+
end
|
383
|
+
|
384
|
+
#Searches for +string+ and +sub_item+ in +self+ and returns the index
|
385
|
+
#of the found list item or false if it isn't found.
|
386
|
+
def find(string, sub_item = "")
|
387
|
+
res = send_command_to_list_view("FindItem", string, sub_item).to_i
|
388
|
+
if res == -1
|
389
|
+
false
|
390
|
+
else
|
391
|
+
res
|
392
|
+
end
|
393
|
+
end
|
394
|
+
|
395
|
+
#call-seq:
|
396
|
+
# item_count ==> anInteger
|
397
|
+
# size ==> anInteger
|
398
|
+
# length ==> anInteger
|
399
|
+
#
|
400
|
+
#Returns the number of items in +self+.
|
401
|
+
def item_count
|
402
|
+
send_command_to_list_view("GetItemCount").to_i
|
403
|
+
end
|
404
|
+
alias size item_count
|
405
|
+
alias length item_count
|
406
|
+
|
407
|
+
#Returns the inices of the selected items in an array which is empty if
|
408
|
+
#none is selected.
|
409
|
+
def selected
|
410
|
+
send_command_to_list_view("GetSelected", 1).split("|")
|
411
|
+
end
|
412
|
+
|
413
|
+
#Returns the number of selected items.
|
414
|
+
def num_selected
|
415
|
+
send_command_to_list_view("GetSelectedCount").to_i
|
416
|
+
end
|
417
|
+
|
418
|
+
#Returns the number of subitems in +self+.
|
419
|
+
def num_subitems
|
420
|
+
send_command_to_list_view("GetSubItemCount").to_i
|
421
|
+
end
|
422
|
+
|
423
|
+
#call-seq:
|
424
|
+
# AutoItX3::ListView#text_at( item [, subitem ] ) ==> aString
|
425
|
+
# AutoItX3::ListView#[ item [, subitem ] ] ==> aString
|
426
|
+
#
|
427
|
+
#Returns the text at the given position.
|
428
|
+
def text_at(item, subitem = "")
|
429
|
+
send_command_to_list_view("GetText", item, subitem)
|
430
|
+
end
|
431
|
+
alias [] text_at
|
432
|
+
|
433
|
+
#Returns wheather or not +item+ is selected.
|
434
|
+
def selected?(item)
|
435
|
+
send_command_to_list_view("IsSelected", item).to_i == 1
|
436
|
+
end
|
437
|
+
|
438
|
+
#Selects the given item(s).
|
439
|
+
def select(from, to = "")
|
440
|
+
send_command_to_list_view("Select", from, to)
|
441
|
+
end
|
442
|
+
|
443
|
+
#Selects all items in +self+.
|
444
|
+
def select_all
|
445
|
+
send_command_to_list_view("SelectAll")
|
446
|
+
end
|
447
|
+
|
448
|
+
# AutoItX3::ListView#clear_selection ==> nil
|
449
|
+
# AutoItX3::ListView#select_none ==> nil
|
450
|
+
#
|
451
|
+
#Clears the selection.
|
452
|
+
def clear_selection
|
453
|
+
send_command_to_list_view("SelectClear")
|
454
|
+
end
|
455
|
+
alias select_none clear_selection
|
456
|
+
|
457
|
+
#Inverts the selection.
|
458
|
+
def invert_selection
|
459
|
+
send_command_to_list_view("SelectInvert")
|
460
|
+
end
|
461
|
+
|
462
|
+
#Changes the view of +self+. Possible values of +view+ are
|
463
|
+
#all constants of the ListView class.
|
464
|
+
def change_view(view)
|
465
|
+
send_command_to_list_view("ViewChange", view)
|
466
|
+
end
|
467
|
+
|
468
|
+
end
|
469
|
+
|
470
|
+
#A TreeView is a control that shows a kind of expandable
|
471
|
+
#list, like the one displayed ont the left side in <tt>.chm</tt> files.
|
472
|
+
class TreeView < Control
|
473
|
+
|
474
|
+
#Sends +cmd+ to +self+. This method is only used internally.
|
475
|
+
def send_command_to_tree_view(command, arg1 = "", arg2 = "")
|
476
|
+
Control.functions[__method__] ||= AU3_Function.new("ControlTreeView", 'SSSSSSPI')
|
477
|
+
buffer = " " * BUFFER_SIZE
|
478
|
+
buffer.wide!
|
479
|
+
Control.functions[__method__].call(@title.wide, @text.wide, @c_id.wide, command.wide, arg1.wide, arg2.wide, buffer, BUFFER_SIZE - 1)
|
480
|
+
raise(Au3Error, "Unknown error occured when sending '#{command}' to '#{@c_id}' in '#{@title}'! Maybe an invalid window?") if AutoItX3.last_error == 1
|
481
|
+
buffer.normal.strip
|
482
|
+
end
|
483
|
+
|
484
|
+
#Checks +item+ if it supports that operation.
|
485
|
+
def check(item)
|
486
|
+
send_command_to_tree_view("Check", item)
|
487
|
+
end
|
488
|
+
|
489
|
+
#Collapses +item+ to hide its children.
|
490
|
+
def collapse(item)
|
491
|
+
send_command_to_tree_view("Collapse", item)
|
492
|
+
end
|
493
|
+
|
494
|
+
#Return wheather or not +item+ exists.
|
495
|
+
def exists?(item)
|
496
|
+
send_command_to_tree_view("Exists", item).to_i == 1
|
497
|
+
end
|
498
|
+
|
499
|
+
#Expands +item+ to show its children.
|
500
|
+
def expand(item)
|
501
|
+
send_command_to_tree_view("Expand", item)
|
502
|
+
end
|
503
|
+
|
504
|
+
#Returns the number of children of +item+.
|
505
|
+
def num_subitems(item)
|
506
|
+
send_command_to_tree_view("GetItemCount", item).to_i
|
507
|
+
end
|
508
|
+
|
509
|
+
#Returns the text reference or the index reference (if +use_index+ is true) of
|
510
|
+
#the selected item.
|
511
|
+
def selected(use_index = false)
|
512
|
+
result = send_command_to_tree_view("GetSelected", use_index ? 1 : 0)
|
513
|
+
return result.to_i if use_index
|
514
|
+
result
|
515
|
+
end
|
516
|
+
|
517
|
+
#call-seq:
|
518
|
+
# text_at( item ) ==> aString
|
519
|
+
# [ item ] ==> aString
|
520
|
+
#
|
521
|
+
#Returns the text of +item+.
|
522
|
+
def text_at(item)
|
523
|
+
send_command_to_tree_view("GetText", item)
|
524
|
+
end
|
525
|
+
alias [] text_at
|
526
|
+
|
527
|
+
#Returns wheather or not +item+ is checked. Raises an Au3Error
|
528
|
+
#if +item+ is not a checkbox.
|
529
|
+
def checked?(item)
|
530
|
+
send_command_to_tree_view("IsChecked", item).to_i == 1
|
531
|
+
end
|
532
|
+
|
533
|
+
#Selects +item+.
|
534
|
+
def select(item)
|
535
|
+
send_command_to_tree_view("Select", item)
|
536
|
+
end
|
537
|
+
|
538
|
+
#Unchecks +item+ if it suports that operation (i.e. it's a checkbox).
|
539
|
+
def uncheck(item)
|
540
|
+
send_command_to_tree_view("Uncheck", item)
|
541
|
+
end
|
542
|
+
|
543
|
+
end
|
544
|
+
|
545
|
+
end
|