win 0.0.6 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -15,19 +15,19 @@ This is still work in progress, only a small portion of Windows API wrapped so f
15
15
  == SUMMARY
16
16
 
17
17
  So you want to write a simple program that makes some Windows API function calls.
18
- You searched MSDN high and low and you now know exactly what functions you need.
19
- All you want is just putting those function calls into your Ruby code without too
20
- much pain. You'd love this to be more or less natural extension of your Ruby code,
21
- preferably not turning your code base into an ugly spaghetty of CamelCase calls,
22
- String/Array pack/unpack gymnastics, buffer/pointer allocations, extracting return
23
- values from [in/out] parameters and checking return codes for 0.
18
+ You searched MSDN high and low and you know exactly what functions you need.
19
+ You just want to put these function calls into your Ruby code without too much pain.
20
+ You'd love this to be more or less natural extension of your Ruby code, preferably
21
+ not turning your code base into an ugly spaghetty of CamelCase calls, String/Array
22
+ pack/unpack gymnastics, buffer/pointer allocations, extracting return values
23
+ from [in/out] parameters and checking return codes for 0.
24
24
 
25
25
  You have several options at this point. You can use 'win32-api' or 'ffi' libraries
26
26
  to connect your ruby code to Windows API and manually define wrapper methods for
27
27
  needed function calls. This is definitely a valid approach, even if it is a bit
