win 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.rdoc +18 -19
- data/VERSION +1 -1
- data/lib/win/dde.rb +147 -88
- data/lib/win/gui/dialog.rb +35 -1
- data/lib/win/gui/input.rb +128 -93
- data/lib/win/gui/message.rb +365 -5
- data/lib/win/gui/{convenience.rb → window/window.rb} +12 -67
- data/lib/win/gui/window.rb +338 -219
- data/lib/win/gui.rb +1 -2
- data/lib/win/library.rb +0 -2
- data/spec/spec_helper.rb +4 -4
- data/spec/win/gui/dialog_spec.rb +22 -7
- data/spec/win/gui/input_spec.rb +30 -0
- data/spec/win/gui/message_spec.rb +0 -7
- data/spec/win/gui/{convenience_spec.rb → window/window_spec.rb} +13 -61
- data/spec/win/gui/window_spec.rb +30 -4
- data/spec/win/library_spec.rb +0 -27
- data/win.gemspec +5 -5
- metadata +5 -5
data/README.rdoc
CHANGED
@@ -116,41 +116,40 @@ Contributors always welcome!
|
|
116
116
|
== SYNOPSIS
|
117
117
|
=== Using pre-defined Windows API functions:
|
118
118
|
|
119
|
-
|
119
|
+
require 'win/gui'
|
120
120
|
|
121
|
-
|
121
|
+
class MyClass
|
122
122
|
include Win::Gui::Window
|
123
123
|
|
124
124
|
fg_window = foreground_window
|
125
125
|
puts window_text(fg_window)
|
126
126
|
show_window(fg_window) unless minimized?(fg_window)
|
127
127
|
...
|
128
|
-
|
128
|
+
end
|
129
129
|
|
130
130
|
=== Defining your own Windows API functions:
|
131
131
|
|
132
|
-
|
132
|
+
require 'win/library'
|
133
133
|
|
134
|
-
|
135
|
-
|
134
|
+
module YourLibModule
|
135
|
+
include Win::Library
|
136
136
|
|
137
|
-
|
138
|
-
|
137
|
+
# Customizing even further: your own method extension in attached block
|
138
|
+
function :GetWindowText, [ :ulong, :pointer, :int ], :int do |api, handle|
|
139
|
+
buffer = FFI::MemoryPointer.new :char, 512
|
140
|
+
buffer.put_string(0, "\x00" * 511)
|
141
|
+
num_chars = api.call(handle, buffer, 512)
|
142
|
+
num_chars == 0 ? nil : buffer.get_bytes(0, num_chars)
|
143
|
+
end
|
139
144
|
|
140
|
-
|
141
|
-
|
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)
|
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
147
|
end
|
148
|
-
end
|
149
148
|
|
150
|
-
|
149
|
+
include YourLibModule
|
151
150
|
|
152
|
-
|
153
|
-
|
151
|
+
handle = my_find(nil, 'cmd') # find any shell window
|
152
|
+
puts handle, window_text(handle) # print shell window handle and title
|
154
153
|
|
155
154
|
== PRIOR ART:
|
156
155
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.2
|
data/lib/win/dde.rb
CHANGED
@@ -100,84 +100,141 @@ module Win
|
|
100
100
|
# The RegisterClipboardFormat function registers a new clipboard format.
|
101
101
|
# This format can then be used as a valid clipboard format.
|
102
102
|
#
|
103
|
-
# Syntax
|
103
|
+
# [*Syntax*] UINT RegisterClipboardFormat( LPCTSTR lpszFormat )
|
104
104
|
#
|
105
|
-
#
|
106
|
-
# format_name (P) - [in] Pointer to a null-terminated string that names the new format.
|
105
|
+
# lpszFormat:: [in] Pointer to a null-terminated string that names the new format.
|
107
106
|
#
|
108
|
-
# Returns:
|
109
|
-
#
|
110
|
-
#
|
111
|
-
#
|
112
|
-
#
|
113
|
-
#
|
114
|
-
#
|
115
|
-
#
|
116
|
-
#
|
117
|
-
#
|
118
|
-
# form of an HGLOBAL value.
|
107
|
+
# *Returns*:: :uint or nil. If the function succeeds, the return value identifies the registered clipboard format.
|
108
|
+
# If the function fails, the return value is *nil*(not zero). For error info, call GetLastError.
|
109
|
+
# ---
|
110
|
+
# *Remarks*:
|
111
|
+
# If a registered format with the specified name already exists, a new format is not registered and the
|
112
|
+
# return value identifies the existing format. This enables more than one application to copy and paste
|
113
|
+
# data using the same registered clipboard format. Note that the comparison is case-insensitive.
|
114
|
+
# Registered clipboard formats are identified by values in the range 0xC000 through 0xFFFF.
|
115
|
+
# When registered clipboard formats are placed on or retrieved from the clipboard, they must be in the
|
116
|
+
# form of an HGLOBAL value.
|
119
117
|
#
|
120
118
|
# :call-seq:
|
121
|
-
#
|
119
|
+
# register_clipboard_format( format_name )
|
122
120
|
#
|
123
|
-
function
|
121
|
+
function :RegisterClipboardFormat, [:pointer], :uint, zeronil: true
|
124
122
|
|
125
|
-
|
126
|
-
#
|
127
|
-
#
|
128
|
-
|
123
|
+
##
|
124
|
+
# The DdeCallback function is an application-defined callback function used with the Dynamic Data Exchange
|
125
|
+
# Management Library (DDEML) functions. It processes Dynamic Data Exchange (DDE) transactions. The PFNCALLBACK
|
126
|
+
# type defines a pointer to this callback function. DdeCallback is a placeholder for the application-defined
|
127
|
+
# function name.
|
128
|
+
#
|
129
|
+
# [*Syntax*] HDDEDATA CALLBACK DdeCallback( UINT uType, UINT uFmt, HCONV hconv, HDDEDATA hsz1, HDDEDATA hsz2,
|
130
|
+
# HDDEDATA hdata, HDDEDATA dwData1, HDDEDATA dwData2);
|
131
|
+
# uType:: [in] Specifies the type of the current transaction. This parameter consists of a combination of
|
132
|
+
# transaction class flags and transaction type flags. The following table describes each of the
|
133
|
+
# transaction classes and provides a list of the transaction types in each class. For information
|
134
|
+
# about a specific transaction type, see the individual description of that type.
|
135
|
+
# - XCLASS_BOOL - A DDE callback function should return TRUE or FALSE when it finishes processing a
|
136
|
+
# transaction that belongs to this class. The XCLASS_BOOL class consists of the following types:
|
137
|
+
# - XTYP_ADVSTART
|
138
|
+
# - XTYP_CONNECT
|
139
|
+
# - XCLASS_DATA - A DDE callback function should return a DDE handle, the CBR_BLOCK return code, or
|
140
|
+
# NULL when it finishes processing a transaction that belongs to this class. The XCLASS_DATA
|
141
|
+
# transaction class consists of the following types:
|
142
|
+
# - XTYP_ADVREQ
|
143
|
+
# - XTYP_REQUEST
|
144
|
+
# - XTYP_WILDCONNECT
|
145
|
+
# - XCLASS_FLAGS - A DDE callback function should return DDE_FACK, DDE_FBUSY, or DDE_FNOTPROCESSED
|
146
|
+
# when it finishes processing a transaction that belongs to this class. The XCLASS_FLAGS transaction
|
147
|
+
# class consists of the following types:
|
148
|
+
# - XTYP_ADVDATA
|
149
|
+
# - XTYP_EXECUTE
|
150
|
+
# - XTYP_POKE
|
151
|
+
# - XCLASS_NOTIFICATION - The transaction types that belong to this class are for notification purposes
|
152
|
+
# only. The return value from the callback function is ignored. The XCLASS_NOTIFICATION transaction
|
153
|
+
# class consists of the following types:
|
154
|
+
# - XTYP_ADVSTOP
|
155
|
+
# - XTYP_CONNECT_CONFIRM
|
156
|
+
# - XTYP_DISCONNECT
|
157
|
+
# - XTYP_ERROR
|
158
|
+
# - XTYP_MONITOR
|
159
|
+
# - XTYP_REGISTER
|
160
|
+
# - XTYP_XACT_COMPLETE
|
161
|
+
# - XTYP_UNREGISTER
|
162
|
+
# uFmt:: [in] Specifies the format in which data is sent or received.
|
163
|
+
# hconv:: [in] Handle to the conversation associated with the current transaction.
|
164
|
+
# hsz1:: [in] Handle to a string. The meaning of this parameter depends on the type of the current transaction.
|
165
|
+
# For the meaning of this parameter, see the description of the transaction type.
|
166
|
+
# hsz2:: [in] Handle to a string. The meaning of this parameter depends on the type of the current transaction.
|
167
|
+
# For the meaning of this parameter, see the description of the transaction type.
|
168
|
+
# hdata:: [in] Handle to DDE data. The meaning of this parameter depends on the type of the current transaction.
|
169
|
+
# For the meaning of this parameter, see the description of the transaction type.
|
170
|
+
# dwData1:: [in] Specifies transaction-specific data. For the meaning, see the description of the transaction type.
|
171
|
+
# dwData2:: [in] Specifies transaction-specific data. For the meaning, see the description of the transaction type.
|
172
|
+
# *Returns*:: The return value depends on the transaction class. For more information about the return values,
|
173
|
+
# see descriptions of the individual transaction types.
|
174
|
+
# ---
|
175
|
+
# *Remarks*:
|
176
|
+
# - The callback function is called asynchronously for transactions that do not involve the creation or termination
|
177
|
+
# of conversations. An application that does not frequently accept incoming messages will have reduced DDE
|
178
|
+
# performance because the Dynamic Data Exchange Management Library (DDEML) uses messages to initiate transactions.
|
179
|
+
# - An application must register the callback function by specifying a pointer to the function in a call to the
|
180
|
+
# DdeInitialize function.
|
181
|
+
#
|
182
|
+
# :call-seq:
|
183
|
+
# DdeCallback block: {|type, format, hconv, hsz1, hsz2, hdata, data1, data2| your code }
|
184
|
+
#
|
185
|
+
callback :DdeCallback, [:uint, :uint, :HCONV, :HDDEDATA, :HDDEDATA, :HDDEDATA, :HDDEDATA, :HDDEDATA], :HDDEDATA
|
129
186
|
|
130
187
|
##
|
131
188
|
# The DdeInitialize function registers an application with the Dynamic Data Exchange Management Library (DDEML).
|
132
189
|
# An application must call this function before calling any other DDEML function.
|
133
190
|
#
|
134
|
-
# Syntax
|
135
|
-
#
|
136
|
-
#
|
137
|
-
#
|
138
|
-
#
|
139
|
-
#
|
140
|
-
#
|
141
|
-
#
|
142
|
-
#
|
143
|
-
#
|
144
|
-
#
|
145
|
-
#
|
146
|
-
#
|
147
|
-
#
|
148
|
-
#
|
149
|
-
#
|
150
|
-
#
|
151
|
-
#
|
152
|
-
#
|
153
|
-
#
|
154
|
-
#
|
155
|
-
#
|
156
|
-
#
|
157
|
-
#
|
158
|
-
#
|
159
|
-
#
|
160
|
-
#
|
161
|
-
#
|
162
|
-
#
|
163
|
-
#
|
164
|
-
#
|
165
|
-
#
|
166
|
-
#
|
167
|
-
#
|
168
|
-
#
|
169
|
-
#
|
170
|
-
#
|
171
|
-
#
|
172
|
-
#
|
173
|
-
#
|
174
|
-
#
|
175
|
-
# and the default value for the iCodePage member of the CONVCONTEXT structure (CP_WINANSI or CP_WINUNICODE).
|
191
|
+
# [*Syntax*] UINT DdeInitialize( LPDWORD pidInst, PFNCALLBACK pfnCallback, DWORD afCmd, DWORD ulRes );
|
192
|
+
#
|
193
|
+
# pidInst:: [in, out] Pointer to the application instance identifier.
|
194
|
+
# At initialization, this parameter should point to 0. If the function succeeds, this parameter points
|
195
|
+
# to the instance identifier for the application. This value should be passed as the idInst parameter
|
196
|
+
# in all other DDEML functions that require it. If an application uses multiple instances of the DDEML
|
197
|
+
# dynamic-link library (DLL), the application should provide a different callback function for each
|
198
|
+
# instance. If pidInst points to a nonzero value, reinitialization of the DDEML is implied. In this
|
199
|
+
# case, pidInst must point to a valid application-instance identifier.
|
200
|
+
# pfnCallback:: Pointer to the application-defined Dynamic Data Exchange DdeCallback function. This function
|
201
|
+
# processes DDE transactions sent by the system. For more information, see the DdeCallback.
|
202
|
+
# afCmd:: [in] Specifies a set of APPCMD_, CBF_, and MF_ flags. The APPCMD_ flags provide special
|
203
|
+
# instructions to DdeInitialize. The CBF_ flags specify filters that prevent specific types of transactions
|
204
|
+
# from reaching the callback function. The MF_ flags specify the types of DDE activity that a DDE monitoring
|
205
|
+
# application monitors. Using these flags enhances the performance of a DDE application by eliminating
|
206
|
+
# unnecessary calls to the callback function. This parameter can be one or more of the following values:
|
207
|
+
# APPCLASS_MONITOR, APPCLASS_STANDARD, APPCMD_CLIENTONLY, APPCMD_FILTERINITS;
|
208
|
+
# CBF_FAIL_ALLSVRXACTIONS, CBF_FAIL_ADVISES, CBF_FAIL_CONNECTIONS, CBF_FAIL_EXECUTES, CBF_FAIL_POKES
|
209
|
+
# CBF_FAIL_REQUESTS, CBF_FAIL_SELFCONNECTIONS, CBF_SKIP_ALLNOTIFICATIONS, CBF_SKIP_CONNECT_CONFIRMS
|
210
|
+
# CBF_SKIP_DISCONNECTS, CBF_SKIP_REGISTRATIONS, CBF_SKIP_UNREGISTRATIONS;
|
211
|
+
# MF_CALLBACKS, MF_CONV, MF_ERRORS, MF_HSZ_INFO, MF_LINKS, MF_POSTMSGS, MF_SENDMSGS
|
212
|
+
# ulRes:: Reserved; must be set to zero.
|
213
|
+
#
|
214
|
+
# *Returns*:: If the function succeeds, the return value is DMLERR_NO_ERROR. If the function fails, the return
|
215
|
+
# value is one of the following values:
|
216
|
+
# - DMLERR_DLL_USAGE
|
217
|
+
# - DMLERR_INVALIDPARAMETER
|
218
|
+
# - DMLERR_SYS_ERROR
|
219
|
+
# ---
|
220
|
+
# *Remarks*:
|
221
|
+
# - An application that uses multiple instances of the DDEML must not pass DDEML objects between instances.
|
222
|
+
# - A DDE monitoring application should not attempt to perform DDE operations (establish conversations,
|
223
|
+
# issue transactions, and so on) within the context of the same application instance.
|
224
|
+
# - A synchronous transaction fails with a DMLERR_REENTRANCY error if any instance of the same task has
|
225
|
+
# a synchronous transaction already in progress.
|
226
|
+
# - The CBF_FAIL_ALLSVRXACTIONS flag causes the DDEML to filter all server transactions and can be changed
|
227
|
+
# by a subsequent call to DdeInitialize. The APPCMD_CLIENTONLY flag prevents the DDEML from creating key
|
228
|
+
# resources for the server and cannot be changed by a subsequent call to DdeInitialize.
|
229
|
+
# - There is an ANSI version and a Unicode version of DdeInitialize. The version called determines the
|
230
|
+
# type of the window procedures used to control DDE conversations (ANSI or Unicode), and the default
|
231
|
+
# value for the iCodePage member of the CONVCONTEXT structure (CP_WINANSI or CP_WINUNICODE).
|
176
232
|
#
|
177
233
|
# :call-seq:
|
178
|
-
#
|
234
|
+
# instance_id, status = dde_initialize( instance_id = 0, cmd )
|
235
|
+
# {|type, format, hconv, hsz1, hsz2, hdata, data1, data2| your dde_callback block}
|
179
236
|
#
|
180
|
-
function
|
237
|
+
function :DdeInitialize, [:pointer, :DdeCallback, :DWORD, :DWORD], :uint,
|
181
238
|
&->(api, old_id=0, cmd, &block){
|
182
239
|
raise ArgumentError, 'No callback block' unless block
|
183
240
|
id = FFI::MemoryPointer.new(:long)
|
@@ -192,30 +249,32 @@ module Win
|
|
192
249
|
# A Dynamic Data Exchange (DDE) client or server application can pass the string handle as a
|
193
250
|
# parameter to other Dynamic Data Exchange Management Library (DDEML) functions.
|
194
251
|
#
|
195
|
-
# Syntax
|
196
|
-
#
|
197
|
-
#
|
198
|
-
#
|
199
|
-
#
|
200
|
-
#
|
201
|
-
#
|
202
|
-
#
|
203
|
-
#
|
204
|
-
#
|
205
|
-
#
|
206
|
-
#
|
207
|
-
#
|
208
|
-
#
|
209
|
-
#
|
210
|
-
#
|
211
|
-
#
|
212
|
-
#
|
213
|
-
#
|
214
|
-
#
|
215
|
-
#
|
216
|
-
#
|
217
|
-
#
|
218
|
-
|
252
|
+
# [*Syntax*] HSZ DdeCreateStringHandle( DWORD idInst, LPTSTR psz, int iCodePage );
|
253
|
+
#
|
254
|
+
# idInst:: [in] Specifies the application instance identifier obtained by a previous call to the
|
255
|
+
# DdeInitialize function.
|
256
|
+
# psz:: [in] Pointer to a buffer that contains the null-terminated string for which a handle
|
257
|
+
# is to be created. This string can be up to 255 characters. The reason for this limit is that
|
258
|
+
# DDEML string management functions are implemented using global atoms.
|
259
|
+
# iCodePage:: [in] Specifies the code page used to render the string. This value should be either
|
260
|
+
# CP_WINANSI (the default code page) or CP_WINUNICODE, depending on whether the ANSI or Unicode
|
261
|
+
# version of DdeInitialize was called by the client application.
|
262
|
+
#
|
263
|
+
# *Returns*:: (L) or nil: If the function succeeds, the return value is a string handle.
|
264
|
+
# If the function fails, the return value is 0(changed to nil in enhanced version).
|
265
|
+
# The DdeGetLastError function can be used to get the error code, which can be one of the
|
266
|
+
# following values: DMLERR_NO_ERROR, DMLERR_INVALIDPARAMETER, DMLERR_SYS_ERROR
|
267
|
+
# ---
|
268
|
+
# *Remarks*: The value of a string handle is not related to the case of the string it identifies.
|
269
|
+
# When an application either creates a string handle or receives one in the callback function
|
270
|
+
# and then uses the DdeKeepStringHandle function to keep it, the application must free that string
|
271
|
+
# handle when it is no longer needed. An instance-specific string handle cannot be mapped from string
|
272
|
+
# handle to string and back to string handle.
|
273
|
+
#
|
274
|
+
# :call-seq:
|
275
|
+
# string_handle = dde_create_string_handle( instance_id, string, code_page_id )
|
276
|
+
#
|
277
|
+
function :DdeCreateStringHandle, [:DWORD, :pointer, :int], :HSZ, zeronil: true
|
219
278
|
|
220
279
|
end
|
221
280
|
end
|
data/lib/win/gui/dialog.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'win/library'
|
2
|
+
require 'win/gui/window'
|
2
3
|
|
3
4
|
module Win
|
4
5
|
module Gui
|
@@ -6,8 +7,41 @@ module Win
|
|
6
7
|
#
|
7
8
|
module Dialog
|
8
9
|
include Win::Library
|
10
|
+
include Win::Gui::Window
|
9
11
|
|
10
|
-
|
12
|
+
# The GetDlgItem function retrieves a handle to a control in the specified dialog box.
|
13
|
+
#
|
14
|
+
# [*Syntax*] HWND GetDlgItem( HWND hDlg, int nIDDlgItem );
|
15
|
+
#
|
16
|
+
# hDlg:: [in] Handle to the dialog box that contains the control.
|
17
|
+
# nIDDlgItem:: [in] Specifies the identifier of the control to be retrieved.
|
18
|
+
# *Returns*:: If the function succeeds, the return value is the window handle of the specified control.
|
19
|
+
# If the function fails, the return value is NULL, indicating an invalid dialog box handle
|
20
|
+
# or a nonexistent control. To get extended error information, call GetLastError.
|
21
|
+
# ---
|
22
|
+
# *Remarks*:
|
23
|
+
# You can use the GetDlgItem function with any parent-child window pair, not just with dialog boxes.
|
24
|
+
# As long as the hDlg parameter specifies a parent window and the child window has a unique identifier
|
25
|
+
# (as specified by the hMenu parameter in the CreateWindow or CreateWindowEx function that created the
|
26
|
+
# child window), GetDlgItem returns a valid handle to the child window.
|
27
|
+
#
|
28
|
+
# :call-seq:
|
29
|
+
# control_handle = [get_]dlg_item( dialog_handle, id )
|
30
|
+
#
|
31
|
+
function :GetDlgItem, [:ulong, :int], :ulong
|
32
|
+
|
33
|
+
# Convenience methods:
|
34
|
+
|
35
|
+
# finds top-level dialog window by title and yields found dialog window to block if given
|
36
|
+
def dialog(title, seconds=3)
|
37
|
+
d = begin
|
38
|
+
win = Window::Window.top_level(title, seconds)
|
39
|
+
yield(win) ? win : nil
|
40
|
+
rescue TimeoutError
|
41
|
+
end
|
42
|
+
d.wait_for_close if d
|
43
|
+
return d
|
44
|
+
end
|
11
45
|
end
|
12
46
|
end
|
13
47
|
end
|