win 0.0.2 → 0.0.3
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 +16 -14
- data/VERSION +1 -1
- data/lib/win/library.rb +256 -45
- data/lib/win/window.rb +547 -0
- data/spec/spec_helper.rb +20 -1
- data/spec/test_apps/locknote/LockNote.exe +0 -0
- data/spec/win/library_spec.rb +1 -0
- data/spec/win/window_spec.rb +309 -0
- data/win.gemspec +68 -0
- metadata +7 -2
data/README.rdoc
CHANGED
@@ -1,21 +1,16 @@
|
|
1
1
|
= win
|
2
2
|
|
3
3
|
by: Arvicco
|
4
|
-
url: http://github.com/arvicco/
|
4
|
+
url: http://github.com/arvicco/win
|
5
5
|
|
6
6
|
== DESCRIPTION
|
7
7
|
|
8
|
-
A collection of Windows functions predefined for you using FFI. In addition to
|
8
|
+
A collection of Windows API functions predefined for you using FFI. In addition to
|
9
9
|
straightforward (CamelCase) API wrappers, it also strives to provide more Ruby-like
|
10
10
|
snake_case methods that take a minimum of arguments with sensible defaults and have
|
11
11
|
sensible return values (false/true instead of 0/nonzero for test functions, etc).
|
12
12
|
|
13
|
-
|
14
|
-
that also contain related constants and convenience methods. For example, win/dde.rb
|
15
|
-
file contains functions related to DDE protocol, such as DdeInitialize() as well as
|
16
|
-
constants such as DMLERR_NO_ERROR, APPCLASS_STANDARD, etc.
|
17
|
-
|
18
|
-
It is still work in progress, only a small number of Windows API functions wrapped so far...
|
13
|
+
This is still work in progress, only a small portion of Windows API wrapped so far...
|
19
14
|
|
20
15
|
== SUMMARY
|
21
16
|
|
@@ -79,7 +74,7 @@ But still, does not it look like TOO MUCH code for something that should (ideall
|
|
79
74
|
title = window_text_w(window_handle)
|
80
75
|
|
81
76
|
This is an idea behind this library - make Windows API functions easier to use and feel more
|
82
|
-
natural inside Ruby code. Following the principle of least surprise, we define methods that:
|
77
|
+
natural inside Ruby code. Following the principle of least surprise, we define wrapper methods that:
|
83
78
|
* Have Rubyesque names (minimized? instead of IsMinimized, etc)
|
84
79
|
* Require minimum arguments with sensible defaults
|
85
80
|
* Return appropriate values explicitly (several return values if necessary)
|
@@ -93,10 +88,17 @@ CamelCase method name instead of Rubyesque snake_case one, it will expect those
|
|
93
88
|
parameters you know and love from MSDN, return your zeroes instead of nils and support no
|
94
89
|
other enhancements.
|
95
90
|
|
91
|
+
Related Windows API functions are grouped by topic and defined in separate namespaces (modules),
|
92
|
+
that also contain related constants and convenience methods. For example, win/dde.rb file
|
93
|
+
contains only functions related to DDE protocol such as DdeInitialize() as well as constants
|
94
|
+
such as DMLERR_NO_ERROR, APPCLASS_STANDARD, etc. So if you need only DDE-related functions,
|
95
|
+
there is no need to load all the other modules, clogging your namespaces - just require 'win/dde'
|
96
|
+
and be done with it.
|
97
|
+
|
96
98
|
And if you do not see your favorite Windows API functions amoung those already defined, it is
|
97
|
-
quite easy to define new ones with 'function'
|
98
|
-
lot of heavy lifting for you and can be customized with options
|
99
|
-
reusable API wrapper methods with the exact behavior you need.
|
99
|
+
quite easy to 'include Win::Library' into your module and define new ones with 'function'
|
100
|
+
class method (macro) - it does a lot of heavy lifting for you and can be customized with options
|
101
|
+
and code blocks to give you reusable API wrapper methods with the exact behavior you need.
|
100
102
|
|
101
103
|
== REQUIREMENTS:
|
102
104
|
|
@@ -116,11 +118,11 @@ Contributors always welcome!
|
|
116
118
|
|
117
119
|
require 'win/window'
|
118
120
|
|
119
|
-
class
|
121
|
+
class MyClass
|
120
122
|
include Win::Window
|
121
123
|
|
122
124
|
fg_window = foreground_window
|
123
|
-
puts
|
125
|
+
puts window_text(fg_window)
|
124
126
|
show_window(fg_window) unless minimized?(fg_window)
|
125
127
|
hide_window(fg_window) if maximized?(fg_window)
|
126
128
|
...
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.3
|
data/lib/win/library.rb
CHANGED
@@ -3,22 +3,24 @@ require 'win/extensions'
|
|
3
3
|
|
4
4
|
module Win
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
module Errors # :nodoc:
|
7
|
+
class NotFoundError < NameError # :nodoc:
|
8
|
+
def initialize(name=nil, libs=nil)
|
9
|
+
super %Q[Function #{name ? "'#{name}' ": ""}not found#{libs ? " in #{libs}" : ""}"]
|
10
|
+
end
|
9
11
|
end
|
10
12
|
end
|
11
13
|
|
12
14
|
module Library
|
13
15
|
|
14
|
-
# Class Win::Library::API mimics Win32::API
|
16
|
+
# API wrapper for Class Win::Library::API mimics Win32::API
|
15
17
|
class API
|
16
18
|
|
17
19
|
# The name of the DLL that exports the API function
|
18
20
|
attr_reader :dll_name
|
19
21
|
|
20
|
-
# Ruby (
|
21
|
-
attr_reader :
|
22
|
+
# Ruby namespace (module) where this API function is attached
|
23
|
+
attr_reader :namespace
|
22
24
|
|
23
25
|
# The name of the function passed to the constructor
|
24
26
|
attr_reader :function_name
|
@@ -34,22 +36,26 @@ module Win
|
|
34
36
|
# The return type (:void for no return value)
|
35
37
|
attr_reader :return_type
|
36
38
|
|
37
|
-
def initialize(
|
38
|
-
@
|
39
|
-
@function_name =
|
39
|
+
def initialize( namespace, function_name, effective_function_name, prototype, return_type, dll_name )
|
40
|
+
@namespace = namespace
|
41
|
+
@function_name = function_name
|
40
42
|
@effective_function_name = effective_function_name
|
41
43
|
@prototype = prototype
|
42
44
|
@return_type = return_type
|
45
|
+
@dll_name = dll_name
|
43
46
|
end
|
44
47
|
|
45
48
|
def call( *args )
|
46
|
-
@
|
49
|
+
@namespace.send(@function_name.to_sym, *args)
|
47
50
|
end
|
51
|
+
|
52
|
+
alias_method :[], :call
|
48
53
|
end
|
49
54
|
|
50
55
|
# Contains class methods (macros) to be used in Win::Libraries
|
51
56
|
module ClassMethods
|
52
57
|
TYPES = {
|
58
|
+
# FFI type shortcuts
|
53
59
|
V: :void, # For functions that return nothing (return type void).
|
54
60
|
v: :void, # For functions that return nothing (return type void).
|
55
61
|
C: :uchar, #– 8-bit unsigned character (byte)
|
@@ -74,12 +80,193 @@ module Win
|
|
74
80
|
D: :double, # 64-bit floating point (double-precision)
|
75
81
|
P: :pointer, # pointer – platform-specific size
|
76
82
|
p: :string, # C-style (NULL-terminated) character string (Win32API: S)
|
77
|
-
B: :bool # (?? 1 byte in C++)
|
83
|
+
B: :bool, # (?? 1 byte in C++)
|
78
84
|
#For function argument type only:
|
79
85
|
# :buffer_in – Similar to :pointer, but optimized for Buffers that the function can only read (not write).
|
80
86
|
# :buffer_out – Similar to :pointer, but optimized for Buffers that the function can only write (not read).
|
81
87
|
# :buffer_inout – Similar to :pointer, but may be optimized for Buffers.
|
82
88
|
# :varargs – Variable arguments
|
89
|
+
|
90
|
+
# Windows-specific typedefs:
|
91
|
+
ATOM: :ushort, # Atom ~= Symbol: Atom table stores strings and corresponding identifiers. Application
|
92
|
+
# places a string in an atom table and receives a 16-bit integer, called an atom, that
|
93
|
+
# can be used to access the string. Placed string is called an atom name.
|
94
|
+
# See: http://msdn.microsoft.com/en-us/library/ms648708%28VS.85%29.aspx
|
95
|
+
BOOL: :bool,
|
96
|
+
BOOLEAN: :bool,
|
97
|
+
BYTE: :uchar, # Byte (8 bits). Declared as unsigned char
|
98
|
+
#CALLBACK: K, # Win32.API gem-specific ?? MSDN: #define CALLBACK __stdcall
|
99
|
+
CHAR: :char, # 8-bit Windows (ANSI) character. See http://msdn.microsoft.com/en-us/library/dd183415%28VS.85%29.aspx
|
100
|
+
COLORREF: :uint32, # Red, green, blue (RGB) color value (32 bits). See COLORREF for more info.
|
101
|
+
DWORD: :uint32, # 32-bit unsigned integer. The range is 0 through 4,294,967,295 decimal.
|
102
|
+
DWORDLONG: :uint64, # 64-bit unsigned integer. The range is 0 through 18,446,744,073,709,551,615 decimal.
|
103
|
+
DWORD_PTR: :ulong, # Unsigned long type for pointer precision. Use when casting a pointer to a long type
|
104
|
+
# to perform pointer arithmetic. (Also commonly used for general 32-bit parameters that have
|
105
|
+
# been extended to 64 bits in 64-bit Windows.) BaseTsd.h: #typedef ULONG_PTR DWORD_PTR;
|
106
|
+
DWORD32: :uint32,
|
107
|
+
DWORD64: :uint64,
|
108
|
+
HALF_PTR: :int, # Half the size of a pointer. Use within a structure that contains a pointer and two small fields.
|
109
|
+
# BaseTsd.h: #ifdef (_WIN64) typedef int HALF_PTR; #else typedef short HALF_PTR;
|
110
|
+
HACCEL: :ulong, # (L) Handle to an accelerator table. WinDef.h: #typedef HANDLE HACCEL;
|
111
|
+
# See http://msdn.microsoft.com/en-us/library/ms645526%28VS.85%29.aspx
|
112
|
+
HANDLE: :ulong, # (L) Handle to an object. WinNT.h: #typedef PVOID HANDLE;
|
113
|
+
HBITMAP: :ulong, # (L) Handle to a bitmap: http://msdn.microsoft.com/en-us/library/dd183377%28VS.85%29.aspx
|
114
|
+
HBRUSH: :ulong, # (L) Handle to a brush. http://msdn.microsoft.com/en-us/library/dd183394%28VS.85%29.aspx
|
115
|
+
HCOLORSPACE: :ulong,# (L) Handle to a color space. http://msdn.microsoft.com/en-us/library/ms536546%28VS.85%29.aspx
|
116
|
+
HCURSOR: :ulong, # (L) Handle to a cursor. http://msdn.microsoft.com/en-us/library/ms646970%28VS.85%29.aspx
|
117
|
+
HCONV: :ulong, # (L) Handle to a dynamic data exchange (DDE) conversation.
|
118
|
+
HCONVLIST: :ulong, # (L) Handle to a DDE conversation list. HANDLE - L ?
|
119
|
+
HDDEDATA: :ulong, # (L) Handle to DDE data (structure?)
|
120
|
+
HDC: :ulong, # (L) Handle to a device context (DC). http://msdn.microsoft.com/en-us/library/dd183560%28VS.85%29.aspx
|
121
|
+
HDESK: :ulong, # (L) Handle to a desktop. http://msdn.microsoft.com/en-us/library/ms682573%28VS.85%29.aspx
|
122
|
+
HDROP: :ulong, # (L) Handle to an internal drop structure.
|
123
|
+
HDWP: :ulong, # (L) Handle to a deferred window position structure.
|
124
|
+
HENHMETAFILE: :ulong,#(L) Handle to an enhanced metafile. http://msdn.microsoft.com/en-us/library/dd145051%28VS.85%29.aspx
|
125
|
+
HFILE: :uint, # (I) Special file handle to a file opened by OpenFile, not CreateFile.
|
126
|
+
# WinDef.h: #typedef int HFILE;
|
127
|
+
HFONT: :ulong, # (L) Handle to a font. http://msdn.microsoft.com/en-us/library/dd162470%28VS.85%29.aspx
|
128
|
+
HGDIOBJ: :ulong, # (L) Handle to a GDI object.
|
129
|
+
HGLOBAL: :ulong, # (L) Handle to a global memory block.
|
130
|
+
HHOOK: :ulong, # (L) Handle to a hook. http://msdn.microsoft.com/en-us/library/ms632589%28VS.85%29.aspx
|
131
|
+
HICON: :ulong, # (L) Handle to an icon. http://msdn.microsoft.com/en-us/library/ms646973%28VS.85%29.aspx
|
132
|
+
HINSTANCE: :ulong, # (L) Handle to an instance. This is the base address of the module in memory.
|
133
|
+
# HMODULE and HINSTANCE are the same today, but were different in 16-bit Windows.
|
134
|
+
HKEY: :ulong, # (L) Handle to a registry key.
|
135
|
+
HKL: :ulong, # (L) Input locale identifier.
|
136
|
+
HLOCAL: :ulong, # (L) Handle to a local memory block.
|
137
|
+
HMENU: :ulong, # (L) Handle to a menu. http://msdn.microsoft.com/en-us/library/ms646977%28VS.85%29.aspx
|
138
|
+
HMETAFILE: :ulong, # (L) Handle to a metafile. http://msdn.microsoft.com/en-us/library/dd145051%28VS.85%29.aspx
|
139
|
+
HMODULE: :ulong, # (L) Handle to an instance. Same as HINSTANCE today, but was different in 16-bit Windows.
|
140
|
+
HMONITOR: :ulong, # (L) Рandle to a display monitor. WinDef.h: if(WINVER >= 0x0500) typedef HANDLE HMONITOR;
|
141
|
+
HPALETTE: :ulong, # (L) Handle to a palette.
|
142
|
+
HPEN: :ulong, # (L) Handle to a pen. http://msdn.microsoft.com/en-us/library/dd162786%28VS.85%29.aspx
|
143
|
+
HRESULT: :long, # Return code used by COM interfaces. For more info, Structure of the COM Error Codes.
|
144
|
+
# To test an HRESULT value, use the FAILED and SUCCEEDED macros.
|
145
|
+
HRGN: :ulong, # (L) Handle to a region. http://msdn.microsoft.com/en-us/library/dd162913%28VS.85%29.aspx
|
146
|
+
HRSRC: :ulong, # (L) Handle to a resource.
|
147
|
+
HSZ: :ulong, # (L) Handle to a DDE string.
|
148
|
+
HWINSTA: :ulong, # (L) Handle to a window station. http://msdn.microsoft.com/en-us/library/ms687096%28VS.85%29.aspx
|
149
|
+
HWND: :ulong, # (L) Handle to a window. http://msdn.microsoft.com/en-us/library/ms632595%28VS.85%29.aspx
|
150
|
+
INT: :int, # 32-bit signed integer. The range is -2147483648 through 2147483647 decimal.
|
151
|
+
INT_PTR: :int, # Signed integer type for pointer precision. Use when casting a pointer to an integer
|
152
|
+
# to perform pointer arithmetic. BaseTsd.h:
|
153
|
+
#if defined(_WIN64) typedef __int64 INT_PTR; #else typedef int INT_PTR;
|
154
|
+
INT32: :int32, # 32-bit signed integer. The range is -2,147,483,648 through +...647 decimal.
|
155
|
+
INT64: :int64, # 64-bit signed integer. The range is –9,223,372,036,854,775,808 through +...807
|
156
|
+
LANGID: :ushort, # Language identifier. For more information, see Locales. WinNT.h: #typedef WORD LANGID;
|
157
|
+
# See http://msdn.microsoft.com/en-us/library/dd318716%28VS.85%29.aspx
|
158
|
+
LCID: :uint32, # Locale identifier. For more information, see Locales.
|
159
|
+
LCTYPE: :uint32, # Locale information type. For a list, see Locale Information Constants.
|
160
|
+
LGRPID: :uint32, # Language group identifier. For a list, see EnumLanguageGroupLocales.
|
161
|
+
LONG: :long, # 32-bit signed integer. The range is -2,147,483,648 through +...647 decimal.
|
162
|
+
LONG32: :long, # 32-bit signed integer. The range is -2,147,483,648 through +...647 decimal.
|
163
|
+
LONG64: :int64, # 64-bit signed integer. The range is –9,223,372,036,854,775,808 through +...807
|
164
|
+
LONGLONG: :int64, # 64-bit signed integer. The range is –9,223,372,036,854,775,808 through +...807
|
165
|
+
LONG_PTR: :long, # Signed long type for pointer precision. Use when casting a pointer to a long to
|
166
|
+
# perform pointer arithmetic. BaseTsd.h:
|
167
|
+
#if defined(_WIN64) typedef __int64 LONG_PTR; #else typedef long LONG_PTR;
|
168
|
+
LPARAM: :long, # Message parameter. WinDef.h as follows: #typedef LONG_PTR LPARAM;
|
169
|
+
LPBOOL: :pointer, # Pointer to a BOOL. WinDef.h as follows: #typedef BOOL far *LPBOOL;
|
170
|
+
LPBYTE: :pointer, # Pointer to a BYTE. WinDef.h as follows: #typedef BYTE far *LPBYTE;
|
171
|
+
LPCOLORREF: :pointer,# Pointer to a COLORREF value. WinDef.h as follows: #typedef DWORD *LPCOLORREF;
|
172
|
+
LPCSTR: :pointer, # Pointer to a constant null-terminated string of 8-bit Windows (ANSI) characters.
|
173
|
+
# See Character Sets Used By Fonts. http://msdn.microsoft.com/en-us/library/dd183415%28VS.85%29.aspx
|
174
|
+
LPCTSTR: :pointer, # An LPCWSTR if UNICODE is defined, an LPCSTR otherwise.
|
175
|
+
LPCVOID: :pointer, # Pointer to a constant of any type. WinDef.h as follows: typedef CONST void *LPCVOID;
|
176
|
+
LPCWSTR: :pointer, # Pointer to a constant null-terminated string of 16-bit Unicode characters.
|
177
|
+
LPDWORD: :pointer, # Pointer to a DWORD. WinDef.h as follows: typedef DWORD *LPDWORD;
|
178
|
+
LPHANDLE: :pointer, # Pointer to a HANDLE. WinDef.h as follows: typedef HANDLE *LPHANDLE;
|
179
|
+
LPINT: :pointer, # Pointer to an INT.
|
180
|
+
LPLONG: :pointer, # Pointer to an LONG.
|
181
|
+
LPSTR: :pointer, # Pointer to a null-terminated string of 8-bit Windows (ANSI) characters.
|
182
|
+
LPTSTR: :pointer, # An LPWSTR if UNICODE is defined, an LPSTR otherwise.
|
183
|
+
LPVOID: :pointer, # Pointer to any type.
|
184
|
+
LPWORD: :pointer, # Pointer to a WORD.
|
185
|
+
LPWSTR: :pointer, # Pointer to a null-terminated string of 16-bit Unicode characters.
|
186
|
+
LRESULT: :long, # Signed result of message processing. WinDef.h: typedef LONG_PTR LRESULT;
|
187
|
+
PBOOL: :pointer, # Pointer to a BOOL.
|
188
|
+
PBOOLEAN: :pointer, # Pointer to a BOOL.
|
189
|
+
PBYTE: :pointer, # Pointer to a BYTE.
|
190
|
+
PCHAR: :pointer, # Pointer to a CHAR.
|
191
|
+
PCSTR: :pointer, # Pointer to a constant null-terminated string of 8-bit Windows (ANSI) characters.
|
192
|
+
PCTSTR: :pointer, # A PCWSTR if UNICODE is defined, a PCSTR otherwise.
|
193
|
+
PCWSTR: :pointer, # Pointer to a constant null-terminated string of 16-bit Unicode characters.
|
194
|
+
PDWORD: :pointer, # Pointer to a DWORD.
|
195
|
+
PDWORDLONG: :pointer,# Pointer to a DWORDLONG.
|
196
|
+
PDWORD_PTR: :pointer,# Pointer to a DWORD_PTR.
|
197
|
+
PDWORD32: :pointer, # Pointer to a DWORD32.
|
198
|
+
PDWORD64: :pointer, # Pointer to a DWORD64.
|
199
|
+
PFLOAT: :pointer, # Pointer to a FLOAT.
|
200
|
+
PHALF_PTR: :pointer, # Pointer to a HALF_PTR.
|
201
|
+
PHANDLE: :pointer, # Pointer to a HANDLE.
|
202
|
+
PHKEY: :pointer, # Pointer to an HKEY.
|
203
|
+
PINT: :pointer, # Pointer to an INT.
|
204
|
+
PINT_PTR: :pointer, # Pointer to an INT_PTR.
|
205
|
+
PINT32: :pointer, # Pointer to an INT32.
|
206
|
+
PINT64: :pointer, # Pointer to an INT64.
|
207
|
+
PLCID: :pointer, # Pointer to an LCID.
|
208
|
+
PLONG: :pointer, # Pointer to a LONG.
|
209
|
+
PLONGLONG: :pointer, # Pointer to a LONGLONG.
|
210
|
+
PLONG_PTR: :pointer, # Pointer to a LONG_PTR.
|
211
|
+
PLONG32: :pointer, # Pointer to a LONG32.
|
212
|
+
PLONG64: :pointer, # Pointer to a LONG64.
|
213
|
+
POINTER_32: :pointer, # 32-bit pointer. On a 32-bit system, this is a native pointer. On a 64-bit system, this is a truncated 64-bit pointer.
|
214
|
+
POINTER_64: :pointer, # 64-bit pointer. On a 64-bit system, this is a native pointer. On a 32-bit system, this is a sign-extended 32-bit pointer.
|
215
|
+
POINTER_SIGNED: :pointer, # A signed pointer.
|
216
|
+
POINTER_UNSIGNED: :pointer, # An unsigned pointer.
|
217
|
+
PSHORT: :pointer, # Pointer to a SHORT.
|
218
|
+
PSIZE_T: :pointer, # Pointer to a SIZE_T.
|
219
|
+
PSSIZE_T: :pointer, # Pointer to a SSIZE_T.
|
220
|
+
PSTR: :pointer, # Pointer to a null-terminated string of 8-bit Windows (ANSI) characters. For more information, see Character Sets Used By Fonts.
|
221
|
+
PTBYTE: :pointer, # Pointer to a TBYTE.
|
222
|
+
PTCHAR: :pointer, # Pointer to a TCHAR.
|
223
|
+
PTSTR: :pointer, # A PWSTR if UNICODE is defined, a PSTR otherwise.
|
224
|
+
PUCHAR: :pointer, # Pointer to a UCHAR.
|
225
|
+
PUHALF_PTR: :pointer, # Pointer to a UHALF_PTR.
|
226
|
+
PUINT: :pointer, # Pointer to a UINT.
|
227
|
+
PUINT_PTR: :pointer, # Pointer to a UINT_PTR.
|
228
|
+
PUINT32: :pointer, # Pointer to a UINT32.
|
229
|
+
PUINT64: :pointer, # Pointer to a UINT64.
|
230
|
+
PULONG: :pointer, # Pointer to a ULONG.
|
231
|
+
PULONGLONG: :pointer, # Pointer to a ULONGLONG.
|
232
|
+
PULONG_PTR: :pointer, # Pointer to a ULONG_PTR.
|
233
|
+
PULONG32: :pointer, # Pointer to a ULONG32.
|
234
|
+
PULONG64: :pointer, # Pointer to a ULONG64.
|
235
|
+
PUSHORT: :pointer, # Pointer to a USHORT.
|
236
|
+
PVOID: :pointer, # Pointer to any type.
|
237
|
+
PWCHAR: :pointer, # Pointer to a WCHAR.
|
238
|
+
PWORD: :pointer, # Pointer to a WORD.
|
239
|
+
PWSTR: :pointer, # Pointer to a null- terminated string of 16-bit Unicode characters.
|
240
|
+
# For more information, see Character Sets Used By Fonts.
|
241
|
+
SC_HANDLE: :ulong, # (L) Handle to a service control manager database.
|
242
|
+
# See SCM Handles http://msdn.microsoft.com/en-us/library/ms685104%28VS.85%29.aspx
|
243
|
+
SC_LOCK: :pointer, # Lock to a service control manager database. For more information, see SCM Handles.
|
244
|
+
SERVICE_STATUS_HANDLE: :ulong, # (L) Handle to a service status value. See SCM Handles.
|
245
|
+
SHORT: :short, # A 16-bit integer. The range is –32768 through 32767 decimal.
|
246
|
+
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.
|
247
|
+
SSIZE_T: :long, # Signed SIZE_T.
|
248
|
+
TBYTE: :short, # A WCHAR if UNICODE is defined, a CHAR otherwise.TCHAR:
|
249
|
+
TCHAR: :short, # A WCHAR if UNICODE is defined, a CHAR otherwise.TCHAR:
|
250
|
+
UCHAR: :uchar, # Unsigned CHAR (8 bit)
|
251
|
+
UHALF_PTR: :uint, # Unsigned HALF_PTR. Use within a structure that contains a pointer and two small fields.
|
252
|
+
UINT: :uint, # Unsigned INT. The range is 0 through 4294967295 decimal.
|
253
|
+
UINT_PTR: :uint, # Unsigned INT_PTR.
|
254
|
+
UINT32: :uint32, # Unsigned INT32. The range is 0 through 4294967295 decimal.
|
255
|
+
UINT64: :uint64, # Unsigned INT64. The range is 0 through 18446744073709551615 decimal.
|
256
|
+
ULONG: :ulong, # Unsigned LONG. The range is 0 through 4294967295 decimal.
|
257
|
+
ULONGLONG: :ulong_long, # 64-bit unsigned integer. The range is 0 through 18446744073709551615 decimal.
|
258
|
+
ULONG_PTR: :ulong, # Unsigned LONG_PTR.
|
259
|
+
ULONG32: :uint32, # Unsigned INT32. The range is 0 through 4294967295 decimal.
|
260
|
+
ULONG64: :uint64, # Unsigned LONG64. The range is 0 through 18446744073709551615 decimal.
|
261
|
+
UNICODE_STRING: :pointer,# Pointer to some string structure??
|
262
|
+
USHORT: :ushort, # Unsigned SHORT. The range is 0 through 65535 decimal.
|
263
|
+
USN: :ulong_long, # Update sequence number (USN).
|
264
|
+
VOID: :void, # Any type ?
|
265
|
+
WCHAR: :ushort, # 16-bit Unicode character. For more information, see Character Sets Used By Fonts.
|
266
|
+
# In WinNT.h: typedef wchar_t WCHAR;
|
267
|
+
#WINAPI: K, # Calling convention for system functions. WinDef.h: define WINAPI __stdcall
|
268
|
+
WORD: :ushort, # 16-bit unsigned integer. The range is 0 through 65535 decimal.
|
269
|
+
WPARAM: :uint # Message parameter. WinDef.h as follows: typedef UINT_PTR WPARAM;
|
83
270
|
}
|
84
271
|
|
85
272
|
##
|
@@ -110,58 +297,60 @@ module Win
|
|
110
297
|
# :boolean:: Forces method to return true/false instead of nonzero/zero
|
111
298
|
# :zeronil:: Forces method to return nil if function result is zero
|
112
299
|
#
|
113
|
-
def function(
|
114
|
-
method_name, effective_names, aliases = generate_names(
|
300
|
+
def function(name, params, returns, options={}, &def_block)
|
301
|
+
method_name, effective_names, aliases = generate_names(name, options)
|
302
|
+
params, returns = generate_signature(params, returns, options)
|
303
|
+
libs = ffi_libraries.map(&:name)
|
115
304
|
boolean = options[:boolean]
|
116
305
|
zeronil = options[:zeronil]
|
117
|
-
params = params.split(//) if params.respond_to?(:split) # Convert params string into array
|
118
|
-
#puts "#{method_name}, #{effective_names}, #{aliases}"
|
119
|
-
params.map! {|param| TYPES[param.to_sym] || param} # Convert chars into FFI type symbols
|
120
|
-
returns = TYPES[returns.to_sym] || returns # Convert chars into FFI type symbols
|
121
306
|
|
122
|
-
|
307
|
+
effective_name = effective_names.inject(nil) do |func, ename|
|
123
308
|
func || begin
|
124
|
-
|
125
|
-
attach_function(ename, params.dup, returns)
|
309
|
+
attach_function(name, ename, params.dup, returns) # creates basic CamelCase method via FFI
|
126
310
|
ename
|
127
311
|
rescue FFI::NotFoundError
|
128
312
|
nil
|
129
313
|
end
|
130
314
|
end
|
131
315
|
|
132
|
-
raise Win::NotFoundError.new(
|
316
|
+
raise Win::Errors::NotFoundError.new(name, libs) unless effective_name
|
133
317
|
|
134
|
-
|
318
|
+
# Create API object that holds information about function names, params, etc
|
319
|
+
api = API.new(namespace, name, effective_name, params, returns, libs)
|
135
320
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
321
|
+
method_body = if def_block
|
322
|
+
if zeronil
|
323
|
+
->(*args, &block){ (res = def_block.(api, *args, &block)) != 0 ? res : nil }
|
324
|
+
elsif boolean
|
325
|
+
->(*args, &block){ def_block.(api, *args, &block) != 0 }
|
326
|
+
else
|
327
|
+
->(*args, &block){ def_block.(api, *args, &block) }
|
141
328
|
end
|
142
329
|
else
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
result
|
330
|
+
if zeronil
|
331
|
+
->(*args, &block){ (res = block ? block[api[*args]] : api[*args]) != 0 ? res : nil }
|
332
|
+
elsif boolean
|
333
|
+
->(*args, &block){ block ? block[api[*args]] : api[*args] != 0 }
|
334
|
+
else
|
335
|
+
->(*args, &block){ block ? block[api[*args]] : api[*args] }
|
150
336
|
end
|
151
337
|
end
|
152
|
-
|
153
|
-
|
338
|
+
|
339
|
+
define_method method_name, &method_body # define snake_case method
|
340
|
+
|
341
|
+
aliases.each {|ali| alias_method ali, method_name } # define aliases
|
342
|
+
api #return api object from function declaration
|
154
343
|
end
|
155
344
|
|
156
|
-
# Generates possible effective names for function in Win32 dll (
|
345
|
+
# Generates possible effective names for function in Win32 dll (name+A/W),
|
157
346
|
# Rubyesque name and aliases for method(s) defined based on function name,
|
158
347
|
# sets boolean flag for test functions (Is...)
|
159
348
|
#
|
160
|
-
def generate_names(
|
161
|
-
effective_names = [
|
162
|
-
effective_names += ["#{
|
349
|
+
def generate_names(name, options={})
|
350
|
+
effective_names = [name]
|
351
|
+
effective_names += ["#{name}A", "#{name}W"] unless name =~ /[WA]$/
|
163
352
|
aliases = ([options[:alias]] + [options[:aliases]]).flatten.compact
|
164
|
-
method_name = options[:rename] ||
|
353
|
+
method_name = options[:rename] || name.snake_case
|
165
354
|
case method_name
|
166
355
|
when /^is_/
|
167
356
|
aliases << method_name.sub(/^is_/, '') + '?'
|
@@ -174,7 +363,16 @@ module Win
|
|
174
363
|
[method_name, effective_names, aliases]
|
175
364
|
end
|
176
365
|
|
177
|
-
#
|
366
|
+
# Generates params and returns (signature) containing only FFI-compliant types
|
367
|
+
#
|
368
|
+
def generate_signature(params, returns, options={})
|
369
|
+
params = params.split(//) if params.respond_to?(:split) # Convert params string into array
|
370
|
+
params.map! {|param| TYPES[param.to_sym] || param} # Convert chars into FFI type symbols
|
371
|
+
returns = TYPES[returns.to_sym] || returns # Convert chars into FFI type symbols
|
372
|
+
[params, returns]
|
373
|
+
end
|
374
|
+
|
375
|
+
# Ensures that args count is equal to params count plus diff
|
178
376
|
#
|
179
377
|
def enforce_count(args, params, diff = 0)
|
180
378
|
num_args = args.size
|
@@ -183,16 +381,29 @@ module Win
|
|
183
381
|
raise ArgumentError, "wrong number of arguments (#{num_args} for #{num_params})"
|
184
382
|
end
|
185
383
|
end
|
186
|
-
end
|
187
384
|
|
188
|
-
|
385
|
+
# Returns string buffer - used to supply string pointer reference to API functions
|
386
|
+
#
|
387
|
+
def buffer(size = 1024, code = "\x00")
|
388
|
+
code * size
|
389
|
+
end
|
390
|
+
|
391
|
+
# Returns array of given args if none of them is zero,
|
392
|
+
# if any arg is zero, returns array of nils
|
393
|
+
#
|
394
|
+
def nonzero_array(*args)
|
395
|
+
args.any?{|arg| arg == 0 } ? args.map{||nil} : args
|
396
|
+
end
|
397
|
+
|
398
|
+
end
|
189
399
|
|
190
400
|
def self.included(klass)
|
191
401
|
klass.extend ClassMethods
|
192
402
|
klass.extend FFI::Library
|
193
403
|
klass.ffi_lib 'user32', 'kernel32' # Default libraries
|
194
404
|
klass.ffi_convention :stdcall
|
195
|
-
klass.
|
405
|
+
klass.instance_eval "def namespace; #{klass}; end"
|
196
406
|
end
|
407
|
+
|
197
408
|
end
|
198
409
|
end
|