28
- low-level one: you'll have to handle (somewhat) gory details of callback announcement,
29
- argument preparation, mimicking pointers with Strings or declaring pointers explicitly
30
- with FFI and other stuff (like manually defining about a gazillion obscure Windows
28
+ low-level one: you'll have to handle (somewhat) gory details of callback announcements,
29
+ argument preparation, mimicking pointers with Strings, declaring pointers explicitly
30
+ with FFI and other stuff (like manually assigning about a gazillion obscure Windows
31
31
  constants). As an example, consider the amount of code needed to complete a task as
32
32
  simple as getting unicode title text for the window that you already have handle for
33
33
  (using win32-api):
@@ -68,7 +68,7 @@ It helps you to cut some of the declaration slack though:
68
68
  buffer.force_encoding('utf-16LE').encode('utf-8').rstrip
69
69
  end
70
70
 
71
- But still it seems like TOO MUCH code for something that should (ideally) look like this:
71
+ But still, it seems like TOO MUCH code for something that should (ideally) look like this:
72
72
 
73
73
  title = window_text_w(window_handle)
74
74
 
@@ -78,8 +78,8 @@ natural inside Ruby code. Following the principle of least surprise, we define w
78
78
  * Require minimum arguments with sensible defaults
79
79
  * Return appropriate values explicitly (several return values if necessary)
80
80
  * Have sensible returns (false/true instead of 0/nonzero for test functions, nil if find function fails, etc)
81
- * Accept blocks where callback is expected
82
- * Are partitioned into related namespaces, so that you can load only the modules you need
81
+ * Accept blocks where callback is needed, provide default callback if no block given
82
+ * Are partitioned into appropriate namespaces, so that you can load only the modules you really need
83
83
 
84
84
  Well, we even keep a backup solution for those diehard Win32 API longtimers who would rather
85
85
  allocate their buffer strings by hand and mess with obscure return codes. If you use original
@@ -94,10 +94,10 @@ such as DMLERR_NO_ERROR, APPCLASS_STANDARD, etc. So if you need only DDE-related
94
94
  there is no need to load all the other modules, clogging your namespaces - just require 'win/dde'
95
95
  and be done with it.
96
96
 
97
- And if you do not see your favorite Windows API functions amoung those already defined, it is
98
- quite easy to 'include Win::Library' into your module and define new ones with 'function'
99
- class method (macro) - it does a lot of heavy lifting for you and can be customized with options
100
- and code blocks to give you reusable API wrapper methods with the exact behavior you need.
97
+ And if you do not see your favorite Windows API functions among those already defined, it is
98
+ quite easy to 'include Win::Library' into your module and define new ones with 'function' macro -
99
+ it does a lot of heavy lifting for you and can be customized with options and code blocks to give
100
+ you reusable API wrapper methods with the exact behavior you need.
101
101
 
102
102
  == REQUIREMENTS:
103
103
 
@@ -114,20 +114,45 @@ Contributors always welcome!
114
114
  $ gem install win
115
115
 
116
116
  == SYNOPSIS
117
+ === Using pre-defined Windows API functions:
117
118
 
118
- require 'win/window'
119
+ require 'win/gui'
119
120
 
120
121
  class MyClass
121
- include Win::Window
122
+ include Win::Gui::Window
122
123
 
123
124
  fg_window = foreground_window
124
125
  puts window_text(fg_window)
125
126
  show_window(fg_window) unless minimized?(fg_window)
126
- hide_window(fg_window) if maximized?(fg_window)
127
127
  ...
128
128
  end
129
129
 
130
- == CREDITS:
130
+ === Defining your own Windows API functions:
131
+
132
+ require 'win/library'
133
+
134
+ module YourLibModule
135
+ include Win::Library
136
+
137
+ # Customizing method behavior: zeronil forces function to return nil instead of 0, rename renames method
138
+ function :FindWindow, [:pointer, :pointer], :ulong, zeronil: true, rename: my_find
139
+
140
+ # Customizing even further: your own method extension in attached block
141
+ function :GetWindowText, [ :pointer, :pointer, :int ], :int do |api, handle|
142
+ buffer = FFI::MemoryPointer.new :char, 512
143
+ buffer.put_string(0, "\x00" * 511)
144
+ num_chars = api.call(handle, buffer, 512)
145
+ return nil if num_chars == 0
146
+ string = buffer.get_bytes(0, num_chars)
147
+ end
148
+ end
149
+
150
+ extend YourLibModule
151
+
152
+ handle = my_find(nil, nil) # find ANY window
153
+ puts window_text(handle) # print window title
154
+
155
+ == PRIOR ART:
131
156
 
132
157
  This library started as an extension of ideas and code described in excellent book
133
158
  "Scripted GUI Testing with Ruby" by Ian Dees. 'win32-api' and 'windows-pr' gems by
data/Rakefile CHANGED
@@ -5,8 +5,8 @@ begin
5
5
  require 'jeweler'
6
6
  Jeweler::Tasks.new do |gem|
7
7
  gem.name = "win"
8
- gem.summary = %Q{A collection of pre-defined Windows API functions with Rubyesque interfaces}
9
- gem.description = %Q{A collection of pre-defined Windows API functions with Rubyesque interfaces}
8
+ gem.summary = %Q{Rubyesque interfaces and wrappers for Windows API functions pre-defined using FFI }
9
+ gem.description = %Q{Rubyesque interfaces and wrappers for Windows API functions pre-defined using FFI }
10
10
  gem.email = "arvitallian@gmail.com"
11
11
  gem.homepage = "http://github.com/arvicco/win"
12
12
  gem.authors = ["arvicco"]
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.6
1
+ 0.1.0
data/lib/win/dde.rb CHANGED
@@ -122,17 +122,7 @@ module Win
122
122
  #
123
123
  function 'RegisterClipboardFormat', 'P', 'I', zeronil: true
124
124
 
125
- # Procedure that calls (DdeInitialize) function expecting a DdeCallback. Runtime block is converted
126
- # into Dde callback and registered with DdeInitialize. Returns DDE init status and DDE instance id.
127
- #
128
- return_id_status = ->(api, id=0, cmd, &block){
129
- raise ArgumentError, 'No callback block' unless block
130
-
131
- status = api.call(id = [id].pack('L'), block, cmd, 0)
132
- id = status == 0 ? id.unpack('L').first : nil
133
- [id, status] }
134
-
135
- # DdeCallabck declaration
125
+ # DdeCallaback declaration
136
126
  # MSDN syntax: HDDEDATA CALLBACK DdeCallback( UINT uType, UINT uFmt, HCONV hconv, HDDEDATA hsz1, HDDEDATA hsz2,
137
127
  # HDDEDATA hdata, HDDEDATA dwData1, HDDEDATA dwData2);
138
128
  callback :dde_callback, [:uint, :uint, :HCONV, :HDDEDATA, :HDDEDATA, :HDDEDATA, :HDDEDATA, :HDDEDATA], :HDDEDATA
@@ -187,7 +177,15 @@ module Win
187
177
  # :call-seq:
188
178
  # id_inst, status = dde_initialize( id_inst = 0, cmd ) {|callback args| callback block}
189
179
  #
190
- function 'DdeInitialize', [:pointer, :dde_callback, :DWORD, :DWORD], :uint, &return_id_status
180
+ function 'DdeInitialize', [:pointer, :dde_callback, :DWORD, :DWORD], :uint,
181
+ &->(api, old_id=0, cmd, &block){
182
+ raise ArgumentError, 'No callback block' unless block
183
+ id = FFI::MemoryPointer.new(:long)
184
+ id.write_long(old_id)
185
+ status = api.call(id, block, cmd, 0)
186
+ id = status == 0 ? id.read_long() : nil
187
+ [id, status] }
188
+ # weird lambda literal instead of block is needed because RDoc goes crazy if block is attached to meta-definition
191
189
 
192
190
  ##
193
191
  # The DdeCreateStringHandle function creates a handle that identifies the specified string.
@@ -209,7 +207,7 @@ module Win
209
207
  # Return Value (L) or nil: If the function succeeds, the return value is a string handle.
210
208
  # If the function fails, the return value is 0(changed to nil in enhanced version).
211
209
  # The DdeGetLastError function can be used to get the error code, which can be one of the following values:
212
- #DMLERR_NO_ERROR, DMLERR_INVALIDPARAMETER, DMLERR_SYS_ERROR
210
+ # DMLERR_NO_ERROR, DMLERR_INVALIDPARAMETER, DMLERR_SYS_ERROR
213
211
  #
214
212
  # Remarks: The value of a string handle is not related to the case of the string it identifies.
215
213
  # When an application either creates a string handle or receives one in the callback function
@@ -217,7 +215,7 @@ module Win
217
215
  # handle when it is no longer needed. An instance-specific string handle cannot be mapped from string
218
216
  # handle to string and back to string handle.
219
217
  #
220
- function 'DdeCreateStringHandle', [:DWORD, :pointer, :int], :HSZ
218
+ function 'DdeCreateStringHandle', [:DWORD, :pointer, :int], :HSZ, zeronil: true
221
219
 
222
220
  end
223
- end
221
+ end
@@ -21,4 +21,4 @@ class String
21
21
  raise "Can't convert unknown character: #{self}"
22
22
  end
23
23
  end
24
- end
24
+ end
@@ -0,0 +1,142 @@
1
+ require 'win/library'
2
+ require 'win/gui/window'
3
+ require 'win/gui/message'
4
+ require 'win/gui/input'
5
+
6
+ module Win
7
+ module Gui
8
+ # Contains convenience methods and extra wrappers for Windows Gui related functions
9
+ #
10
+ module Convenience
11
+ include Win::Gui::Window
12
+ include Win::Gui::Message
13
+ include Win::Gui::Input
14
+
15
+ # Internal constants:
16
+
17
+ # Key event delay
18
+ KEY_DELAY = 0.00001
19
+ # Wait delay
20
+ SLEEP_DELAY = 0.001
21
+ # Timeout waiting for Window to be closed
22
+ CLOSE_TIMEOUT = 1
23
+
24
+ # Convenience wrapper methods:
25
+
26
+ # Hides the window and activates another window
27
+ def hide_window(win_handle)
28
+ show_window(win_handle, SW_HIDE)
29
+ end
30
+
31
+ ##
32
+ # Tests if given window handle points to foreground (topmost) window
33
+ #
34
+ def foreground?(win_handle)
35
+ win_handle == foreground_window
36
+ end
37
+
38
+ ##
39
+ # Emulates combinations of (any amount of) keys pressed one after another (Ctrl+Alt+P) and then released
40
+ # *keys should be a sequence of a virtual-key codes. The codes must be a value in the range 1 to 254.
41
+ # For a complete list, see msdn:Virtual Key Codes.
42
+ def keystroke(*keys)
43
+ return if keys.empty?
44
+ keybd_event keys.first, 0, KEYEVENTF_KEYDOWN, 0
45
+ sleep KEY_DELAY
46
+ keystroke *keys[1..-1]
47
+ sleep KEY_DELAY
48
+ keybd_event keys.first, 0, KEYEVENTF_KEYUP, 0
49
+ end
50
+
51
+ # types text message into window holding the focus
52
+ def type_in(message)
53
+ message.scan(/./m) do |char|
54
+ keystroke(*char.to_vkeys)
55
+ end
56
+ end
57
+
58
+ # finds top-level dialog window by title and yields found dialog window to block if given
59
+ def dialog(title, seconds=3)
60
+ d = begin
61
+ win = WrapWindow.top_level(title, seconds)
62
+ yield(win) ? win : nil
63
+ rescue TimeoutError
64
+ end
65
+ d.wait_for_close if d
66
+ return d
67
+ end
68
+
69
+ # This class is a thin wrapper around window handle
70
+ class WrapWindow
71
+ include Win::Gui::Window
72
+ extend Win::Gui::Window
73
+ include Win::Gui::Message
74
+
75
+ attr_reader :handle
76
+
77
+ # find top level window by title, return wrapped Window object
78
+ def self.top_level(title, seconds=3)
79
+ @handle = timeout(seconds) do
80
+ sleep SLEEP_DELAY while (h = find_window nil, title) == nil; h
81
+ end
82
+ WrapWindow.new @handle
83
+ end
84
+
85
+ def initialize(handle)
86
+ @handle = handle
87
+ end
88
+
89
+ # find child window (control) by title, window class, or control ID:
90
+ def child(id)
91
+ result = case id
92
+ when String
93
+ by_title = find_window_ex @handle, 0, nil, id.gsub('_', '&' )
94
+ by_class = find_window_ex @handle, 0, id, nil
95
+ by_title ? by_title : by_class
96
+ when Fixnum
97
+ get_dlg_item @handle, id
98
+ when nil
99
+ find_window_ex @handle, 0, nil, nil
100
+ else
101
+ nil
102
+ end
103
+ raise "Control '#{id}' not found" unless result
104
+ WrapWindow.new result
105
+ end
106
+
107
+ def children
108
+ enum_child_windows(@handle).map{|child_handle| WrapWindow.new child_handle}
109
+ end
110
+
111
+ # emulate click of the control identified by id
112
+ def click(id)
113
+ h = child(id).handle
114
+ rectangle = [0, 0, 0, 0].pack 'LLLL'
115
+ get_window_rect h, rectangle
116
+ left, top, right, bottom = rectangle.unpack 'LLLL'
117
+ center = [(left + right) / 2, (top + bottom) / 2]
118
+ set_cursor_pos *center
119
+ mouse_event MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0
120
+ mouse_event MOUSEEVENTF_LEFTUP, 0, 0, 0, 0
121
+ end
122
+
123
+ def close
124
+ post_message @handle, WM_SYSCOMMAND, SC_CLOSE, 0
125
+ end
126
+
127
+ def wait_for_close
128
+ timeout(CLOSE_TIMEOUT) do
129
+ sleep SLEEP_DELAY while window_visible?(@handle)
130
+ end
131
+ end
132
+
133
+ def text
134
+ buffer = "\x0" * 2048
135
+ length = send_message @handle, WM_GETTEXT, buffer.length, buffer
136
+ length == 0 ? '' : buffer[0..length - 1]
137
+ end
138
+ end
139
+ end
140
+ end
141
+ end
142
+
@@ -0,0 +1,15 @@
1
+ require 'win/library'
2
+
3
+ module Win
4
+ module Gui
5
+ # Contains constants and Win32API functions related to dialog manipulation
6
+ #
7
+ module Dialog
8
+ include Win::Library
9
+
10
+ function 'GetDlgItem', 'LL', 'L'
11
+ end
12
+ end
13
+ end
14
+
15
+
@@ -0,0 +1,255 @@
1
+ require 'win/library'
2
+
3
+ module Win
4
+ module Gui
5
+ # Contains constants and Win32API functions related to end user input
6
+ #
7
+ module Input
8
+ include Win::Library
9
+
10
+ # Windows keyboard-related Constants:
11
+
12
+ # Key down keyboard event (the key is being depressed)
13
+ KEYEVENTF_KEYDOWN = 0
14
+ # Key up keyboard event (the key is being released)
15
+ KEYEVENTF_KEYUP = 2
16
+ # Extended kb event. If specified, the scan code was preceded by a prefix byte having the value 0xE0 (224).
17
+ KEYEVENTF_EXTENDEDKEY = 1
18
+
19
+ # Virtual key codes:
20
+
21
+ # Control-break processing
22
+ VK_CANCEL = 0x03
23
+ # Backspace? key
24
+ VK_BACK = 0x08
25
+ # Tab key
26
+ VK_TAB = 0x09
27
+ # Shift key
28
+ VK_SHIFT = 0x10
29
+ # Ctrl key
30
+ VK_CONTROL = 0x11
31
+ # ENTER key
32
+ VK_RETURN = 0x0D
33
+ # ALT key
34
+ VK_ALT = 0x12
35
+ # ALT key alias
36
+ VK_MENU = 0x12
37
+ # PAUSE key
38
+ VK_PAUSE = 0x13
39
+ # CAPS LOCK key
40
+ VK_CAPITAL = 0x14
41
+ # ESC key
42
+ VK_ESCAPE = 0x1B
43
+ # SPACEBAR
44
+ VK_SPACE = 0x20
45
+ # PAGE UP key
46
+ VK_PRIOR = 0x21
47
+ # PAGE DOWN key
48
+ VK_NEXT = 0x22
49
+ # END key
50
+ VK_END = 0x23
51
+ # HOME key
52
+ VK_HOME = 0x24
53
+ # LEFT ARROW key
54
+ VK_LEFT = 0x25
55
+ # UP ARROW key
56
+ VK_UP = 0x26
57
+ # RIGHT ARROW key
58
+ VK_RIGHT = 0x27
59
+ # DOWN ARROW key
60
+ VK_DOWN = 0x28
61
+ # SELECT key
62
+ VK_SELECT = 0x29
63
+ # PRINT key
64
+ VK_PRINT = 0x2A
65
+ # EXECUTE key
66
+ VK_EXECUTE = 0x2B
67
+ # PRINT SCREEN key
68
+ VK_SNAPSHOT = 0x2C
69
+ # INS key
70
+ VK_INSERT = 0x2D
71
+ # DEL key
72
+ VK_DELETE = 0x2E
73
+ # HELP key
74
+ VK_HELP = 0x2F
75
+
76
+ # Public Type MOUSEINPUT
77
+ # dx As Long
78
+ # dy As Long
79
+ # mouseData As Long
80
+ # dwFlags As Long
81
+ # time As Long
82
+ # dwExtraInfo As Long
83
+ # End Type
84
+ #
85
+ # Public Type INPUT_TYPE
86
+ # dwType As Long
87
+ # xi(0 To 23) As Byte
88
+ # End Type
89
+
90
+
91
+
92
+ # dwFlags:
93
+ # Specifies that the dx and dy parameters contain normalized absolute coordinates. If not set, those parameters
94
+ # contain relative data: the change in position since the last reported position. This flag can be set, or not
95
+ # set, regardless of what kind of mouse or mouse-like device, if any, is connected to the system. For further
96
+ # information about relative mouse motion, see mouse_event Remarks section.
97
+ MOUSEEVENTF_ABSOLUTE = 0x8000
98
+ #Specifies that movement occurred.
99
+ MOUSEEVENTF_MOVE = 0x01
100
+ #Specifies that the left button is down.
101
+ MOUSEEVENTF_LEFTDOWN = 0x02
102
+ #Specifies that the left button is up.
103
+ MOUSEEVENTF_LEFTUP = 0x04
104
+ #Specifies that the right button is down.
105
+ MOUSEEVENTF_RIGHTDOWN = 0x08
106
+ #Specifies that the right button is up.
107
+ MOUSEEVENTF_RIGHTUP = 0x010
108
+ #Specifies that the middle button is down.
109
+ MOUSEEVENTF_MIDDLEDOWN = 0x20
110
+ #Specifies that the middle button is up.
111
+ MOUSEEVENTF_MIDDLEUP = 0x040
112
+ #Windows NT/2000/XP: Specifies that the wheel has been moved, if the mouse has a wheel. The amount of movement
113
+ #is specified in dwData
114
+ MOUSEEVENTF_WHEEL = 0x80
115
+ #Windows 2000/XP: Specifies that an X button was pressed.
116
+ MOUSEEVENTF_XDOWN = 0x100
117
+ #Windows 2000/XP: Specifies that an X button was released.
118
+ MOUSEEVENTF_XUP = 0x200
119
+
120
+ # dwData:
121
+ # One wheel click is defined as WHEEL_DELTA, which is 120.
122
+ WHEEL_DELTA = 120
123
+ # Set if the first X button was pressed or released.
124
+ XBUTTON1 = 1
125
+ # Set if the second X button was pressed or released.
126
+ XBUTTON2 = 2
127
+ # Indicates NO data if dwFlags are NOT any of MOUSEEVENTF_WHEEL, MOUSEEVENTF_XDOWN, or MOUSEEVENTF_XUP
128
+ INPUT_MOUSE = 0
129
+
130
+
131
+ ##
132
+ # The keybd_event function synthesizes a keystroke. The system can use such a synthesized keystroke to generate
133
+ # a WM_KEYUP or WM_KEYDOWN message. The keyboard driver's interrupt handler calls the keybd_event function.
134
+ #
135
+ # !!!! Windows NT/2000/XP/Vista:This function has been superseded. Use SendInput instead.
136
+ #
137
+ # Syntax: VOID keybd_event( BYTE bVk, BYTE bScan, DWORD dwFlags, PTR dwExtraInfo);
138
+ #
139
+ # Parameters:
140
+ # bVk [C] - [in] Specifies a virtual-key code. The code must be a value in the range 1 to 254.
141
+ # For a complete list, see Virtual-Key Codes.
142
+ # bScan [C] - [in] Specifies a hardware scan code for the key.
143
+ # dwFlags [L] - [in] Specifies various aspects of function operation. This parameter can be
144
+ # one or more of the following values:
145
+ # KEYEVENTF_EXTENDEDKEY, KEYEVENTF_KEYUP, KEYEVENTF_KEYDOWN
146
+ # dwExtraInfo [L] -[in] Specifies an additional value associated with the key stroke.
147
+ #
148
+ # Return Value: none
149
+ #
150
+ # Remarks: An application can simulate a press of the PRINTSCRN key in order to obtain a screen snapshot and save
151
+ # it to the clipboard. To do this, call keybd_event with the bVk parameter set to VK_SNAPSHOT.
152
+ #
153
+ # Windows NT/2000/XP: The keybd_event function can toggle the NUM LOCK, CAPS LOCK, and SCROLL LOCK keys.
154
+ # Windows 95/98/Me: The keybd_event function can toggle only the CAPS LOCK and SCROLL LOCK keys.
155
+ #
156
+ function 'keybd_event', 'IILL', 'V'
157
+
158
+ ##
159
+ # The mouse_event function synthesizes mouse motion and button clicks.
160
+ # !!!! Windows NT/2000/XP: This function has been superseded. Use SendInput instead.
161
+ #
162
+ # Syntax: VOID mouse_event( DWORD dwFlags, DWORD dx, DWORD dy, DWORD dwData, ULONG_PTR dwExtraInfo );
163
+ #
164
+ # Parameters:
165
+ # flags (I) - [in] Specifies various aspects of mouse motion and button clicking. This parameter can be
166
+ # certain combinations of the following values. The values that specify mouse button status are set to
167
+ # indicate changes in status, not ongoing conditions. For example, if the left mouse button is pressed
168
+ # and held down, MOUSEEVENTF_LEFTDOWN is set when the left button is first pressed, but not for subsequent
169
+ # motions. Similarly, MOUSEEVENTF_LEFTUP is set only when the button is first released. You cannot specify
170
+ # both MOUSEEVENTF_WHEEL and either MOUSEEVENTF_XDOWN or MOUSEEVENTF_XUP simultaneously, because they
171
+ # both require use of the dwData field:
172
+ # MOUSEEVENTF_ABSOLUTE, MOUSEEVENTF_MOVE, MOUSEEVENTF_LEFTDOWN, MOUSEEVENTF_LEFTUP, MOUSEEVENTF_RIGHTDOWN,
173
+ # MOUSEEVENTF_RIGHTUP, MOUSEEVENTF_MIDDLEDOWN, MOUSEEVENTF_MIDDLEUP, MOUSEEVENTF_WHEEL, MOUSEEVENTF_XDOWN,
174
+ # MOUSEEVENTF_XUP
175
+ # dx (I) - [in] Specifies the mouse's absolute position along the x-axis or its amount of motion since the
176
+ # last mouse event was generated, depending on the setting of MOUSEEVENTF_ABSOLUTE. Absolute data is
177
+ # specified as the mouse's actual x-coordinate; relative data is specified as the number of mickeys moved.
178
+ # A mickey is the amount that a mouse has to move for it to report that it has moved.
179
+ # dy (I) - [in] Specifies the mouse's absolute position along the y-axis or its amount of motion since the
180
+ # last mouse event was generated, depending on the setting of MOUSEEVENTF_ABSOLUTE. Absolute data is
181
+ # specified as the mouse's actual y-coordinate; relative data is specified as the number of mickeys moved.
182
+ # data (I) - [in] If flags contains MOUSEEVENTF_WHEEL, then data specifies the amount of wheel movement.
183
+ # A positive value indicates that the wheel was rotated forward, away from the user; a negative value
184
+ # indicates that the wheel was rotated backward, toward the user. One wheel click is defined as
185
+ # WHEEL_DELTA, which is 120. If flags contains MOUSEEVENTF_WHHEEL, then data specifies the amount of
186
+ # wheel movement. A positive value indicates that the wheel was rotated to the right; a negative value
187
+ # indicates that the wheel was rotated to the left. One wheel click is defined as WHEEL_DELTA, which is 120.
188
+ # Windows 2000/XP: If flags contains MOUSEEVENTF_XDOWN or MOUSEEVENTF_XUP, then data specifies which X
189
+ # buttons were pressed or released. This value may be any combination of the following flags.
190
+ # If flags is not MOUSEEVENTF_WHEEL, MOUSEEVENTF_XDOWN, or MOUSEEVENTF_XUP, then data should be zero.
191
+ # XBUTTON1 - Set if the first X button was pressed or released.
192
+ # XBUTTON2 - Set if the second X button was pressed or released.
193
+ # extra_info (P) - [in] Specifies an additional value associated with the mouse event. An application
194
+ # calls GetMessageExtraInfo to obtain this extra information.
195
+ #
196
+ # NO Return Value
197
+ #
198
+ # Remarks: If the mouse has moved, indicated by MOUSEEVENTF_MOVE being set, dx and dy hold information about
199
+ # that motion. The information is specified as absolute or relative integer values. If MOUSEEVENTF_ABSOLUTE
200
+ # value is specified, dx and dy contain normalized absolute coordinates between 0 and 65,535. The event
201
+ # procedure maps these coordinates onto the display surface. Coordinate (0,0) maps onto the upper-left corner
202
+ # of the display surface, (65535,65535) maps onto the lower-right corner. If the MOUSEEVENTF_ABSOLUTE value
203
+ # is not specified, dx and dy specify relative motions from when the last mouse event was generated (the last
204
+ # reported position). Positive values mean the mouse moved right (or down); negative values mean the mouse
205
+ # moved left (or up). Relative mouse motion is subject to the settings for mouse speed and acceleration level.
206
+ # An end user sets these values using the Mouse application in Control Panel. An application obtains and sets
207
+ # these values with the SystemParametersInfo function. The system applies two tests to the specified relative
208
+ # mouse motion when applying acceleration. If the specified distance along either the x or y axis is greater
209
+ # than the first mouse threshold value, and the mouse acceleration level is not zero, the operating system
210
+ # doubles the distance. If the specified distance along either the x- or y-axis is greater than the second
211
+ # mouse threshold value, and the mouse acceleration level is equal to two, the operating system doubles the
212
+ # distance that resulted from applying the first threshold test. It is thus possible for the operating system
213
+ # to multiply relatively-specified mouse motion along the x- or y-axis by up to four times. Once acceleration
214
+ # has been applied, the system scales the resultant value by the desired mouse speed. Mouse speed can range
215
+ # from 1 (slowest) to 20 (fastest) and represents how much the pointer moves based on the distance the mouse
216
+ # moves. The default value is 10, which results in no additional modification to the mouse motion. The
217
+ # mouse_event function is used to synthesize mouse events by applications that need to do so. It is also used
218
+ # by applications that need to obtain more information from the mouse than its position and button state.
219
+ # For example, if a tablet manufacturer wants to pass pen-based information to its own applications, it can
220
+ # write a DLL that communicates directly to the tablet hardware, obtains the extra information, and saves it
221
+ # in a queue. The DLL then calls mouse_event with the standard button and x/y position data, along with,
222
+ # in the dwExtraInfo parameter, some pointer or index to the queued extra information. When the application
223
+ # needs the extra information, it calls the DLL with the pointer or index stored in dwExtraInfo, and the DLL
224
+ # returns the extra information.
225
+ #
226
+ #
227
+ function 'mouse_event', 'IIIIP', 'V'
228
+
229
+ ##
230
+ # SetCursorPos Function moves the cursor to the specified screen coordinates. If the new coordinates are not
231
+ # within the screen rectangle set by the most recent ClipCursor function call, the system automatically adjusts
232
+ # the coordinates so that the cursor stays within the rectangle.
233
+ #
234
+ # Syntax: BOOL SetCursorPos( int X, int Y );
235
+ #
236
+ # Parameters:
237
+ # X (i) - [in] Specifies the new x-coordinate of the cursor, in screen coordinates.
238
+ # Y (i) - [in] Specifies the new y-coordinate of the cursor, in screen coordinates.
239
+ #
240
+ # Return Value: Nonzero if successful or zero otherwise. To get extended error information, call GetLastError.
241
+ # Enhanced to return true/false instead of nonzero/zero
242
+ #
243
+ # Remarks: The cursor is a shared resource. A window should move the cursor only when the cursor is in the
244
+ # window's client area. The calling process must have WINSTA_WRITEATTRIBUTES access to the window station.
245
+ # The input desktop must be the current desktop when you call SetCursorPos. Call OpenInputDesktop to determine
246
+ # whether the current desktop is the input desktop. If it is not, call SetThreadDesktop with the HDESK returned
247
+ # by OpenInputDesktop to switch to that desktop.
248
+ #
249
+ # :call-seq:
250
+ # success = set_cursor_pos(x,y)
251
+ #
252
+ function :SetCursorPos, [:int, :int], :bool
253
+ end
254
+ end
255
+ end
@@ -0,0 +1,22 @@
1
+ require 'win/library'
2
+
3
+ module Win
4
+ module Gui
5
+ # Contains constants and Win32API functions related to inter-Window messaging
6
+ #
7
+ module Message
8
+ include Win::Library
9
+
10
+ # Windows Message Get Text
11
+ WM_GETTEXT = 0x000D
12
+ # Windows Message Sys Command
13
+ WM_SYSCOMMAND = 0x0112
14
+ # Sys Command Close
15
+ SC_CLOSE = 0xF060
16
+
17
+ function 'PostMessage', 'LLLL', 'L'
18
+ function 'SendMessage', 'LLLP', 'L'
19
+ end
20
+ end
21
+ end
22
+