win 0.1.9 → 0.1.11
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +5 -4
- data/VERSION +1 -1
- data/lib/win/dde.rb +105 -27
- data/lib/win/extensions.rb +4 -0
- data/lib/win/gui/dialog.rb +2 -2
- data/lib/win/gui/input.rb +1 -1
- data/lib/win/gui/message.rb +1 -1
- data/lib/win/gui/window/window.rb +6 -5
- data/lib/win/gui/window.rb +3 -2
- data/lib/win/gui.rb +6 -5
- data/lib/win/library.rb +35 -31
- data/spec/spec_helper.rb +2 -2
- data/spec/win/dde_spec.rb +6 -0
- data/spec/win/gui/dialog_spec.rb +3 -3
- data/spec/win/gui/input_spec.rb +3 -3
- data/spec/win/gui/message_spec.rb +3 -3
- data/spec/win/gui/window/window_spec.rb +5 -5
- data/spec/win/gui/window_spec.rb +16 -14
- data/win.gemspec +2 -2
- metadata +2 -2
data/README.rdoc
CHANGED
@@ -116,10 +116,10 @@ Contributors always welcome!
|
|
116
116
|
== SYNOPSIS
|
117
117
|
=== Using pre-defined Windows API functions:
|
118
118
|
|
119
|
-
require 'win/gui'
|
119
|
+
require 'win/gui/window'
|
120
120
|
|
121
121
|
class MyClass
|
122
|
-
include Win::
|
122
|
+
include Win::GUI::Window
|
123
123
|
|
124
124
|
fg_window = foreground_window
|
125
125
|
puts window_text(fg_window)
|
@@ -134,6 +134,9 @@ Contributors always welcome!
|
|
134
134
|
module YourLibModule
|
135
135
|
include Win::Library
|
136
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
|
+
|
137
140
|
# Customizing even further: your own method extension in attached block
|
138
141
|
function :GetWindowText, [ :ulong, :pointer, :int ], :int do |api, handle|
|
139
142
|
buffer = FFI::MemoryPointer.new :char, 512
|
@@ -142,8 +145,6 @@ Contributors always welcome!
|
|
142
145
|
num_chars == 0 ? nil : buffer.get_bytes(0, num_chars)
|
143
146
|
end
|
144
147
|
|
145
|
-
# Customizing method behavior: zeronil forces function to return nil instead of 0, rename renames method
|
146
|
-
function :FindWindow, [:pointer, :pointer], :ulong, zeronil: true, rename: :my_find
|
147
148
|
end
|
148
149
|
|
149
150
|
include YourLibModule
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.11
|
data/lib/win/dde.rb
CHANGED
@@ -13,10 +13,8 @@ module Win
|
|
13
13
|
# DDE name service afCmd commands used by DdeNameService function:
|
14
14
|
|
15
15
|
# Registers the service name.
|
16
|
-
|
17
16
|
DNS_REGISTER = 1
|
18
|
-
# Unregisters the service name.
|
19
|
-
# unregistered.
|
17
|
+
# Unregisters the service name. When hsz1 == 0L, ALL service names registered by the server will be unregistered.
|
20
18
|
DNS_UNREGISTER = 2
|
21
19
|
# Turns on service name initiation filtering. The filter prevents a server from receiving
|
22
20
|
# XTYP_CONNECT transactions for service names it has not registered. This is the default
|
@@ -30,28 +28,51 @@ module Win
|
|
30
28
|
|
31
29
|
# Transaction types:
|
32
30
|
|
31
|
+
XTYPF_NOBLOCK = 0x0002
|
32
|
+
XTYPF_NODATA = 0x0004
|
33
|
+
XTYPF_ACKREQ = 0x0008
|
34
|
+
|
35
|
+
XCLASS_MASK = 0xFC00
|
36
|
+
XCLASS_BOOL = 0x1000
|
37
|
+
XCLASS_DATA = 0x2000
|
38
|
+
XCLASS_FLAGS = 0x4000
|
39
|
+
XCLASS_NOTIFICATION = 0x8000
|
40
|
+
|
41
|
+
XTYP_ERROR = XCLASS_NOTIFICATION | XTYPF_NOBLOCK
|
42
|
+
XTYP_ADVDATA = 0x0010 | XCLASS_FLAGS
|
43
|
+
XTYP_ADVREQ = 0x0020 | XCLASS_DATA | XTYPF_NOBLOCK
|
44
|
+
XTYP_ADVSTART = 0x0030 | XCLASS_BOOL
|
45
|
+
XTYP_ADVSTOP = 0x0040 | XCLASS_NOTIFICATION
|
46
|
+
XTYP_EXECUTE = 0x0050 | XCLASS_FLAGS
|
33
47
|
# A client uses the XTYP_CONNECT transaction to establish a conversation. A DDE server callback function,
|
34
48
|
# DdeCallback, receives this transaction when a client specifies a service name that the server supports
|
35
49
|
# (and a topic name that is not NULL) in a call to the DdeConnect function.
|
36
|
-
XTYP_CONNECT
|
37
|
-
|
38
|
-
|
39
|
-
# A client uses the XTYP_POKE transaction to send unsolicited data to the server. DDE server callback function,
|
50
|
+
XTYP_CONNECT = 0x0060 | XCLASS_BOOL | XTYPF_NOBLOCK
|
51
|
+
XTYP_CONNECT_CONFIRM = 0x0070 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK
|
52
|
+
XTYP_XACT_COMPLETE = 0x0080 | XCLASS_NOTIFICATION
|
53
|
+
# A client uses the XTYP_POKE transaction to send unsolicited data to the server. DDE server callback function,
|
40
54
|
# DdeCallback, receives this transaction when a client specifies XTYP_POKE in the DdeClientTransaction function.
|
41
|
-
XTYP_POKE
|
42
|
-
|
55
|
+
XTYP_POKE = 0x0090 | XCLASS_FLAGS
|
56
|
+
XTYP_REGISTER = 0x00A0 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK
|
57
|
+
XTYP_REQUEST = 0x00B0 | XCLASS_DATA
|
58
|
+
XTYP_DISCONNECT = 0x00C0 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK
|
59
|
+
XTYP_UNREGISTER = 0x00D0 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK
|
60
|
+
XTYP_WILDCONNECT = 0x00E0 | XCLASS_DATA | XTYPF_NOBLOCK
|
61
|
+
XTYP_MONITOR = 0X00F0 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK
|
62
|
+
XTYP_MASK = 0x00F0
|
63
|
+
XTYP_SHIFT = 0x0004
|
43
64
|
|
44
65
|
# Transaction confirmations:
|
45
66
|
|
46
67
|
# Transaction confirmation
|
47
|
-
DDE_FACK
|
68
|
+
DDE_FACK = 0x8000
|
48
69
|
# Server is too busy to process transaction
|
49
|
-
DDE_FBUSY
|
50
|
-
DDE_FDEFERUPD
|
51
|
-
DDE_FACKREQ
|
70
|
+
DDE_FBUSY = 0x4000
|
71
|
+
DDE_FDEFERUPD = 0x4000
|
72
|
+
DDE_FACKREQ = 0x8000
|
52
73
|
DDE_FRELEASE = 0x2000
|
53
|
-
DDE_FREQUESTED
|
54
|
-
DDE_FAPPSTATUS
|
74
|
+
DDE_FREQUESTED = 0x1000
|
75
|
+
DDE_FAPPSTATUS = 0x00ff
|
55
76
|
# Transaction rejected
|
56
77
|
DDE_FNOTPROCESSED = 0
|
57
78
|
|
@@ -130,10 +151,23 @@ module Win
|
|
130
151
|
|
131
152
|
# Returned if DDE Init successful
|
132
153
|
DMLERR_NO_ERROR = 0x00
|
154
|
+
# First (lowest) error code
|
155
|
+
DMLERR_FIRST = 0x4000
|
156
|
+
# A request for a synchronous advise transaction has timed out.
|
157
|
+
DMLERR_ADVACKTIMEOUT = DMLERR_FIRST
|
158
|
+
# The response to the transaction caused the DDE_FBUSY flag to be set
|
159
|
+
DMLERR_BUSY = 0x4001
|
160
|
+
# A request for a synchronous data transaction has timed out.
|
161
|
+
DMLERR_DATAACKTIMEOUT = 0x4002
|
162
|
+
# A DDEML function was called without first calling the DdeInitialize function, or an invalid instance
|
163
|
+
# identifier was passed to a DDEML function.
|
164
|
+
DMLERR_DLL_NOT_INITIALIZED = 0x4003
|
133
165
|
# An application initialized as APPCLASS_MONITOR has attempted to perform a Dynamic Data Exchange (DDE) transaction,
|
134
|
-
# or an application initialized as APPCMD_CLIENTONLY has attempted to perform server transactions.
|
166
|
+
# or an application initialized as APPCMD_CLIENTONLY has attempted to perform server transactions.
|
135
167
|
DMLERR_DLL_USAGE = 0x4004
|
136
|
-
#
|
168
|
+
# A request for a synchronous execute transaction has timed out.
|
169
|
+
DMLERR_EXECACKTIMEOUT = 0x4005
|
170
|
+
# A parameter failed to be validated by the DDEML. Some of the possible causes follow:
|
137
171
|
# - The application used a data handle initialized with a different item name handle than was required by the
|
138
172
|
# transaction.
|
139
173
|
# - The application used a data handle that was initialized with a different clipboard data format than was
|
@@ -142,24 +176,68 @@ module Win
|
|
142
176
|
# - The application used a freed data handle or string handle.
|
143
177
|
# - More than one instance of the application used the same object.
|
144
178
|
DMLERR_INVALIDPARAMETER = 0x4006
|
145
|
-
# DMLERR_SYS_ERROR An internal error has occurred in the DDEML.
|
146
|
-
DMLERR_SYS_ERROR = 0x400f
|
147
|
-
# DMLERR_ADVACKTIMEOUT A request for a synchronous advise transaction has timed out.
|
148
|
-
# DMLERR_BUSY The response to the transaction caused the DDE_FBUSY flag to be set.
|
149
|
-
# DMLERR_DATAACKTIMEOUT A request for a synchronous data transaction has timed out.
|
150
|
-
# DMLERR_DLL_NOT_INITIALIZED A DDEML function was called without first calling the DdeInitialize function, or an invalid instance identifier was passed to a DDEML function.
|
151
|
-
# DMLERR_DLL_USAGE
|
152
|
-
# DMLERR_EXECACKTIMEOUT A request for a synchronous execute transaction has timed out.
|
153
179
|
# DMLERR_LOW_MEMORY A DDEML application has created a prolonged race condition (in which the server application outruns the client), causing large amounts of memory to be consumed.
|
180
|
+
DMLERR_LOW_MEMORY = 0x4007
|
154
181
|
# DMLERR_MEMORY_ERROR A memory allocation has failed.
|
155
|
-
|
182
|
+
DMLERR_MEMORY_ERROR = 0x4008
|
156
183
|
# DMLERR_NOTPROCESSED A transaction has failed.
|
184
|
+
DMLERR_NOTPROCESSED = 0x4009
|
185
|
+
# DMLERR_NO_CONV_ESTABLISHED A client's attempt to establish a conversation has failed.
|
186
|
+
DMLERR_NO_CONV_ESTABLISHED = 0x400a
|
157
187
|
# DMLERR_POKEACKTIMEOUT A request for a synchronous poke transaction has timed out.
|
188
|
+
DMLERR_POKEACKTIMEOUT = 0x400b
|
158
189
|
# DMLERR_POSTMSG_FAILED An internal call to the PostMessage function has failed.
|
190
|
+
DMLERR_POSTMSG_FAILED = 0x400c
|
159
191
|
# DMLERR_REENTRANCY An application instance with a synchronous transaction already in progress attempted to initiate another synchronous transaction, or the DdeEnableCallback function was called from within a DDEML callback function.
|
192
|
+
DMLERR_REENTRANCY = 0x400d
|
160
193
|
# DMLERR_SERVER_DIED A server-side transaction was attempted on a conversation terminated by the client, or the server terminated before completing a transaction.
|
194
|
+
DMLERR_SERVER_DIED = 0x400e
|
195
|
+
# DMLERR_SYS_ERROR An internal error has occurred in the DDEML.
|
196
|
+
DMLERR_SYS_ERROR = 0x400f
|
161
197
|
# DMLERR_UNADVACKTIMEOUT A request to end an advise transaction has timed out.
|
198
|
+
DMLERR_UNADVACKTIMEOUT = 0x4010
|
162
199
|
# DMLERR_UNFOUND_QUEUE_ID An invalid transaction identifier was passed to a DDEML function. Once the application has returned from an XTYP_XACT_COMPLETE callback, the transaction identifier for that callback function is no longer valid.
|
200
|
+
DMLERR_UNFOUND_QUEUE_ID = 0x4011
|
201
|
+
# Last (highest) error code
|
202
|
+
DMLERR_LAST = DMLERR_UNFOUND_QUEUE_ID
|
203
|
+
|
204
|
+
# Hash {ERROR_CODE=>'Error description')}
|
205
|
+
ERRORS = {
|
206
|
+
DMLERR_ADVACKTIMEOUT => 'A request for a synchronous advise transaction has timed out.',
|
207
|
+
DMLERR_BUSY => 'The response to the transaction caused the DDE_FBUSY flag to be set.',
|
208
|
+
DMLERR_DATAACKTIMEOUT => 'A request for a synchronous data transaction has timed out.',
|
209
|
+
DMLERR_DLL_NOT_INITIALIZED => 'A DDEML function was called without first calling the DdeInitialize ' +
|
210
|
+
'function, or an invalid instance identifier was passed to a DDEML function.',
|
211
|
+
DMLERR_DLL_USAGE => 'An application initialized as APPCLASS_MONITOR has attempted to perform a DDE ' +
|
212
|
+
'transaction, or an application initialized as APPCMD_CLIENTONLY has attempted to perform ' +
|
213
|
+
'server transactions.',
|
214
|
+
DMLERR_EXECACKTIMEOUT => 'A request for a synchronous execute transaction has timed out.',
|
215
|
+
DMLERR_INVALIDPARAMETER => 'A parameter failed to be validated by the DDEML. Possible causes: ' +
|
216
|
+
'Application used a data handle initialized with a different item name handle than was required ' +
|
217
|
+
'by the transaction.' +
|
218
|
+
'The application used a data handle that was initialized with a different clipboard data format ' +
|
219
|
+
'than was required by the transaction. ' +
|
220
|
+
'The application used a client-side conversation handle with server-side function or vice versa. ' +
|
221
|
+
'The application used a freed data handle or string handle. ' +
|
222
|
+
'More than one instance of the application used the same object.',
|
223
|
+
DMLERR_LOW_MEMORY => 'A DDEML application has created a prolonged race condition (in which the server ' +
|
224
|
+
'application outruns the client), causing large amounts of memory to be consumed.',
|
225
|
+
DMLERR_MEMORY_ERROR => 'A memory allocation has failed.',
|
226
|
+
DMLERR_NO_CONV_ESTABLISHED => 'A client`s attempt to establish a conversation has failed.',
|
227
|
+
DMLERR_NOTPROCESSED => 'A transaction has failed.',
|
228
|
+
DMLERR_POKEACKTIMEOUT => 'A request for a synchronous poke transaction has timed out.',
|
229
|
+
DMLERR_POSTMSG_FAILED => 'An internal call to the PostMessage function has failed.',
|
230
|
+
DMLERR_REENTRANCY => 'An application instance with a synchronous transaction already in progress ' +
|
231
|
+
'attempted to initiate another synchronous transaction, or the DdeEnableCallback function ' +
|
232
|
+
'was called from within a DDEML callback function.',
|
233
|
+
DMLERR_SERVER_DIED => 'A server-side transaction was attempted on a conversation terminated by the ' +
|
234
|
+
'client, or the server terminated before completing a transaction.',
|
235
|
+
DMLERR_SYS_ERROR => 'An internal error has occurred in the DDEML.',
|
236
|
+
DMLERR_UNADVACKTIMEOUT => 'A request to end an advise transaction has timed out.',
|
237
|
+
DMLERR_UNFOUND_QUEUE_ID => 'An invalid transaction identifier was passed to a DDEML function. Once the ' +
|
238
|
+
'application has returned from an XTYP_XACT_COMPLETE callback, the transaction identifier for ' +
|
239
|
+
'that callback function is no longer valid.'
|
240
|
+
}
|
163
241
|
|
164
242
|
##
|
165
243
|
# The RegisterClipboardFormat function registers a new clipboard format.
|
@@ -575,7 +653,7 @@ module Win
|
|
575
653
|
# during the XTYP_REGISTER and XTYP_UNREGISTER transactions.
|
576
654
|
# - All members of the default CONVCONTEXT structure are set to zero except cb, which specifies the size of the
|
577
655
|
# structure, and iCodePage, which specifies CP_WINANSI (the default code page) or CP_WINUNICODE, depending on
|
578
|
-
# whether the ANSI or Unicode version of the DdeInitialize function was called by the client application.
|
656
|
+
# whether the ANSI or Unicode version of the DdeInitialize function was called by the client application.
|
579
657
|
#
|
580
658
|
# :call-seq:
|
581
659
|
# conversation_handle = dde_connect( instance_id, [service = nil, topic = nil, context = nil] )
|
data/lib/win/extensions.rb
CHANGED
@@ -1,12 +1,16 @@
|
|
1
1
|
class String
|
2
|
+
# returns snake_case representation of string
|
2
3
|
def snake_case
|
3
4
|
gsub(/([a-z])([A-Z0-9])/, '\1_\2' ).downcase
|
4
5
|
end
|
5
6
|
|
7
|
+
# converts string to 'wide char' (Windows Unicode) format
|
6
8
|
def to_w
|
7
9
|
(self+"\x00").encode('utf-16LE')
|
8
10
|
end
|
9
11
|
|
12
|
+
# converts one-char string into keyboard-scan 'Virtual key' code
|
13
|
+
# only letters and numbers convertable so far, need to be extended
|
10
14
|
def to_vkeys
|
11
15
|
unless size == 1
|
12
16
|
raise "Can't convert but a single character: #{self}"
|
data/lib/win/gui/dialog.rb
CHANGED
@@ -2,12 +2,12 @@ require 'win/library'
|
|
2
2
|
require 'win/gui/window'
|
3
3
|
|
4
4
|
module Win
|
5
|
-
module
|
5
|
+
module GUI
|
6
6
|
# Contains constants and Win32API functions related to dialog manipulation
|
7
7
|
#
|
8
8
|
module Dialog
|
9
9
|
include Win::Library
|
10
|
-
include Win::
|
10
|
+
include Win::GUI::Window
|
11
11
|
|
12
12
|
# The GetDlgItem function retrieves a handle to a control in the specified dialog box.
|
13
13
|
#
|
data/lib/win/gui/input.rb
CHANGED
data/lib/win/gui/message.rb
CHANGED
@@ -4,19 +4,20 @@ require 'win/gui/message'
|
|
4
4
|
require 'win/gui/input'
|
5
5
|
|
6
6
|
module Win
|
7
|
-
module
|
7
|
+
module GUI
|
8
8
|
module Window
|
9
9
|
# This class is a thin wrapper around window handle
|
10
|
+
# It should be probably moved out of this lib since it's supposed to be "close to metal"
|
10
11
|
class Window
|
11
12
|
# Wait delay
|
12
13
|
SLEEP_DELAY = 0.001
|
13
14
|
# Timeout waiting for Window to be closed
|
14
15
|
CLOSE_TIMEOUT = 1
|
15
16
|
|
16
|
-
include Win::
|
17
|
-
extend Win::
|
18
|
-
include Win::
|
19
|
-
include Win::
|
17
|
+
include Win::GUI::Window
|
18
|
+
extend Win::GUI::Window
|
19
|
+
include Win::GUI::Message
|
20
|
+
include Win::GUI::Input
|
20
21
|
|
21
22
|
attr_reader :handle
|
22
23
|
|
data/lib/win/gui/window.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'win/library'
|
2
2
|
|
3
3
|
module Win
|
4
|
-
module
|
4
|
+
module GUI
|
5
5
|
# Contains constants and Win32API functions related to window manipulation
|
6
6
|
#
|
7
7
|
module Window
|
@@ -367,7 +367,8 @@ module Win
|
|
367
367
|
#:call-seq:
|
368
368
|
# was_visible = show_window( win_handle, cmd )
|
369
369
|
#
|
370
|
-
function :ShowWindow, [:ulong, :int], :int, boolean: true
|
370
|
+
function :ShowWindow, [:ulong, :int], :int, boolean: true,
|
371
|
+
&->(api, handle, cmd=SW_SHOW) { api.call handle, cmd }
|
371
372
|
|
372
373
|
##
|
373
374
|
# GetWindowThreadProcessId retrieves the identifier of the thread that created the specified window
|
data/lib/win/gui.rb
CHANGED
@@ -5,12 +5,13 @@ require 'win/gui/dialog'
|
|
5
5
|
require 'win/gui/window/window'
|
6
6
|
|
7
7
|
module Win
|
8
|
+
|
8
9
|
# Contains several modules defining Win32 API functions and constants related to Windows GUI (Graphical User Interface)
|
9
10
|
#
|
10
|
-
module
|
11
|
-
include Win::
|
12
|
-
include Win::
|
13
|
-
include Win::
|
14
|
-
include Win::
|
11
|
+
module GUI
|
12
|
+
include Win::GUI::Window
|
13
|
+
include Win::GUI::Input
|
14
|
+
include Win::GUI::Message
|
15
|
+
include Win::GUI::Dialog
|
15
16
|
end
|
16
17
|
end
|
data/lib/win/library.rb
CHANGED
@@ -5,8 +5,9 @@ require 'win/extensions'
|
|
5
5
|
# that also contain related constants and convenience methods. For example, Win::DDE module
|
6
6
|
# contains only functions related to DDE protocol such as DdeInitialize() as well as constants
|
7
7
|
# such as DMLERR_NO_ERROR, APPCLASS_STANDARD, etc. So if you need only DDE-related functions,
|
8
|
-
# there is no need to load all the other modules, clogging your namespaces - just require 'win/dde'
|
9
|
-
# and be done with it. Win is just a top level namespace (container) that holds all the other modules.
|
8
|
+
# there is no need to load all the other modules, clogging your namespaces - just <b> require 'win/dde' </b>
|
9
|
+
# and be done with it. Win is just a top level namespace (container) that holds all the other modules.
|
10
|
+
#
|
10
11
|
module Win
|
11
12
|
|
12
13
|
module Errors # :nodoc:
|
@@ -23,6 +24,7 @@ module Win
|
|
23
24
|
# and declare them using ‘function’ class method (macro) - it does a lot of heavy lifting for you and
|
24
25
|
# can be customized with options and code blocks to give you reusable API wrapper methods with the exact
|
25
26
|
# behavior you need.
|
27
|
+
#
|
26
28
|
module Library
|
27
29
|
|
28
30
|
# Win::Library::API is a wrapper for callable function API object that mimics Win32::API
|
@@ -287,34 +289,34 @@ module Win
|
|
287
289
|
|
288
290
|
##
|
289
291
|
# Defines new method wrappers for Windows API function call:
|
290
|
-
#
|
291
|
-
#
|
292
|
-
#
|
293
|
-
#
|
294
|
-
#
|
295
|
-
#
|
296
|
-
#
|
297
|
-
#
|
298
|
-
#
|
299
|
-
# You may modify default behavior of defined method by providing optional
|
300
|
-
#
|
301
|
-
#
|
302
|
-
#
|
303
|
-
#
|
304
|
-
#
|
305
|
-
#
|
306
|
-
#
|
307
|
-
#
|
308
|
-
#
|
309
|
-
#
|
310
|
-
#
|
311
|
-
#
|
292
|
+
# - Defines method with original (CamelCase) API function name and original signature (matches MSDN description)
|
293
|
+
# - Defines method with snake_case name (converted from CamelCase function name) with enhanced API signature
|
294
|
+
# When defined snake_case method is called, it converts the arguments you provided into ones required by
|
295
|
+
# original API (adding defaults, mute and transitory args as necessary), executes API function call
|
296
|
+
# and (optionally) transforms the result before returning it. If a block is attached to
|
297
|
+
# method invocation, raw result is yielded to this block before final transformation take place
|
298
|
+
# - Defines aliases for enhanced method with more Rubyesque names for getters, setters and tests:
|
299
|
+
# GetWindowText -> window_test, SetWindowText -> window_text=, IsZoomed -> zoomed?
|
300
|
+
# ---
|
301
|
+
# You may modify default behavior of defined method by providing optional *def_block* to function definition.
|
302
|
+
# If you do so, snake_case method is defined based on your *def_block*. It receives callable API
|
303
|
+
# object for function being defined, arguments and (optional) runtime block with which the method
|
304
|
+
# will be called. Results coming from &def_block are then transformed and returned.
|
305
|
+
# So, your *def_block* should specify all the behavior of the method being defined. You can use *def_block* to:
|
306
|
+
# - Change original signature of API function, provide argument defaults, check argument types
|
307
|
+
# - Pack arguments into strings/structs for [in] or [in/out] parameters that expect a pointer
|
308
|
+
# - Allocate buffers/structs for pointers required by API functions [out] parameters
|
309
|
+
# - Unpack [out] and [in/out] parameters returned as pointers
|
310
|
+
# - Explicitly return results of API call that are returned in [out] and [in/out] parameters
|
311
|
+
# - Convert attached runtime blocks into callback functions and stuff them into [in] callback parameters
|
312
|
+
# - do other stuff that you think is appropriate to make Windows API function behavior more Ruby-like...
|
313
|
+
# ---
|
312
314
|
# Accepts following options:
|
313
|
-
#
|
314
|
-
#
|
315
|
-
#
|
316
|
-
#
|
317
|
-
#
|
315
|
+
# :dll:: Use this dll instead of default 'user32'
|
316
|
+
# :rename:: Use this name instead of standard (conventional) function name
|
317
|
+
# :alias(es):: Provides additional alias(es) for defined method
|
318
|
+
# :boolean:: Forces method to return true/false instead of nonzero/zero
|
319
|
+
# :zeronil:: Forces method to return nil if function result is zero
|
318
320
|
#
|
319
321
|
def function(name, params, returns, options={}, &def_block)
|
320
322
|
method_name, effective_names, aliases = generate_names(name, options)
|
@@ -395,6 +397,7 @@ module Win
|
|
395
397
|
##
|
396
398
|
# Wrapper for FFI::Library#callback() that converts Win32/shortcut argument types into FFI-compliant types.
|
397
399
|
# This method overrides FFI.callback which must be aliased to FFI.attach_callback
|
400
|
+
#
|
398
401
|
def callback(name, params, returns)
|
399
402
|
params, returns = generate_signature(params, returns)
|
400
403
|
attach_callback name.to_sym, params, returns
|
@@ -402,8 +405,8 @@ module Win
|
|
402
405
|
|
403
406
|
##
|
404
407
|
# :method: namespace
|
405
|
-
# This method is meta-generated when Win::Library module is included into other module/class
|
406
|
-
# It returns reference to including (host) module for use by Win::Library::API and class methods.
|
408
|
+
# This method is meta-generated when Win::Library module is included into other module/class.
|
409
|
+
# It returns reference to including (host) class/module for use by Win::Library::API and class methods.
|
407
410
|
|
408
411
|
##
|
409
412
|
# Ensures that args count is equal to params count plus diff
|
@@ -421,6 +424,7 @@ module Win
|
|
421
424
|
##
|
422
425
|
# Hook executed when Win::Library is included into class or module. It extends host class/module
|
423
426
|
# with both FFI::Library methods and Win::Library macro methods like 'function'.
|
427
|
+
#
|
424
428
|
def self.included(klass)
|
425
429
|
klass.extend FFI::Library
|
426
430
|
|
data/spec/spec_helper.rb
CHANGED
data/spec/win/dde_spec.rb
CHANGED
@@ -127,6 +127,12 @@ module WinDDETest
|
|
127
127
|
end
|
128
128
|
end
|
129
129
|
|
130
|
+
it 'created different handles for two different strings ' do
|
131
|
+
string_handle1 = dde_create_string_handle(@instance_id, 'My String')
|
132
|
+
string_handle2 = dde_create_string_handle(@instance_id, 'My String1')
|
133
|
+
string_handle1.should_not == string_handle2
|
134
|
+
end
|
135
|
+
|
130
136
|
it 'returns nil if unable to register handle to a string' do
|
131
137
|
string_handle = dde_create_string_handle(@instance_id, "", CP_WINANSI)
|
132
138
|
string_handle.should == nil
|
data/spec/win/gui/dialog_spec.rb
CHANGED
@@ -5,9 +5,9 @@ require 'win/gui/input'
|
|
5
5
|
module WinWindowTest
|
6
6
|
|
7
7
|
include WinTestApp
|
8
|
-
include Win::
|
8
|
+
include Win::GUI::Dialog
|
9
9
|
|
10
|
-
describe Win::
|
10
|
+
describe Win::GUI::Dialog do
|
11
11
|
|
12
12
|
describe '#get_dlg_item' do
|
13
13
|
spec{ use{ control_handle = get_dlg_item(handle = 0, item_id = 1) }}
|
@@ -30,7 +30,7 @@ module WinWindowTest
|
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
-
describe Win::
|
33
|
+
describe Win::GUI::Dialog, ' defines convenience/service methods on top of Windows API' do
|
34
34
|
describe 'dialog' do
|
35
35
|
spec{ use{ dialog( title ='Dialog Title', timeout_sec = 0.001, &any_block) }}
|
36
36
|
|
data/spec/win/gui/input_spec.rb
CHANGED
@@ -5,9 +5,9 @@ require 'win/gui/input'
|
|
5
5
|
module WinWindowTest
|
6
6
|
|
7
7
|
include WinTestApp
|
8
|
-
include Win::
|
8
|
+
include Win::GUI::Input
|
9
9
|
|
10
|
-
describe Win::
|
10
|
+
describe Win::GUI::Input do
|
11
11
|
|
12
12
|
describe '#keydb_event' do
|
13
13
|
spec{ use{ keybd_event(vkey = 0, bscan = 0, flags = 0, extra_info = 0) }}
|
@@ -38,7 +38,7 @@ module WinWindowTest
|
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
|
-
describe Win::
|
41
|
+
describe Win::GUI::Input, ' defines convenience/service methods on top of Windows API' do
|
42
42
|
describe '#keystroke' do
|
43
43
|
spec{ use{ keystroke( vkey = 30, vkey = 30) }}
|
44
44
|
|
@@ -2,12 +2,12 @@ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
|
2
2
|
require 'win/gui/input'
|
3
3
|
#require 'win/gui/window'
|
4
4
|
|
5
|
-
module
|
5
|
+
module WinGUIMessageTest
|
6
6
|
|
7
7
|
include WinTestApp
|
8
|
-
include Win::
|
8
|
+
include Win::GUI::Message
|
9
9
|
|
10
|
-
describe Win::
|
10
|
+
describe Win::GUI::Message do
|
11
11
|
|
12
12
|
describe '#post_message' do
|
13
13
|
spec{ use{ success = PostMessage(handle = 0, msg = 0, w_param = 0, l_param = 0) }}
|
@@ -2,12 +2,12 @@ require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper')
|
|
2
2
|
require 'win/gui/window'
|
3
3
|
require 'win/gui/window/window'
|
4
4
|
|
5
|
-
module
|
5
|
+
module WinGUITest
|
6
6
|
include WinTestApp
|
7
|
-
include Win::
|
8
|
-
include Win::
|
7
|
+
include Win::GUI::Window
|
8
|
+
include Win::GUI::Input
|
9
9
|
|
10
|
-
describe Win::
|
10
|
+
describe Win::GUI::Window::Window, ' thin wrapper class around window handle' do
|
11
11
|
before(:each) { @app = launch_test_app }
|
12
12
|
after(:each){ close_test_app }
|
13
13
|
|
@@ -44,7 +44,7 @@ module WinGuiTest
|
|
44
44
|
start = Time.now
|
45
45
|
@app.close
|
46
46
|
@app.wait_for_close
|
47
|
-
(Time.now - start).should be <= Win::
|
47
|
+
(Time.now - start).should be <= Win::GUI::Window::Window::CLOSE_TIMEOUT
|
48
48
|
window_visible?(@app.handle).should be false
|
49
49
|
end
|
50
50
|
end
|
data/spec/win/gui/window_spec.rb
CHANGED
@@ -4,7 +4,7 @@ require 'win/gui/window'
|
|
4
4
|
module WinWindowTest
|
5
5
|
|
6
6
|
include WinTestApp
|
7
|
-
include Win::
|
7
|
+
include Win::GUI::Window
|
8
8
|
|
9
9
|
def commands_should_show_window *cmds, tests
|
10
10
|
cmds.each do |cmd|
|
@@ -27,7 +27,7 @@ module WinWindowTest
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
-
describe Win::
|
30
|
+
describe Win::GUI::Window, ' defines a set user32 API functions related to Window manipulation' do
|
31
31
|
describe '#window?' do
|
32
32
|
spec{ use{ IsWindow(any_handle) }}
|
33
33
|
spec{ use{ is_window(any_handle) }}
|
@@ -311,13 +311,11 @@ module WinWindowTest
|
|
311
311
|
describe '#show_window ', 'LI', 'I' do
|
312
312
|
spec{ use{ was_visible = show_window(handle = any_handle, cmd = SW_SHOWNA) }}
|
313
313
|
|
314
|
-
it '
|
314
|
+
it 'defaults to SW_SHOW if no command given' do
|
315
315
|
test_app do |app|
|
316
|
-
|
317
|
-
|
318
|
-
visible?(app.handle).should ==
|
319
|
-
hide_window(app.handle).should == false
|
320
|
-
visible?(app.handle).should == false
|
316
|
+
hide_window(app.handle)
|
317
|
+
use{show_window(app.handle)}
|
318
|
+
visible?(app.handle).should == true
|
321
319
|
end
|
322
320
|
end
|
323
321
|
|
@@ -354,7 +352,7 @@ module WinWindowTest
|
|
354
352
|
end
|
355
353
|
|
356
354
|
it 'SW_SHOWMINNOACTIVE, SW_SHOWMINIMIZED displays the window as a minimized foreground window' do
|
357
|
-
commands_should_show_window SW_SHOWMINNOACTIVE, SW_SHOWMINIMIZED,
|
355
|
+
commands_should_show_window SW_SHOWMINNOACTIVE, SW_SHOWMINIMIZED, #!
|
358
356
|
:minimized? => true, :maximized? => false, :visible? => true, :foreground? => true
|
359
357
|
end
|
360
358
|
|
@@ -418,7 +416,7 @@ module WinWindowTest
|
|
418
416
|
|
419
417
|
it 'iterates through all the top-level windows for a given desktop'
|
420
418
|
end
|
421
|
-
|
419
|
+
|
422
420
|
describe '#enum_child_windows' do
|
423
421
|
before(:all){@app = launch_test_app}
|
424
422
|
after(:all){close_test_app}
|
@@ -461,20 +459,24 @@ module WinWindowTest
|
|
461
459
|
end
|
462
460
|
end
|
463
461
|
|
464
|
-
describe Win::
|
462
|
+
describe Win::GUI::Window, ' defines convenience/service methods on top of Windows API' do
|
465
463
|
describe '#foreground' do
|
466
464
|
spec{ use{ foreground?( any_handle) }}
|
467
465
|
end
|
466
|
+
|
468
467
|
describe '#hide_window' do
|
469
|
-
spec{ use{ hide_window(any_handle) }}
|
468
|
+
spec{ use{ was_visible = hide_window(any_handle) }}
|
470
469
|
|
471
|
-
end
|
472
470
|
it 'hides window: same as show_window(handle, SW_HIDE)' do
|
473
471
|
test_app do |app|
|
474
|
-
hide_window(app.handle)
|
472
|
+
was_visible = hide_window(app.handle)
|
473
|
+
was_visible.should == true
|
474
|
+
visible?(app.handle).should == false
|
475
|
+
hide_window(app.handle).should == false
|
475
476
|
visible?(app.handle).should == false
|
476
477
|
end
|
477
478
|
end
|
478
479
|
end
|
480
|
+
end
|
479
481
|
end
|
480
482
|
end
|
data/win.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{win}
|
8
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.11"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["arvicco"]
|
12
|
-
s.date = %q{2010-02-
|
12
|
+
s.date = %q{2010-02-20}
|
13
13
|
s.description = %q{Rubyesque interfaces and wrappers for Windows API functions pre-defined using FFI }
|
14
14
|
s.email = %q{arvitallian@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: win
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- arvicco
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-02-
|
12
|
+
date: 2010-02-20 00:00:00 +03:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|