win 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|