win 0.0.4 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +12 -13
- data/Rakefile +3 -2
- data/VERSION +1 -1
- data/lib/win/dde.rb +223 -0
- data/lib/win/library.rb +162 -151
- data/lib/win/window/extra.rb +113 -0
- data/lib/win/window.rb +280 -222
- data/spec/spec_helper.rb +15 -7
- data/spec/win/dde_spec.rb +68 -0
- data/spec/win/window/extra_spec.rb +181 -0
- data/spec/win/window_spec.rb +232 -5
- data/win.gemspec +13 -4
- metadata +20 -4
data/lib/win/library.rb
CHANGED
@@ -64,128 +64,132 @@ module Win
|
|
64
64
|
alias_method :[], :call
|
65
65
|
end
|
66
66
|
|
67
|
-
# Contains class methods (macros)
|
67
|
+
# Contains class methods (macros) that can be used in any module mixing in Win::Library
|
68
68
|
module ClassMethods
|
69
|
+
|
70
|
+
# Mapping of Windows API types and one-letter shortcuts into FFI types.
|
71
|
+
# Like :ATOM => :ushort, :LPARAM => :long, :c => :char, :i => :int
|
69
72
|
TYPES = {
|
70
73
|
# FFI type shortcuts
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
#
|
76
|
-
#
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
#
|
84
|
-
#
|
85
|
-
|
86
|
-
|
87
|
-
#
|
88
|
-
#
|
89
|
-
#
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
#For
|
97
|
-
#
|
98
|
-
# :
|
74
|
+
C: :uchar, #– 8-bit unsigned character (byte)
|
75
|
+
c: :char, # 8-bit character (byte)
|
76
|
+
# :int8 – 8-bit signed integer
|
77
|
+
# :uint8 – 8-bit unsigned integer
|
78
|
+
S: :ushort, # – 16-bit unsigned integer (Win32API: used for string)
|
79
|
+
s: :short, # – 16-bit signed integer
|
80
|
+
# :uint16 – 16-bit unsigned integer
|
81
|
+
# :int16 – 16-bit signed integer
|
82
|
+
I: :uint, # 32-bit unsigned integer
|
83
|
+
i: :int, # 32-bit signed integer
|
84
|
+
# :uint32 – 32-bit unsigned integer
|
85
|
+
# :int32 – 32-bit signed integer
|
86
|
+
L: :ulong, # unsigned long int – platform-specific size
|
87
|
+
l: :long, # long int – platform-specific size. For discussion of platforms, see:
|
88
|
+
# (http://groups.google.com/group/ruby-ffi/browse_thread/thread/4762fc77130339b1)
|
89
|
+
# :int64 – 64-bit signed integer
|
90
|
+
# :uint64 – 64-bit unsigned integer
|
91
|
+
# :long_long – 64-bit signed integer
|
92
|
+
# :ulong_long – 64-bit unsigned integer
|
93
|
+
F: :float, # 32-bit floating point
|
94
|
+
D: :double, # 64-bit floating point (double-precision)
|
95
|
+
P: :pointer, # pointer – platform-specific size
|
96
|
+
p: :string, # C-style (NULL-terminated) character string (Win32API: S)
|
97
|
+
B: :bool, # (?? 1 byte in C++)
|
98
|
+
V: :void, # For functions that return nothing (return type void).
|
99
|
+
v: :void, # For functions that return nothing (return type void).
|
100
|
+
# For function argument type only:
|
101
|
+
# :buffer_in – Similar to :pointer, but optimized for Buffers that the function can only read (not write).
|
102
|
+
# :buffer_out – Similar to :pointer, but optimized for Buffers that the function can only write (not read).
|
99
103
|
# :buffer_inout – Similar to :pointer, but may be optimized for Buffers.
|
100
|
-
# :varargs
|
104
|
+
# :varargs – Variable arguments
|
101
105
|
|
102
106
|
# Windows-specific typedefs:
|
103
107
|
ATOM: :ushort, # Atom ~= Symbol: Atom table stores strings and corresponding identifiers. Application
|
104
|
-
|
105
|
-
|
106
|
-
|
108
|
+
# places a string in an atom table and receives a 16-bit integer, called an atom, that
|
109
|
+
# can be used to access the string. Placed string is called an atom name.
|
110
|
+
# See: http://msdn.microsoft.com/en-us/library/ms648708%28VS.85%29.aspx
|
107
111
|
BOOL: :bool,
|
108
112
|
BOOLEAN: :bool,
|
109
|
-
BYTE: :uchar,
|
113
|
+
BYTE: :uchar, # Byte (8 bits). Declared as unsigned char
|
110
114
|
#CALLBACK: K, # Win32.API gem-specific ?? MSDN: #define CALLBACK __stdcall
|
111
|
-
CHAR: :char,
|
115
|
+
CHAR: :char, # 8-bit Windows (ANSI) character. See http://msdn.microsoft.com/en-us/library/dd183415%28VS.85%29.aspx
|
112
116
|
COLORREF: :uint32, # Red, green, blue (RGB) color value (32 bits). See COLORREF for more info.
|
113
117
|
DWORD: :uint32, # 32-bit unsigned integer. The range is 0 through 4,294,967,295 decimal.
|
114
118
|
DWORDLONG: :uint64, # 64-bit unsigned integer. The range is 0 through 18,446,744,073,709,551,615 decimal.
|
115
|
-
DWORD_PTR: :ulong,
|
116
|
-
|
117
|
-
|
119
|
+
DWORD_PTR: :ulong, # Unsigned long type for pointer precision. Use when casting a pointer to a long type
|
120
|
+
# to perform pointer arithmetic. (Also commonly used for general 32-bit parameters that have
|
121
|
+
# been extended to 64 bits in 64-bit Windows.) BaseTsd.h: #typedef ULONG_PTR DWORD_PTR;
|
118
122
|
DWORD32: :uint32,
|
119
123
|
DWORD64: :uint64,
|
120
|
-
HALF_PTR: :int,
|
121
|
-
|
122
|
-
HACCEL: :ulong,
|
123
|
-
|
124
|
-
HANDLE: :ulong,
|
125
|
-
HBITMAP: :ulong,
|
126
|
-
HBRUSH: :ulong,
|
127
|
-
HCOLORSPACE: :ulong
|
128
|
-
HCURSOR: :ulong,
|
129
|
-
HCONV: :ulong,
|
130
|
-
HCONVLIST: :ulong,
|
131
|
-
HDDEDATA: :ulong,
|
132
|
-
HDC: :ulong,
|
133
|
-
HDESK: :ulong,
|
134
|
-
HDROP: :ulong,
|
135
|
-
HDWP: :ulong,
|
136
|
-
HENHMETAFILE: :ulong
|
137
|
-
HFILE: :uint,
|
138
|
-
|
139
|
-
HFONT: :ulong,
|
140
|
-
HGDIOBJ: :ulong,
|
141
|
-
HGLOBAL: :ulong,
|
142
|
-
HHOOK: :ulong,
|
143
|
-
HICON: :ulong,
|
144
|
-
HINSTANCE: :ulong,
|
145
|
-
|
146
|
-
HKEY: :ulong,
|
147
|
-
HKL: :ulong,
|
148
|
-
HLOCAL: :ulong,
|
149
|
-
HMENU: :ulong,
|
150
|
-
HMETAFILE: :ulong,
|
151
|
-
HMODULE: :ulong,
|
152
|
-
HMONITOR: :ulong,
|
153
|
-
HPALETTE: :ulong,
|
154
|
-
HPEN: :ulong,
|
155
|
-
HRESULT: :long,
|
156
|
-
|
157
|
-
HRGN: :ulong,
|
158
|
-
HRSRC: :ulong,
|
159
|
-
HSZ: :ulong,
|
160
|
-
HWINSTA: :ulong,
|
161
|
-
HWND: :ulong,
|
162
|
-
INT: :int,
|
163
|
-
INT_PTR: :int,
|
164
|
-
|
165
|
-
|
166
|
-
INT32: :int32,
|
167
|
-
INT64: :int64,
|
124
|
+
HALF_PTR: :int, # Half the size of a pointer. Use within a structure that contains a pointer and two small fields.
|
125
|
+
# BaseTsd.h: #ifdef (_WIN64) typedef int HALF_PTR; #else typedef short HALF_PTR;
|
126
|
+
HACCEL: :ulong, # (L) Handle to an accelerator table. WinDef.h: #typedef HANDLE HACCEL;
|
127
|
+
# See http://msdn.microsoft.com/en-us/library/ms645526%28VS.85%29.aspx
|
128
|
+
HANDLE: :ulong, # (L) Handle to an object. WinNT.h: #typedef PVOID HANDLE;
|
129
|
+
HBITMAP: :ulong, # (L) Handle to a bitmap: http://msdn.microsoft.com/en-us/library/dd183377%28VS.85%29.aspx
|
130
|
+
HBRUSH: :ulong, # (L) Handle to a brush. http://msdn.microsoft.com/en-us/library/dd183394%28VS.85%29.aspx
|
131
|
+
HCOLORSPACE: :ulong, # (L) Handle to a color space. http://msdn.microsoft.com/en-us/library/ms536546%28VS.85%29.aspx
|
132
|
+
HCURSOR: :ulong, # (L) Handle to a cursor. http://msdn.microsoft.com/en-us/library/ms646970%28VS.85%29.aspx
|
133
|
+
HCONV: :ulong, # (L) Handle to a dynamic data exchange (DDE) conversation.
|
134
|
+
HCONVLIST: :ulong, # (L) Handle to a DDE conversation list. HANDLE - L ?
|
135
|
+
HDDEDATA: :ulong, # (L) Handle to DDE data (structure?)
|
136
|
+
HDC: :ulong, # (L) Handle to a device context (DC). http://msdn.microsoft.com/en-us/library/dd183560%28VS.85%29.aspx
|
137
|
+
HDESK: :ulong, # (L) Handle to a desktop. http://msdn.microsoft.com/en-us/library/ms682573%28VS.85%29.aspx
|
138
|
+
HDROP: :ulong, # (L) Handle to an internal drop structure.
|
139
|
+
HDWP: :ulong, # (L) Handle to a deferred window position structure.
|
140
|
+
HENHMETAFILE: :ulong, #(L) Handle to an enhanced metafile. http://msdn.microsoft.com/en-us/library/dd145051%28VS.85%29.aspx
|
141
|
+
HFILE: :uint, # (I) Special file handle to a file opened by OpenFile, not CreateFile.
|
142
|
+
# WinDef.h: #typedef int HFILE;
|
143
|
+
HFONT: :ulong, # (L) Handle to a font. http://msdn.microsoft.com/en-us/library/dd162470%28VS.85%29.aspx
|
144
|
+
HGDIOBJ: :ulong, # (L) Handle to a GDI object.
|
145
|
+
HGLOBAL: :ulong, # (L) Handle to a global memory block.
|
146
|
+
HHOOK: :ulong, # (L) Handle to a hook. http://msdn.microsoft.com/en-us/library/ms632589%28VS.85%29.aspx
|
147
|
+
HICON: :ulong, # (L) Handle to an icon. http://msdn.microsoft.com/en-us/library/ms646973%28VS.85%29.aspx
|
148
|
+
HINSTANCE: :ulong, # (L) Handle to an instance. This is the base address of the module in memory.
|
149
|
+
# HMODULE and HINSTANCE are the same today, but were different in 16-bit Windows.
|
150
|
+
HKEY: :ulong, # (L) Handle to a registry key.
|
151
|
+
HKL: :ulong, # (L) Input locale identifier.
|
152
|
+
HLOCAL: :ulong, # (L) Handle to a local memory block.
|
153
|
+
HMENU: :ulong, # (L) Handle to a menu. http://msdn.microsoft.com/en-us/library/ms646977%28VS.85%29.aspx
|
154
|
+
HMETAFILE: :ulong, # (L) Handle to a metafile. http://msdn.microsoft.com/en-us/library/dd145051%28VS.85%29.aspx
|
155
|
+
HMODULE: :ulong, # (L) Handle to an instance. Same as HINSTANCE today, but was different in 16-bit Windows.
|
156
|
+
HMONITOR: :ulong, # (L) Рandle to a display monitor. WinDef.h: if(WINVER >= 0x0500) typedef HANDLE HMONITOR;
|
157
|
+
HPALETTE: :ulong, # (L) Handle to a palette.
|
158
|
+
HPEN: :ulong, # (L) Handle to a pen. http://msdn.microsoft.com/en-us/library/dd162786%28VS.85%29.aspx
|
159
|
+
HRESULT: :long, # Return code used by COM interfaces. For more info, Structure of the COM Error Codes.
|
160
|
+
# To test an HRESULT value, use the FAILED and SUCCEEDED macros.
|
161
|
+
HRGN: :ulong, # (L) Handle to a region. http://msdn.microsoft.com/en-us/library/dd162913%28VS.85%29.aspx
|
162
|
+
HRSRC: :ulong, # (L) Handle to a resource.
|
163
|
+
HSZ: :ulong, # (L) Handle to a DDE string.
|
164
|
+
HWINSTA: :ulong, # (L) Handle to a window station. http://msdn.microsoft.com/en-us/library/ms687096%28VS.85%29.aspx
|
165
|
+
HWND: :ulong, # (L) Handle to a window. http://msdn.microsoft.com/en-us/library/ms632595%28VS.85%29.aspx
|
166
|
+
INT: :int, # 32-bit signed integer. The range is -2147483648 through 2147483647 decimal.
|
167
|
+
INT_PTR: :int, # Signed integer type for pointer precision. Use when casting a pointer to an integer
|
168
|
+
# to perform pointer arithmetic. BaseTsd.h:
|
169
|
+
#if defined(_WIN64) typedef __int64 INT_PTR; #else typedef int INT_PTR;
|
170
|
+
INT32: :int32, # 32-bit signed integer. The range is -2,147,483,648 through +...647 decimal.
|
171
|
+
INT64: :int64, # 64-bit signed integer. The range is –9,223,372,036,854,775,808 through +...807
|
168
172
|
LANGID: :ushort, # Language identifier. For more information, see Locales. WinNT.h: #typedef WORD LANGID;
|
169
|
-
|
173
|
+
# See http://msdn.microsoft.com/en-us/library/dd318716%28VS.85%29.aspx
|
170
174
|
LCID: :uint32, # Locale identifier. For more information, see Locales.
|
171
175
|
LCTYPE: :uint32, # Locale information type. For a list, see Locale Information Constants.
|
172
176
|
LGRPID: :uint32, # Language group identifier. For a list, see EnumLanguageGroupLocales.
|
173
|
-
LONG: :long,
|
174
|
-
LONG32: :long,
|
175
|
-
LONG64: :int64,
|
176
|
-
LONGLONG: :int64,
|
177
|
-
LONG_PTR: :long,
|
178
|
-
|
179
|
-
|
180
|
-
LPARAM: :long,
|
181
|
-
LPBOOL: :pointer,
|
182
|
-
LPBYTE: :pointer,
|
183
|
-
LPCOLORREF: :pointer
|
184
|
-
LPCSTR: :pointer,
|
185
|
-
|
186
|
-
LPCTSTR: :pointer,
|
187
|
-
LPCVOID: :pointer,
|
188
|
-
LPCWSTR: :pointer,
|
177
|
+
LONG: :long, # 32-bit signed integer. The range is -2,147,483,648 through +...647 decimal.
|
178
|
+
LONG32: :long, # 32-bit signed integer. The range is -2,147,483,648 through +...647 decimal.
|
179
|
+
LONG64: :int64, # 64-bit signed integer. The range is –9,223,372,036,854,775,808 through +...807
|
180
|
+
LONGLONG: :int64, # 64-bit signed integer. The range is –9,223,372,036,854,775,808 through +...807
|
181
|
+
LONG_PTR: :long, # Signed long type for pointer precision. Use when casting a pointer to a long to
|
182
|
+
# perform pointer arithmetic. BaseTsd.h:
|
183
|
+
#if defined(_WIN64) typedef __int64 LONG_PTR; #else typedef long LONG_PTR;
|
184
|
+
LPARAM: :long, # Message parameter. WinDef.h as follows: #typedef LONG_PTR LPARAM;
|
185
|
+
LPBOOL: :pointer, # Pointer to a BOOL. WinDef.h as follows: #typedef BOOL far *LPBOOL;
|
186
|
+
LPBYTE: :pointer, # Pointer to a BYTE. WinDef.h as follows: #typedef BYTE far *LPBYTE;
|
187
|
+
LPCOLORREF: :pointer, # Pointer to a COLORREF value. WinDef.h as follows: #typedef DWORD *LPCOLORREF;
|
188
|
+
LPCSTR: :pointer, # Pointer to a constant null-terminated string of 8-bit Windows (ANSI) characters.
|
189
|
+
# See Character Sets Used By Fonts. http://msdn.microsoft.com/en-us/library/dd183415%28VS.85%29.aspx
|
190
|
+
LPCTSTR: :pointer, # An LPCWSTR if UNICODE is defined, an LPCSTR otherwise.
|
191
|
+
LPCVOID: :pointer, # Pointer to a constant of any type. WinDef.h as follows: typedef CONST void *LPCVOID;
|
192
|
+
LPCWSTR: :pointer, # Pointer to a constant null-terminated string of 16-bit Unicode characters.
|
189
193
|
LPDWORD: :pointer, # Pointer to a DWORD. WinDef.h as follows: typedef DWORD *LPDWORD;
|
190
194
|
LPHANDLE: :pointer, # Pointer to a HANDLE. WinDef.h as follows: typedef HANDLE *LPHANDLE;
|
191
195
|
LPINT: :pointer, # Pointer to an INT.
|
@@ -195,7 +199,7 @@ module Win
|
|
195
199
|
LPVOID: :pointer, # Pointer to any type.
|
196
200
|
LPWORD: :pointer, # Pointer to a WORD.
|
197
201
|
LPWSTR: :pointer, # Pointer to a null-terminated string of 16-bit Unicode characters.
|
198
|
-
LRESULT: :long,
|
202
|
+
LRESULT: :long, # Signed result of message processing. WinDef.h: typedef LONG_PTR LRESULT;
|
199
203
|
PBOOL: :pointer, # Pointer to a BOOL.
|
200
204
|
PBOOLEAN: :pointer, # Pointer to a BOOL.
|
201
205
|
PBYTE: :pointer, # Pointer to a BYTE.
|
@@ -204,8 +208,8 @@ module Win
|
|
204
208
|
PCTSTR: :pointer, # A PCWSTR if UNICODE is defined, a PCSTR otherwise.
|
205
209
|
PCWSTR: :pointer, # Pointer to a constant null-terminated string of 16-bit Unicode characters.
|
206
210
|
PDWORD: :pointer, # Pointer to a DWORD.
|
207
|
-
PDWORDLONG: :pointer
|
208
|
-
PDWORD_PTR: :pointer
|
211
|
+
PDWORDLONG: :pointer, # Pointer to a DWORDLONG.
|
212
|
+
PDWORD_PTR: :pointer, # Pointer to a DWORD_PTR.
|
209
213
|
PDWORD32: :pointer, # Pointer to a DWORD32.
|
210
214
|
PDWORD64: :pointer, # Pointer to a DWORD64.
|
211
215
|
PFLOAT: :pointer, # Pointer to a FLOAT.
|
@@ -249,35 +253,35 @@ module Win
|
|
249
253
|
PWCHAR: :pointer, # Pointer to a WCHAR.
|
250
254
|
PWORD: :pointer, # Pointer to a WORD.
|
251
255
|
PWSTR: :pointer, # Pointer to a null- terminated string of 16-bit Unicode characters.
|
252
|
-
|
253
|
-
SC_HANDLE: :ulong,
|
254
|
-
|
256
|
+
# For more information, see Character Sets Used By Fonts.
|
257
|
+
SC_HANDLE: :ulong, # (L) Handle to a service control manager database.
|
258
|
+
# See SCM Handles http://msdn.microsoft.com/en-us/library/ms685104%28VS.85%29.aspx
|
255
259
|
SC_LOCK: :pointer, # Lock to a service control manager database. For more information, see SCM Handles.
|
256
|
-
SERVICE_STATUS_HANDLE: :ulong,
|
257
|
-
SHORT: :short,
|
258
|
-
SIZE_T: :ulong,
|
259
|
-
SSIZE_T: :long,
|
260
|
-
TBYTE: :short,
|
261
|
-
TCHAR: :short,
|
262
|
-
UCHAR: :uchar,
|
263
|
-
UHALF_PTR: :uint,
|
264
|
-
UINT: :uint,
|
265
|
-
UINT_PTR: :uint,
|
260
|
+
SERVICE_STATUS_HANDLE: :ulong, # (L) Handle to a service status value. See SCM Handles.
|
261
|
+
SHORT: :short, # A 16-bit integer. The range is –32768 through 32767 decimal.
|
262
|
+
SIZE_T: :ulong, # The maximum number of bytes to which a pointer can point. Use for a count that must span the full range of a pointer.
|
263
|
+
SSIZE_T: :long, # Signed SIZE_T.
|
264
|
+
TBYTE: :short, # A WCHAR if UNICODE is defined, a CHAR otherwise.TCHAR:
|
265
|
+
TCHAR: :short, # A WCHAR if UNICODE is defined, a CHAR otherwise.TCHAR:
|
266
|
+
UCHAR: :uchar, # Unsigned CHAR (8 bit)
|
267
|
+
UHALF_PTR: :uint, # Unsigned HALF_PTR. Use within a structure that contains a pointer and two small fields.
|
268
|
+
UINT: :uint, # Unsigned INT. The range is 0 through 4294967295 decimal.
|
269
|
+
UINT_PTR: :uint, # Unsigned INT_PTR.
|
266
270
|
UINT32: :uint32, # Unsigned INT32. The range is 0 through 4294967295 decimal.
|
267
271
|
UINT64: :uint64, # Unsigned INT64. The range is 0 through 18446744073709551615 decimal.
|
268
|
-
ULONG: :ulong,
|
272
|
+
ULONG: :ulong, # Unsigned LONG. The range is 0 through 4294967295 decimal.
|
269
273
|
ULONGLONG: :ulong_long, # 64-bit unsigned integer. The range is 0 through 18446744073709551615 decimal.
|
270
|
-
ULONG_PTR: :ulong,
|
271
|
-
ULONG32: :uint32,
|
272
|
-
ULONG64: :uint64,
|
273
|
-
UNICODE_STRING: :pointer
|
274
|
-
USHORT: :ushort,
|
275
|
-
USN: :ulong_long,
|
276
|
-
VOID:
|
274
|
+
ULONG_PTR: :ulong, # Unsigned LONG_PTR.
|
275
|
+
ULONG32: :uint32, # Unsigned INT32. The range is 0 through 4294967295 decimal.
|
276
|
+
ULONG64: :uint64, # Unsigned LONG64. The range is 0 through 18446744073709551615 decimal.
|
277
|
+
UNICODE_STRING: :pointer, # Pointer to some string structure??
|
278
|
+
USHORT: :ushort, # Unsigned SHORT. The range is 0 through 65535 decimal.
|
279
|
+
USN: :ulong_long, # Update sequence number (USN).
|
280
|
+
VOID: [], # Any type ? Only use it to indicate no arguments or no return value
|
277
281
|
WCHAR: :ushort, # 16-bit Unicode character. For more information, see Character Sets Used By Fonts.
|
278
|
-
|
282
|
+
# In WinNT.h: typedef wchar_t WCHAR;
|
279
283
|
#WINAPI: K, # Calling convention for system functions. WinDef.h: define WINAPI __stdcall
|
280
|
-
WORD: :ushort,
|
284
|
+
WORD: :ushort, # 16-bit unsigned integer. The range is 0 through 65535 decimal.
|
281
285
|
WPARAM: :uint # Message parameter. WinDef.h as follows: typedef UINT_PTR WPARAM;
|
282
286
|
}
|
283
287
|
|
@@ -314,7 +318,7 @@ module Win
|
|
314
318
|
#
|
315
319
|
def function(name, params, returns, options={}, &def_block)
|
316
320
|
method_name, effective_names, aliases = generate_names(name, options)
|
317
|
-
params, returns = generate_signature(params, returns
|
321
|
+
params, returns = generate_signature(params, returns)
|
318
322
|
libs = ffi_libraries.map(&:name)
|
319
323
|
boolean = options[:boolean]
|
320
324
|
zeronil = options[:zeronil]
|
@@ -357,6 +361,7 @@ module Win
|
|
357
361
|
api #return api object from function declaration
|
358
362
|
end
|
359
363
|
|
364
|
+
##
|
360
365
|
# Generates possible effective names for function in Win32 dll (name+A/W),
|
361
366
|
# Rubyesque name and aliases for method(s) defined based on function name,
|
362
367
|
# sets boolean flag for test functions (Is...)
|
@@ -378,16 +383,31 @@ module Win
|
|
378
383
|
[method_name, effective_names, aliases]
|
379
384
|
end
|
380
385
|
|
386
|
+
##
|
381
387
|
# Generates params and returns (signature) containing only FFI-compliant types
|
382
388
|
#
|
383
|
-
def generate_signature(params, returns
|
389
|
+
def generate_signature(params, returns)
|
384
390
|
params = params.split(//) if params.respond_to?(:split) # Convert params string into array
|
385
391
|
params.map! {|param| TYPES[param.to_sym] || param} # Convert chars into FFI type symbols
|
386
392
|
returns = TYPES[returns.to_sym] || returns # Convert chars into FFI type symbols
|
387
393
|
[params, returns]
|
388
394
|
end
|
389
395
|
|
390
|
-
|
396
|
+
##
|
397
|
+
# Wrapper for FFI::Library#callback() that converts Win32/shortcut types into FFI format
|
398
|
+
#
|
399
|
+
def callback(name, params, returns)
|
400
|
+
params, returns = generate_signature(params, returns)
|
401
|
+
ffi_callback name.to_sym, params, returns
|
402
|
+
end
|
403
|
+
|
404
|
+
##
|
405
|
+
# :method: namespace
|
406
|
+
# This method is meta-generated when Win::Library module is included into other module/class
|
407
|
+
# It returns reference to including (host) module for use by Win::Library::API and class methods.
|
408
|
+
|
409
|
+
##
|
410
|
+
# Ensures that args count is equal to params count plus diff
|
391
411
|
#
|
392
412
|
def enforce_count(args, params, diff = 0)
|
393
413
|
num_args = args.size
|
@@ -397,31 +417,22 @@ module Win
|
|
397
417
|
end
|
398
418
|
end
|
399
419
|
|
400
|
-
# Returns string buffer - used to supply string pointer reference to API functions
|
401
|
-
#
|
402
|
-
def buffer(size = 1024, code = "\x00")
|
403
|
-
code * size
|
404
|
-
end
|
405
|
-
|
406
|
-
# Returns array of given args if none of them is zero,
|
407
|
-
# if any arg is zero, returns array of nils
|
408
|
-
#
|
409
|
-
def nonzero_array(*args)
|
410
|
-
args.any?{|arg| arg == 0 } ? args.map{||nil} : args
|
411
|
-
end
|
412
|
-
|
413
|
-
##
|
414
|
-
# :singleton-method: namespace
|
415
|
-
# This method is meta-generated when Win::Library module is included into other module/class
|
416
|
-
# it holds reference to including module for use by Win::Library::API and class methods.
|
417
420
|
end
|
418
421
|
|
422
|
+
##
|
423
|
+
# Hook executed when Win::Library is included into class or module. It extends host class/module
|
424
|
+
# with both FFI::Library methods and Win::Library macro methods like 'function'.
|
419
425
|
def self.included(klass)
|
420
|
-
klass.extend ClassMethods
|
421
426
|
klass.extend FFI::Library
|
427
|
+
|
428
|
+
eigenklass = class << klass; self; end # Extracting host class's eigenclass
|
429
|
+
eigenklass.class_eval "
|
430
|
+
alias_method :ffi_callback, :callback
|
431
|
+
def namespace; #{klass}; end"
|
432
|
+
|
433
|
+
klass.extend ClassMethods
|
422
434
|
klass.ffi_lib 'user32', 'kernel32' # Default libraries
|
423
435
|
klass.ffi_convention :stdcall
|
424
|
-
klass.instance_eval "def namespace; #{klass}; end"
|
425
436
|
end
|
426
437
|
|
427
438
|
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require 'win/library'
|
2
|
+
require 'win/window'
|
3
|
+
|
4
|
+
module Win
|
5
|
+
module Window
|
6
|
+
# Wait delay quant
|
7
|
+
SLEEP_DELAY = 0.001
|
8
|
+
# Timeout waiting for Window to be closed
|
9
|
+
CLOSE_TIMEOUT = 1
|
10
|
+
|
11
|
+
# Convenience wrapper methods:
|
12
|
+
|
13
|
+
# emulates combinations of keys pressed (Ctrl+Alt+P+M, etc)
|
14
|
+
def keystroke(*keys)
|
15
|
+
return if keys.empty?
|
16
|
+
keybd_event keys.first, 0, KEYEVENTF_KEYDOWN, 0
|
17
|
+
sleep KEY_DELAY
|
18
|
+
keystroke *keys[1..-1]
|
19
|
+
sleep KEY_DELAY
|
20
|
+
keybd_event keys.first, 0, KEYEVENTF_KEYUP, 0
|
21
|
+
end
|
22
|
+
|
23
|
+
# types text message into window holding the focus
|
24
|
+
def type_in(message)
|
25
|
+
message.scan(/./m) do |char|
|
26
|
+
keystroke(*char.to_vkeys)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# finds top-level dialog window by title and yields it to given block
|
31
|
+
def dialog(title, seconds=3)
|
32
|
+
d = begin
|
33
|
+
win = Window.top_level(title, seconds)
|
34
|
+
yield(win) ? win : nil
|
35
|
+
rescue TimeoutError
|
36
|
+
end
|
37
|
+
d.wait_for_close if d
|
38
|
+
return d
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
# Thin class is a thin wrapper around window handle
|
43
|
+
class Window
|
44
|
+
include Win::Window
|
45
|
+
extend Win::Window
|
46
|
+
|
47
|
+
attr_reader :handle
|
48
|
+
|
49
|
+
# find top level window by title, return wrapped Window object
|
50
|
+
def self.top_level(title, seconds=3)
|
51
|
+
@handle = timeout(seconds) do
|
52
|
+
sleep SLEEP_DELAY while (h = find_window nil, title) == nil; h
|
53
|
+
end
|
54
|
+
Window.new @handle
|
55
|
+
end
|
56
|
+
|
57
|
+
def initialize(handle)
|
58
|
+
@handle = handle
|
59
|
+
end
|
60
|
+
|
61
|
+
# find child window (control) by title, window class, or control ID:
|
62
|
+
def child(id)
|
63
|
+
result = case id
|
64
|
+
when String
|
65
|
+
by_title = find_window_ex @handle, 0, nil, id.gsub('_', '&' )
|
66
|
+
by_class = find_window_ex @handle, 0, id, nil
|
67
|
+
by_title ? by_title : by_class
|
68
|
+
when Fixnum
|
69
|
+
get_dlg_item @handle, id
|
70
|
+
when nil
|
71
|
+
find_window_ex @handle, 0, nil, nil
|
72
|
+
else
|
73
|
+
nil
|
74
|
+
end
|
75
|
+
raise "Control '#{id}' not found" unless result
|
76
|
+
Window.new result
|
77
|
+
end
|
78
|
+
|
79
|
+
def children
|
80
|
+
enum_child_windows(@handle).map{|child_handle| Window.new child_handle}
|
81
|
+
end
|
82
|
+
|
83
|
+
# emulate click of the control identified by id
|
84
|
+
def click(id)
|
85
|
+
h = child(id).handle
|
86
|
+
rectangle = [0, 0, 0, 0].pack 'LLLL'
|
87
|
+
get_window_rect h, rectangle
|
88
|
+
left, top, right, bottom = rectangle.unpack 'LLLL'
|
89
|
+
center = [(left + right) / 2, (top + bottom) / 2]
|
90
|
+
set_cursor_pos *center
|
91
|
+
mouse_event MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0
|
92
|
+
mouse_event MOUSEEVENTF_LEFTUP, 0, 0, 0, 0
|
93
|
+
end
|
94
|
+
|
95
|
+
def close
|
96
|
+
post_message @handle, WM_SYSCOMMAND, SC_CLOSE, 0
|
97
|
+
end
|
98
|
+
|
99
|
+
def wait_for_close
|
100
|
+
timeout(CLOSE_TIMEOUT) do
|
101
|
+
sleep SLEEP_DELAY while window_visible?(@handle)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def text
|
106
|
+
buffer = "\x0" * 2048
|
107
|
+
length = send_message @handle, WM_GETTEXT, buffer.length, buffer
|
108
|
+
length == 0 ? '' : buffer[0..length - 1]
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
113
|
+
end
|