win 0.3.8 → 0.3.11

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/HISTORY CHANGED
@@ -26,3 +26,15 @@
26
26
  == 0.3.8 / 2010-06-02
27
27
 
28
28
  * Require paths bug fixed
29
+
30
+ == 0.3.9 / 2010-06-02
31
+
32
+ * Changed Win::Library mix-in mode from include to extend
33
+
34
+ == 0.3.10 / 2010-06-02
35
+
36
+ * Win::Library.extended refactored with module_function
37
+
38
+ == 0.3.11 / 2010-06-03
39
+
40
+ * GetDlgCtrlID function added
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.8
1
+ 0.3.11
data/lib/win/dde.rb CHANGED
@@ -5,7 +5,7 @@ module Win
5
5
  # Includes functions related to DDE exchange protocol in Windows
6
6
  #
7
7
  module Dde
8
- include Win::Library
8
+ extend Win::Library
9
9
 
10
10
  # Windows ANSI codepage:
11
11
  CP_WINANSI = 1004
data/lib/win/error.rb CHANGED
@@ -7,7 +7,7 @@ module Win
7
7
  # other modules may contain additional error codes specific to their domain.
8
8
  #
9
9
  module Error
10
- include Win::Library
10
+ extend Win::Library
11
11
 
12
12
  #Error codes:
13
13
 
@@ -8,7 +8,7 @@ module Win
8
8
  # Windows dialog basics can be found here:
9
9
  # http://msdn.microsoft.com/en-us/library/ms644996#init_box
10
10
  module Dialog
11
- include Win::Library
11
+ extend Win::Library
12
12
  include Win::Gui::Window
13
13
 
14
14
  # Message Box flags:
@@ -300,6 +300,36 @@ module Win
300
300
  caption_pointer = FFI::MemoryPointer.from_string(caption)
301
301
  api.call handle, text_pointer, caption_pointer, type }
302
302
 
303
+ ##
304
+ # The GetDlgCtrlID function retrieves the identifier of the specified control. In other words,
305
+ # you give it a handle (say, for a button window inside a dialog), and it returns control ID
306
+ # that this window is associated with (say IDOK - meaning this window is in fact "OK" button.
307
+ #
308
+ # [*Syntax*] int GetDlgCtrlID( HWND hwndCtl );
309
+ #
310
+ # hwndCtl:: [in] Handle to the control.
311
+ #
312
+ # *Returns*:: If the function succeeds, the return value is the identifier of the control.
313
+ # If the function fails, the return value is zero. An invalid value for the hwndCtl parameter, for
314
+ # example, will cause the function to fail. To get extended error information, call GetLastError.
315
+ # ---
316
+ # *Remarks*:
317
+ # GetDlgCtrlID accepts child window handles as well as handles of controls in dialog boxes. An
318
+ # application sets the identifier for a child window when it creates the window by assigning the
319
+ # identifier value to the hmenu parameter when calling the CreateWindow or CreateWindowEx function.
320
+ # Although GetDlgCtrlID may return a value if hwndCtl is a handle to a top-level window, top-level
321
+ # windows cannot have identifiers and such a return value is never valid.
322
+ # ---
323
+ # *See* *Also*
324
+ # Dialog Boxes Overview, CreateWindow, CreateWindowEx, GetDlgItem
325
+ # ---
326
+ # <b>Enhanced (snake_case) API: returns nil instead of zero if function fails</b>
327
+ #
328
+ # :call-seq:
329
+ # control_id = get_dlg_ctrl_id(control_handle)
330
+ #
331
+ function :GetDlgCtrlID, [:HWND], :int, zeronil: true
332
+
303
333
  # Untested:
304
334
 
305
335
  ##
@@ -315,8 +345,6 @@ module Win
315
345
  ##
316
346
  function :GetDialogBaseUnits, 'V', 'L'
317
347
  ##
318
- function :GetDlgCtrlID, 'L', 'I'
319
- ##
320
348
  function :GetDlgItemText, 'LIPI', 'I'
321
349
  ##
322
350
  function :GetNextDlgGroupItem, 'LLI', 'L'
data/lib/win/gui/input.rb CHANGED
@@ -5,7 +5,7 @@ module Win
5
5
  # Contains constants and Win32API functions related to end user input
6
6
  #
7
7
  module Input
8
- include Win::Library
8
+ extend Win::Library
9
9
 
10
10
  # Windows defined constants:
11
11
 
@@ -39,7 +39,7 @@ module Win
39
39
  # WM:: General window
40
40
 
41
41
  module Message
42
- include Win::Library
42
+ extend Win::Library
43
43
 
44
44
  # General window messages cover a wide range of information and requests, including messages for mouse and
45
45
  # keyboard input, menu and dialog box input, window creation and management, and Dynamic Data Exchange (DDE).
@@ -505,6 +505,13 @@ module Win
505
505
  #
506
506
  function :SendMessage, [:ulong, :uint, :uint, :pointer], :int # LPARAM different from PostMessage!
507
507
 
508
+ ##
509
+ # :method: :SendMessageLong?
510
+ # We need to attach another SendMessage function, this time accepting :long instead of :pointer lParam.
511
+ # I do not know yet how to make FFI attach functions with same name, but different signature...
512
+ #
513
+ # function :SendMessage, [:ulong, :uint, :uint, :long], :int, alias: send_message_long?
514
+
508
515
  ##
509
516
  # The GetMessage function retrieves a message from the calling thread's message queue. The function
510
517
  # dispatches incoming sent messages until a posted message is available for retrieval.
@@ -6,7 +6,7 @@ module Win
6
6
  # Contains constants and Win32API functions related to window manipulation
7
7
  #
8
8
  module Window
9
- include Win::Library
9
+ extend Win::Library
10
10
 
11
11
  # ShowWindow constants:
12
12
 
@@ -390,7 +390,7 @@ module Win
390
390
  &->(api, handle, cmd=SW_SHOW) { api.call handle, cmd }
391
391
 
392
392
  ##
393
- # The CloseWindow function minimizes (but does not destroy) the specified window.
393
+ # The CloseWindow function MINIMIZES (but does not destroy) the specified window.
394
394
  #
395
395
  # [*Syntax*]: BOOL CloseWindow( HWND hWnd );
396
396
  #
@@ -451,7 +451,7 @@ module Win
451
451
  # *Returns*: Pair of identifiers of the thread and process_id that created the window.
452
452
  #
453
453
  #:call-seq:
454
- # thread, process_id = [get_]window_tread_process_id( win_handle )
454
+ # thread, process_id = [get_]window_thread_process_id( win_handle )
455
455
  #
456
456
  function :GetWindowThreadProcessId, [:HWND, :pointer], :long,
457
457
  &->(api, handle) {
@@ -812,7 +812,7 @@ module Win
812
812
  #
813
813
  function :GetAncestor, [:HWND, :UINT], :HWND, zeronil: true
814
814
 
815
-
815
+
816
816
  # Convenience wrapper methods:
817
817
 
818
818
  ##
data/lib/win/library.rb CHANGED
@@ -26,6 +26,399 @@ module Win
26
26
  # behavior you need.
27
27
  #
28
28
  module Library
29
+ include FFI::Library
30
+
31
+ # Mapping of Windows API types and one-letter shortcuts into FFI types.
32
+ # Like :ATOM => :ushort, :LPARAM => :long, :c => :char, :i => :int
33
+ TYPES = {
34
+ # FFI type shortcuts
35
+ C: :uchar, #– 8-bit unsigned character (byte)
36
+ c: :char, # 8-bit character (byte)
37
+ # :int8 – 8-bit signed integer
38
+ # :uint8 – 8-bit unsigned integer
39
+ S: :ushort, # – 16-bit unsigned integer (Win32/API: S used for string params)
40
+ s: :short, # – 16-bit signed integer
41
+ # :uint16 – 16-bit unsigned integer
42
+ # :int16 – 16-bit signed integer
43
+ I: :uint, # 32-bit unsigned integer
44
+ i: :int, # 32-bit signed integer
45
+ # :uint32 – 32-bit unsigned integer
46
+ # :int32 – 32-bit signed integer
47
+ L: :ulong, # unsigned long int – platform-specific size
48
+ l: :long, # long int – platform-specific size. For discussion of platforms, see:
49
+ # (http://groups.google.com/group/ruby-ffi/browse_thread/thread/4762fc77130339b1)
50
+ # :int64 – 64-bit signed integer
51
+ # :uint64 – 64-bit unsigned integer
52
+ # :long_long – 64-bit signed integer
53
+ # :ulong_long – 64-bit unsigned integer
54
+ F: :float, # 32-bit floating point
55
+ D: :double, # 64-bit floating point (double-precision)
56
+ P: :pointer, # pointer – platform-specific size
57
+ p: :string, # C-style (NULL-terminated) character string (Win32API: S)
58
+ B: :bool, # (?? 1 byte in C++)
59
+ V: :void, # For functions that return nothing (return type void).
60
+ v: :void, # For functions that return nothing (return type void).
61
+ # For function argument type only:
62
+ # :buffer_in – Similar to :pointer, but optimized for Buffers that the function can only read (not write).
63
+ # :buffer_out – Similar to :pointer, but optimized for Buffers that the function can only write (not read).
64
+ # :buffer_inout – Similar to :pointer, but may be optimized for Buffers.
65
+ # :varargs – Variable arguments
66
+ # :enum - Enumerable type (should be defined)
67
+ # :char_array - ??
68
+
69
+ # Windows-specific type defs (ms-help://MS.MSDNQTR.v90.en/winprog/winprog/windows_data_types.htm):
70
+ ATOM: :ushort, # Atom ~= Symbol: Atom table stores strings and corresponding identifiers. Application
71
+ # places a string in an atom table and receives a 16-bit integer, called an atom, that
72
+ # can be used to access the string. Placed string is called an atom name.
73
+ # See: http://msdn.microsoft.com/en-us/library/ms648708%28VS.85%29.aspx
74
+ BOOL: :bool,
75
+ BOOLEAN: :bool,
76
+ BYTE: :uchar, # Byte (8 bits). Declared as unsigned char
77
+ #CALLBACK: K, # Win32.API gem-specific ?? MSDN: #define CALLBACK __stdcall
78
+ CHAR: :char, # 8-bit Windows (ANSI) character. See http://msdn.microsoft.com/en-us/library/dd183415%28VS.85%29.aspx
79
+ COLORREF: :uint32, # Red, green, blue (RGB) color value (32 bits). See COLORREF for more info.
80
+ DWORD: :uint32, # 32-bit unsigned integer. The range is 0 through 4,294,967,295 decimal.
81
+ DWORDLONG: :uint64, # 64-bit unsigned integer. The range is 0 through 18,446,744,073,709,551,615 decimal.
82
+ DWORD_PTR: :ulong, # Unsigned long type for pointer precision. Use when casting a pointer to a long type
83
+ # to perform pointer arithmetic. (Also commonly used for general 32-bit parameters that have
84
+ # been extended to 64 bits in 64-bit Windows.) BaseTsd.h: #typedef ULONG_PTR DWORD_PTR;
85
+ DWORD32: :uint32,
86
+ DWORD64: :uint64,
87
+ HALF_PTR: :int, # Half the size of a pointer. Use within a structure that contains a pointer and two small fields.
88
+ # BaseTsd.h: #ifdef (_WIN64) typedef int HALF_PTR; #else typedef short HALF_PTR;
89
+ HACCEL: :ulong, # (L) Handle to an accelerator table. WinDef.h: #typedef HANDLE HACCEL;
90
+ # See http://msdn.microsoft.com/en-us/library/ms645526%28VS.85%29.aspx
91
+ HANDLE: :ulong, # (L) Handle to an object. WinNT.h: #typedef PVOID HANDLE;
92
+ # todo: Platform-dependent! Need to change to :uint64 for Win64
93
+ HBITMAP: :ulong, # (L) Handle to a bitmap: http://msdn.microsoft.com/en-us/library/dd183377%28VS.85%29.aspx
94
+ HBRUSH: :ulong, # (L) Handle to a brush. http://msdn.microsoft.com/en-us/library/dd183394%28VS.85%29.aspx
95
+ HCOLORSPACE: :ulong, # (L) Handle to a color space. http://msdn.microsoft.com/en-us/library/ms536546%28VS.85%29.aspx
96
+ HCURSOR: :ulong, # (L) Handle to a cursor. http://msdn.microsoft.com/en-us/library/ms646970%28VS.85%29.aspx
97
+ HCONV: :ulong, # (L) Handle to a dynamic data exchange (DDE) conversation.
98
+ HCONVLIST: :ulong, # (L) Handle to a DDE conversation list. HANDLE - L ?
99
+ HDDEDATA: :ulong, # (L) Handle to DDE data (structure?)
100
+ HDC: :ulong, # (L) Handle to a device context (DC). http://msdn.microsoft.com/en-us/library/dd183560%28VS.85%29.aspx
101
+ HDESK: :ulong, # (L) Handle to a desktop. http://msdn.microsoft.com/en-us/library/ms682573%28VS.85%29.aspx
102
+ HDROP: :ulong, # (L) Handle to an internal drop structure.
103
+ HDWP: :ulong, # (L) Handle to a deferred window position structure.
104
+ HENHMETAFILE: :ulong, #(L) Handle to an enhanced metafile. http://msdn.microsoft.com/en-us/library/dd145051%28VS.85%29.aspx
105
+ HFILE: :uint, # (I) Special file handle to a file opened by OpenFile, not CreateFile.
106
+ # WinDef.h: #typedef int HFILE;
107
+ HFONT: :ulong, # (L) Handle to a font. http://msdn.microsoft.com/en-us/library/dd162470%28VS.85%29.aspx
108
+ HGDIOBJ: :ulong, # (L) Handle to a GDI object.
109
+ HGLOBAL: :ulong, # (L) Handle to a global memory block.
110
+ HHOOK: :ulong, # (L) Handle to a hook. http://msdn.microsoft.com/en-us/library/ms632589%28VS.85%29.aspx
111
+ HICON: :ulong, # (L) Handle to an icon. http://msdn.microsoft.com/en-us/library/ms646973%28VS.85%29.aspx
112
+ HINSTANCE: :ulong, # (L) Handle to an instance. This is the base address of the module in memory.
113
+ # HMODULE and HINSTANCE are the same today, but were different in 16-bit Windows.
114
+ HKEY: :ulong, # (L) Handle to a registry key.
115
+ HKL: :ulong, # (L) Input locale identifier.
116
+ HLOCAL: :ulong, # (L) Handle to a local memory block.
117
+ HMENU: :ulong, # (L) Handle to a menu. http://msdn.microsoft.com/en-us/library/ms646977%28VS.85%29.aspx
118
+ HMETAFILE: :ulong, # (L) Handle to a metafile. http://msdn.microsoft.com/en-us/library/dd145051%28VS.85%29.aspx
119
+ HMODULE: :ulong, # (L) Handle to an instance. Same as HINSTANCE today, but was different in 16-bit Windows.
120
+ HMONITOR: :ulong, # (L) Рandle to a display monitor. WinDef.h: if(WINVER >= 0x0500) typedef HANDLE HMONITOR;
121
+ HPALETTE: :ulong, # (L) Handle to a palette.
122
+ HPEN: :ulong, # (L) Handle to a pen. http://msdn.microsoft.com/en-us/library/dd162786%28VS.85%29.aspx
123
+ HRESULT: :long, # Return code used by COM interfaces. For more info, Structure of the COM Error Codes.
124
+ # To test an HRESULT value, use the FAILED and SUCCEEDED macros.
125
+ HRGN: :ulong, # (L) Handle to a region. http://msdn.microsoft.com/en-us/library/dd162913%28VS.85%29.aspx
126
+ HRSRC: :ulong, # (L) Handle to a resource.
127
+ HSZ: :ulong, # (L) Handle to a DDE string.
128
+ HWINSTA: :ulong, # (L) Handle to a window station. http://msdn.microsoft.com/en-us/library/ms687096%28VS.85%29.aspx
129
+ HWND: :ulong, # (L) Handle to a window. http://msdn.microsoft.com/en-us/library/ms632595%28VS.85%29.aspx
130
+ INT: :int, # 32-bit signed integer. The range is -2147483648 through 2147483647 decimal.
131
+ INT_PTR: :int, # Signed integer type for pointer precision. Use when casting a pointer to an integer
132
+ # to perform pointer arithmetic. BaseTsd.h:
133
+ #if defined(_WIN64) typedef __int64 INT_PTR; #else typedef int INT_PTR;
134
+ INT32: :int32, # 32-bit signed integer. The range is -2,147,483,648 through +...647 decimal.
135
+ INT64: :int64, # 64-bit signed integer. The range is –9,223,372,036,854,775,808 through +...807
136
+ LANGID: :ushort, # Language identifier. For more information, see Locales. WinNT.h: #typedef WORD LANGID;
137
+ # See http://msdn.microsoft.com/en-us/library/dd318716%28VS.85%29.aspx
138
+ LCID: :uint32, # Locale identifier. For more information, see Locales.
139
+ LCTYPE: :uint32, # Locale information type. For a list, see Locale Information Constants.
140
+ LGRPID: :uint32, # Language group identifier. For a list, see EnumLanguageGroupLocales.
141
+ LONG: :long, # 32-bit signed integer. The range is -2,147,483,648 through +...647 decimal.
142
+ LONG32: :int32, # 32-bit signed integer. The range is -2,147,483,648 through +...647 decimal.
143
+ LONG64: :int64, # 64-bit signed integer. The range is –9,223,372,036,854,775,808 through +...807
144
+ LONGLONG: :int64, # 64-bit signed integer. The range is –9,223,372,036,854,775,808 through +...807
145
+ LONG_PTR: :long, # Signed long type for pointer precision. Use when casting a pointer to a long to
146
+ # perform pointer arithmetic. BaseTsd.h:
147
+ #if defined(_WIN64) typedef __int64 LONG_PTR; #else typedef long LONG_PTR;
148
+ LPARAM: :long, # Message parameter. WinDef.h as follows: #typedef LONG_PTR LPARAM;
149
+ LPBOOL: :pointer, # Pointer to a BOOL. WinDef.h as follows: #typedef BOOL far *LPBOOL;
150
+ LPBYTE: :pointer, # Pointer to a BYTE. WinDef.h as follows: #typedef BYTE far *LPBYTE;
151
+ LPCOLORREF: :pointer, # Pointer to a COLORREF value. WinDef.h as follows: #typedef DWORD *LPCOLORREF;
152
+ LPCSTR: :pointer, # Pointer to a constant null-terminated string of 8-bit Windows (ANSI) characters.
153
+ # See Character Sets Used By Fonts. http://msdn.microsoft.com/en-us/library/dd183415%28VS.85%29.aspx
154
+ LPCTSTR: :pointer, # An LPCWSTR if UNICODE is defined, an LPCSTR otherwise.
155
+ LPCVOID: :pointer, # Pointer to a constant of any type. WinDef.h as follows: typedef CONST void *LPCVOID;
156
+ LPCWSTR: :pointer, # Pointer to a constant null-terminated string of 16-bit Unicode characters.
157
+ LPDWORD: :pointer, # Pointer to a DWORD. WinDef.h as follows: typedef DWORD *LPDWORD;
158
+ LPHANDLE: :pointer, # Pointer to a HANDLE. WinDef.h as follows: typedef HANDLE *LPHANDLE;
159
+ LPINT: :pointer, # Pointer to an INT.
160
+ LPLONG: :pointer, # Pointer to an LONG.
161
+ LPSTR: :pointer, # Pointer to a null-terminated string of 8-bit Windows (ANSI) characters.
162
+ LPTSTR: :pointer, # An LPWSTR if UNICODE is defined, an LPSTR otherwise.
163
+ LPVOID: :pointer, # Pointer to any type.
164
+ LPWORD: :pointer, # Pointer to a WORD.
165
+ LPWSTR: :pointer, # Pointer to a null-terminated string of 16-bit Unicode characters.
166
+ LRESULT: :long, # Signed result of message processing. WinDef.h: typedef LONG_PTR LRESULT;
167
+ PBOOL: :pointer, # Pointer to a BOOL.
168
+ PBOOLEAN: :pointer, # Pointer to a BOOL.
169
+ PBYTE: :pointer, # Pointer to a BYTE.
170
+ PCHAR: :pointer, # Pointer to a CHAR.
171
+ PCSTR: :pointer, # Pointer to a constant null-terminated string of 8-bit Windows (ANSI) characters.
172
+ PCTSTR: :pointer, # A PCWSTR if UNICODE is defined, a PCSTR otherwise.
173
+ PCWSTR: :pointer, # Pointer to a constant null-terminated string of 16-bit Unicode characters.
174
+ PDWORD: :pointer, # Pointer to a DWORD.
175
+ PDWORDLONG: :pointer, # Pointer to a DWORDLONG.
176
+ PDWORD_PTR: :pointer, # Pointer to a DWORD_PTR.
177
+ PDWORD32: :pointer, # Pointer to a DWORD32.
178
+ PDWORD64: :pointer, # Pointer to a DWORD64.
179
+ PFLOAT: :pointer, # Pointer to a FLOAT.
180
+ PHALF_PTR: :pointer, # Pointer to a HALF_PTR.
181
+ PHANDLE: :pointer, # Pointer to a HANDLE.
182
+ PHKEY: :pointer, # Pointer to an HKEY.
183
+ PINT: :pointer, # Pointer to an INT.
184
+ PINT_PTR: :pointer, # Pointer to an INT_PTR.
185
+ PINT32: :pointer, # Pointer to an INT32.
186
+ PINT64: :pointer, # Pointer to an INT64.
187
+ PLCID: :pointer, # Pointer to an LCID.
188
+ PLONG: :pointer, # Pointer to a LONG.
189
+ PLONGLONG: :pointer, # Pointer to a LONGLONG.
190
+ PLONG_PTR: :pointer, # Pointer to a LONG_PTR.
191
+ PLONG32: :pointer, # Pointer to a LONG32.
192
+ PLONG64: :pointer, # Pointer to a LONG64.
193
+ 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.
194
+ 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.
195
+ POINTER_SIGNED: :pointer, # A signed pointer.
196
+ POINTER_UNSIGNED: :pointer, # An unsigned pointer.
197
+ PSHORT: :pointer, # Pointer to a SHORT.
198
+ PSIZE_T: :pointer, # Pointer to a SIZE_T.
199
+ PSSIZE_T: :pointer, # Pointer to a SSIZE_T.
200
+ PSTR: :pointer, # Pointer to a null-terminated string of 8-bit Windows (ANSI) characters. For more information, see Character Sets Used By Fonts.
201
+ PTBYTE: :pointer, # Pointer to a TBYTE.
202
+ PTCHAR: :pointer, # Pointer to a TCHAR.
203
+ PTSTR: :pointer, # A PWSTR if UNICODE is defined, a PSTR otherwise.
204
+ PUCHAR: :pointer, # Pointer to a UCHAR.
205
+ PUHALF_PTR: :pointer, # Pointer to a UHALF_PTR.
206
+ PUINT: :pointer, # Pointer to a UINT.
207
+ PUINT_PTR: :pointer, # Pointer to a UINT_PTR.
208
+ PUINT32: :pointer, # Pointer to a UINT32.
209
+ PUINT64: :pointer, # Pointer to a UINT64.
210
+ PULONG: :pointer, # Pointer to a ULONG.
211
+ PULONGLONG: :pointer, # Pointer to a ULONGLONG.
212
+ PULONG_PTR: :pointer, # Pointer to a ULONG_PTR.
213
+ PULONG32: :pointer, # Pointer to a ULONG32.
214
+ PULONG64: :pointer, # Pointer to a ULONG64.
215
+ PUSHORT: :pointer, # Pointer to a USHORT.
216
+ PVOID: :pointer, # Pointer to any type.
217
+ PWCHAR: :pointer, # Pointer to a WCHAR.
218
+ PWORD: :pointer, # Pointer to a WORD.
219
+ PWSTR: :pointer, # Pointer to a null- terminated string of 16-bit Unicode characters.
220
+ # For more information, see Character Sets Used By Fonts.
221
+ SC_HANDLE: :ulong, # (L) Handle to a service control manager database.
222
+ # See SCM Handles http://msdn.microsoft.com/en-us/library/ms685104%28VS.85%29.aspx
223
+ SC_LOCK: :pointer, # Lock to a service control manager database. For more information, see SCM Handles.
224
+ SERVICE_STATUS_HANDLE: :ulong, # (L) Handle to a service status value. See SCM Handles.
225
+ SHORT: :short, # A 16-bit integer. The range is –32768 through 32767 decimal.
226
+ 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.
227
+ SSIZE_T: :long, # Signed SIZE_T.
228
+ TBYTE: :short, # A WCHAR if UNICODE is defined, a CHAR otherwise.TCHAR:
229
+ TCHAR: :short, # A WCHAR if UNICODE is defined, a CHAR otherwise.TCHAR:
230
+ UCHAR: :uchar, # Unsigned CHAR (8 bit)
231
+ UHALF_PTR: :uint, # Unsigned HALF_PTR. Use within a structure that contains a pointer and two small fields.
232
+ UINT: :uint, # Unsigned INT. The range is 0 through 4294967295 decimal.
233
+ UINT_PTR: :uint, # Unsigned INT_PTR.
234
+ UINT32: :uint32, # Unsigned INT32. The range is 0 through 4294967295 decimal.
235
+ UINT64: :uint64, # Unsigned INT64. The range is 0 through 18446744073709551615 decimal.
236
+ ULONG: :ulong, # Unsigned LONG. The range is 0 through 4294967295 decimal.
237
+ ULONGLONG: :ulong_long, # 64-bit unsigned integer. The range is 0 through 18446744073709551615 decimal.
238
+ ULONG_PTR: :ulong, # Unsigned LONG_PTR.
239
+ ULONG32: :uint32, # Unsigned INT32. The range is 0 through 4294967295 decimal.
240
+ ULONG64: :uint64, # Unsigned LONG64. The range is 0 through 18446744073709551615 decimal.
241
+ UNICODE_STRING: :pointer, # Pointer to some string structure??
242
+ USHORT: :ushort, # Unsigned SHORT. The range is 0 through 65535 decimal.
243
+ USN: :ulong_long, # Update sequence number (USN).
244
+ VOID: [], # Any type ? Only use it to indicate no arguments or no return value
245
+ WCHAR: :ushort, # 16-bit Unicode character. For more information, see Character Sets Used By Fonts.
246
+ # In WinNT.h: typedef wchar_t WCHAR;
247
+ #WINAPI: K, # Calling convention for system functions. WinDef.h: define WINAPI __stdcall
248
+ WORD: :ushort, # 16-bit unsigned integer. The range is 0 through 65535 decimal.
249
+ WPARAM: :uint # Message parameter. WinDef.h as follows: typedef UINT_PTR WPARAM;
250
+ }
251
+
252
+ ##
253
+ # Defines new method wrappers for Windows API function call:
254
+ # - Defines method with original (CamelCase) API function name and original signature (matches MSDN description)
255
+ # - Defines method with snake_case name (converted from CamelCase function name) with enhanced API signature
256
+ # When defined snake_case method is called, it converts the arguments you provided into ones required by
257
+ # original API (adding defaults, mute and transitory args as necessary), executes API function call
258
+ # and (optionally) transforms the result before returning it. If a block is attached to
259
+ # method invocation, raw result is yielded to this block before final transformation take place
260
+ # - Defines aliases for enhanced method with more Rubyesque names for getters, setters and tests:
261
+ # GetWindowText -> window_test, SetWindowText -> window_text=, IsZoomed -> zoomed?
262
+ # ---
263
+ # You may modify default behavior of defined method by providing optional *def_block* to function definition.
264
+ # If you do so, snake_case method is defined based on your *def_block*. It receives callable API
265
+ # object for function being defined, arguments and (optional) runtime block with which the method
266
+ # will be called. Results coming from &def_block are then transformed and returned.
267
+ # So, your *def_block* should specify all the behavior of the method being defined. You can use *def_block* to:
268
+ # - Change original signature of API function, provide argument defaults, check argument types
269
+ # - Pack arguments into strings/structs for <in> or <in/out> parameters that expect a pointer
270
+ # - Allocate buffers/structs for pointers required by API functions <out> parameters
271
+ # - Unpack <out> and <in/out> parameters returned as pointers
272
+ # - Explicitly return results of API call that are returned in <out> and <in/out> parameters
273
+ # - Convert attached runtime blocks into callback functions and stuff them into <in> callback parameters
274
+ # - do other stuff that you think is appropriate to make Windows API function behavior more Ruby-like...
275
+ # ---
276
+ # Accepts following options:
277
+ # :dll:: Use this dll instead of default 'user32'
278
+ # :rename:: Use this name instead of standard (conventional) function name
279
+ # :alias(es):: Provides additional alias(es) for defined method
280
+ # :boolean:: Forces method to return true/false instead of nonzero/zero
281
+ # :zeronil:: Forces method to return nil if function result is zero
282
+ #
283
+ def function(name, params, returns, options={}, &def_block)
284
+ snake_name, effective_names, aliases = generate_names(name, options)
285
+ params, returns = generate_signature(params, returns)
286
+ libs = ffi_libraries.map(&:name)
287
+ boolean = options[:boolean]
288
+ zeronil = options[:zeronil]
289
+
290
+ effective_name = effective_names.inject(nil) do |func, effective_name|
291
+ func || begin
292
+ # tries to attach basic CamelCase method via FFI
293
+ attach_function(name, effective_name, params.dup, returns)
294
+ effective_name
295
+ rescue FFI::NotFoundError
296
+ nil
297
+ end
298
+ end
299
+
300
+ raise Win::Errors::NotFoundError.new(name, libs) unless effective_name
301
+
302
+ # Create API object that holds information about function names, params, etc
303
+ api = API.new(namespace, name, effective_name, params, returns, libs)
304
+
305
+ # Only define enhanced API if snake_name is different from original name (e.g. keybd_event),
306
+ # If names are the same, this function is already "attached", not possible to enhance its API
307
+ unless snake_name.to_s == name.to_s
308
+ method_body = if def_block
309
+ if zeronil
310
+ ->(*args, &block){ (res = def_block.(api, *args, &block)) != 0 ? res : nil }
311
+ elsif boolean
312
+ ->(*args, &block){ def_block.(api, *args, &block) != 0 }
313
+ else
314
+ ->(*args, &block){ def_block.(api, *args, &block) }
315
+ end
316
+ else
317
+ if zeronil
318
+ ->(*args, &block){ (res = block ? block[api.call(*args)] : api.call(*args)) != 0 ? res : nil }
319
+ elsif boolean
320
+ ->(*args, &block){ block ? block[api.call(*args)] : api.call(*args) != 0 }
321
+ else
322
+ ->(*args, &block){ block ? block[api.call(*args)] : api.call(*args) }
323
+ end
324
+ end
325
+
326
+ define_method snake_name, &method_body # define snake_case instance method
327
+
328
+ # module_function snake_name # TODO: Doesn't work as a perfect replacement for eigen_class stuff. :( Why?
329
+
330
+ eigen_class = class << self;
331
+ self;
332
+ end # Extracting eigenclass
333
+
334
+ eigen_class.class_eval do
335
+ define_method snake_name, &method_body # define snake_case class method
336
+ end
337
+ end
338
+
339
+ aliases.each {|ali| alias_method ali, snake_name } # define aliases
340
+ api #return api object from function declaration
341
+ end
342
+
343
+ # Try to define platform-specific function, rescue error, return message
344
+ #
345
+ def try_function(name, params, returns, options={}, &def_block)
346
+ begin
347
+ function name, params, returns, options={}, &def_block
348
+ rescue Win::Errors::NotFoundError
349
+ "This platform does not support function #{name}"
350
+ end
351
+ end
352
+
353
+ # Generates possible effective names for function in Win32 dll (name+A/W),
354
+ # Rubyesque name and aliases for method(s) defined based on function name,
355
+ #
356
+ def generate_names(name, options={})
357
+ name = name.to_s
358
+ effective_names = [name]
359
+ effective_names += ["#{name}A", "#{name}W"] unless name =~ /[WA]$/
360
+ aliases = ([options[:alias]] + [options[:aliases]]).flatten.compact
361
+ snake_name = options[:rename] || name.snake_case
362
+ case snake_name
363
+ when /^is_/
364
+ aliases << snake_name.sub(/^is_/, '') + '?'
365
+ when /^set_/
366
+ aliases << snake_name.sub(/^set_/, '')+ '='
367
+ when /^get_/
368
+ aliases << snake_name.sub(/^get_/, '')
369
+ end
370
+ [snake_name, effective_names, aliases]
371
+ end
372
+
373
+ ##
374
+ # Generates params and returns (signature) containing only FFI-compliant types
375
+ #
376
+ def generate_signature(params, returns)
377
+ params = params.split(//) if params.respond_to?(:split) # Convert params string into array
378
+ params.map! {|param| TYPES[param.to_sym] || param} # Convert chars into FFI type symbols
379
+ returns = TYPES[returns.to_sym] || returns # Convert chars into FFI type symbols
380
+ [params, returns]
381
+ end
382
+
383
+ ##
384
+ # Wrapper for FFI::Library.callback() that converts Win32/shortcut argument types into FFI-compliant types.
385
+ # This method overrides FFI::Library.callback
386
+ #
387
+ def callback(name, params, returns)
388
+ params, returns = generate_signature(params, returns)
389
+ super name.to_sym, params, returns
390
+ end
391
+
392
+ ##
393
+ # :method: namespace
394
+ # This method is meta-generated when Win::Library module is included into other module/class.
395
+ # It returns reference to including (host) class/module for use by Win::Library::API and class methods.
396
+
397
+ ##
398
+ # Ensures that args count is equal to params count plus diff
399
+ #
400
+ def enforce_count(args, params, diff = 0)
401
+ num_args = args.size
402
+ num_params = params.size + diff #params == 'V' ? 0 : params.size + diff
403
+ if num_args != num_params
404
+ raise ArgumentError, "wrong number of arguments (#{num_args} for #{num_params})"
405
+ end
406
+ end
407
+
408
+ ##
409
+ # Hook executed when Win::Library extends other module or class. It adds namespace method pointing
410
+ # to host module/class that is used by Win::Library to invoke attached (CamelCase) functions.
411
+ # Also sets default ffi libs and calling conventions.
412
+ def self.extended(host)
413
+
414
+ host.module_eval do
415
+ define_method(:namespace) {host}
416
+ module_function :namespace
417
+ end
418
+
419
+ host.ffi_lib 'user32', 'kernel32' # Default libraries
420
+ host.ffi_convention :stdcall
421
+ end
29
422
 
30
423
  # Win::Library::API is a wrapper for callable function API object that mimics Win32::API
31
424
  class API
@@ -63,407 +456,7 @@ module Win
63
456
  @namespace.send(@function_name.to_sym, *args)
64
457
  end
65
458
 
66
- # alias_method :[], :call
67
- end
68
-
69
- # Contains class methods (macros) that can be used in any module mixing in Win::Library
70
- module ClassMethods
71
-
72
- # Mapping of Windows API types and one-letter shortcuts into FFI types.
73
- # Like :ATOM => :ushort, :LPARAM => :long, :c => :char, :i => :int
74
- TYPES = {
75
- # FFI type shortcuts
76
- C: :uchar, #– 8-bit unsigned character (byte)
77
- c: :char, # 8-bit character (byte)
78
- # :int8 – 8-bit signed integer
79
- # :uint8 – 8-bit unsigned integer
80
- S: :ushort, # – 16-bit unsigned integer (Win32/API: S used for string params)
81
- s: :short, # – 16-bit signed integer
82
- # :uint16 – 16-bit unsigned integer
83
- # :int16 – 16-bit signed integer
84
- I: :uint, # 32-bit unsigned integer
85
- i: :int, # 32-bit signed integer
86
- # :uint32 – 32-bit unsigned integer
87
- # :int32 – 32-bit signed integer
88
- L: :ulong, # unsigned long int – platform-specific size
89
- l: :long, # long int – platform-specific size. For discussion of platforms, see:
90
- # (http://groups.google.com/group/ruby-ffi/browse_thread/thread/4762fc77130339b1)
91
- # :int64 – 64-bit signed integer
92
- # :uint64 – 64-bit unsigned integer
93
- # :long_long – 64-bit signed integer
94
- # :ulong_long – 64-bit unsigned integer
95
- F: :float, # 32-bit floating point
96
- D: :double, # 64-bit floating point (double-precision)
97
- P: :pointer, # pointer – platform-specific size
98
- p: :string, # C-style (NULL-terminated) character string (Win32API: S)
99
- B: :bool, # (?? 1 byte in C++)
100
- V: :void, # For functions that return nothing (return type void).
101
- v: :void, # For functions that return nothing (return type void).
102
- # For function argument type only:
103
- # :buffer_in – Similar to :pointer, but optimized for Buffers that the function can only read (not write).
104
- # :buffer_out – Similar to :pointer, but optimized for Buffers that the function can only write (not read).
105
- # :buffer_inout – Similar to :pointer, but may be optimized for Buffers.
106
- # :varargs – Variable arguments
107
- # :enum - Enumerable type (should be defined)
108
- # :char_array - ??
109
-
110
- # Windows-specific type defs (ms-help://MS.MSDNQTR.v90.en/winprog/winprog/windows_data_types.htm):
111
- ATOM: :ushort, # Atom ~= Symbol: Atom table stores strings and corresponding identifiers. Application
112
- # places a string in an atom table and receives a 16-bit integer, called an atom, that
113
- # can be used to access the string. Placed string is called an atom name.
114
- # See: http://msdn.microsoft.com/en-us/library/ms648708%28VS.85%29.aspx
115
- BOOL: :bool,
116
- BOOLEAN: :bool,
117
- BYTE: :uchar, # Byte (8 bits). Declared as unsigned char
118
- #CALLBACK: K, # Win32.API gem-specific ?? MSDN: #define CALLBACK __stdcall
119
- CHAR: :char, # 8-bit Windows (ANSI) character. See http://msdn.microsoft.com/en-us/library/dd183415%28VS.85%29.aspx
120
- COLORREF: :uint32, # Red, green, blue (RGB) color value (32 bits). See COLORREF for more info.
121
- DWORD: :uint32, # 32-bit unsigned integer. The range is 0 through 4,294,967,295 decimal.
122
- DWORDLONG: :uint64, # 64-bit unsigned integer. The range is 0 through 18,446,744,073,709,551,615 decimal.
123
- DWORD_PTR: :ulong, # Unsigned long type for pointer precision. Use when casting a pointer to a long type
124
- # to perform pointer arithmetic. (Also commonly used for general 32-bit parameters that have
125
- # been extended to 64 bits in 64-bit Windows.) BaseTsd.h: #typedef ULONG_PTR DWORD_PTR;
126
- DWORD32: :uint32,
127
- DWORD64: :uint64,
128
- HALF_PTR: :int, # Half the size of a pointer. Use within a structure that contains a pointer and two small fields.
129
- # BaseTsd.h: #ifdef (_WIN64) typedef int HALF_PTR; #else typedef short HALF_PTR;
130
- HACCEL: :ulong, # (L) Handle to an accelerator table. WinDef.h: #typedef HANDLE HACCEL;
131
- # See http://msdn.microsoft.com/en-us/library/ms645526%28VS.85%29.aspx
132
- HANDLE: :ulong, # (L) Handle to an object. WinNT.h: #typedef PVOID HANDLE;
133
- # todo: Platform-dependent! Need to change to :uint64 for Win64
134
- HBITMAP: :ulong, # (L) Handle to a bitmap: http://msdn.microsoft.com/en-us/library/dd183377%28VS.85%29.aspx
135
- HBRUSH: :ulong, # (L) Handle to a brush. http://msdn.microsoft.com/en-us/library/dd183394%28VS.85%29.aspx
136
- HCOLORSPACE: :ulong, # (L) Handle to a color space. http://msdn.microsoft.com/en-us/library/ms536546%28VS.85%29.aspx
137
- HCURSOR: :ulong, # (L) Handle to a cursor. http://msdn.microsoft.com/en-us/library/ms646970%28VS.85%29.aspx
138
- HCONV: :ulong, # (L) Handle to a dynamic data exchange (DDE) conversation.
139
- HCONVLIST: :ulong, # (L) Handle to a DDE conversation list. HANDLE - L ?
140
- HDDEDATA: :ulong, # (L) Handle to DDE data (structure?)
141
- HDC: :ulong, # (L) Handle to a device context (DC). http://msdn.microsoft.com/en-us/library/dd183560%28VS.85%29.aspx
142
- HDESK: :ulong, # (L) Handle to a desktop. http://msdn.microsoft.com/en-us/library/ms682573%28VS.85%29.aspx
143
- HDROP: :ulong, # (L) Handle to an internal drop structure.
144
- HDWP: :ulong, # (L) Handle to a deferred window position structure.
145
- HENHMETAFILE: :ulong, #(L) Handle to an enhanced metafile. http://msdn.microsoft.com/en-us/library/dd145051%28VS.85%29.aspx
146
- HFILE: :uint, # (I) Special file handle to a file opened by OpenFile, not CreateFile.
147
- # WinDef.h: #typedef int HFILE;
148
- HFONT: :ulong, # (L) Handle to a font. http://msdn.microsoft.com/en-us/library/dd162470%28VS.85%29.aspx
149
- HGDIOBJ: :ulong, # (L) Handle to a GDI object.
150
- HGLOBAL: :ulong, # (L) Handle to a global memory block.
151
- HHOOK: :ulong, # (L) Handle to a hook. http://msdn.microsoft.com/en-us/library/ms632589%28VS.85%29.aspx
152
- HICON: :ulong, # (L) Handle to an icon. http://msdn.microsoft.com/en-us/library/ms646973%28VS.85%29.aspx
153
- HINSTANCE: :ulong, # (L) Handle to an instance. This is the base address of the module in memory.
154
- # HMODULE and HINSTANCE are the same today, but were different in 16-bit Windows.
155
- HKEY: :ulong, # (L) Handle to a registry key.
156
- HKL: :ulong, # (L) Input locale identifier.
157
- HLOCAL: :ulong, # (L) Handle to a local memory block.
158
- HMENU: :ulong, # (L) Handle to a menu. http://msdn.microsoft.com/en-us/library/ms646977%28VS.85%29.aspx
159
- HMETAFILE: :ulong, # (L) Handle to a metafile. http://msdn.microsoft.com/en-us/library/dd145051%28VS.85%29.aspx
160
- HMODULE: :ulong, # (L) Handle to an instance. Same as HINSTANCE today, but was different in 16-bit Windows.
161
- HMONITOR: :ulong, # (L) Рandle to a display monitor. WinDef.h: if(WINVER >= 0x0500) typedef HANDLE HMONITOR;
162
- HPALETTE: :ulong, # (L) Handle to a palette.
163
- HPEN: :ulong, # (L) Handle to a pen. http://msdn.microsoft.com/en-us/library/dd162786%28VS.85%29.aspx
164
- HRESULT: :long, # Return code used by COM interfaces. For more info, Structure of the COM Error Codes.
165
- # To test an HRESULT value, use the FAILED and SUCCEEDED macros.
166
- HRGN: :ulong, # (L) Handle to a region. http://msdn.microsoft.com/en-us/library/dd162913%28VS.85%29.aspx
167
- HRSRC: :ulong, # (L) Handle to a resource.
168
- HSZ: :ulong, # (L) Handle to a DDE string.
169
- HWINSTA: :ulong, # (L) Handle to a window station. http://msdn.microsoft.com/en-us/library/ms687096%28VS.85%29.aspx
170
- HWND: :ulong, # (L) Handle to a window. http://msdn.microsoft.com/en-us/library/ms632595%28VS.85%29.aspx
171
- INT: :int, # 32-bit signed integer. The range is -2147483648 through 2147483647 decimal.
172
- INT_PTR: :int, # Signed integer type for pointer precision. Use when casting a pointer to an integer
173
- # to perform pointer arithmetic. BaseTsd.h:
174
- #if defined(_WIN64) typedef __int64 INT_PTR; #else typedef int INT_PTR;
175
- INT32: :int32, # 32-bit signed integer. The range is -2,147,483,648 through +...647 decimal.
176
- INT64: :int64, # 64-bit signed integer. The range is –9,223,372,036,854,775,808 through +...807
177
- LANGID: :ushort, # Language identifier. For more information, see Locales. WinNT.h: #typedef WORD LANGID;
178
- # See http://msdn.microsoft.com/en-us/library/dd318716%28VS.85%29.aspx
179
- LCID: :uint32, # Locale identifier. For more information, see Locales.
180
- LCTYPE: :uint32, # Locale information type. For a list, see Locale Information Constants.
181
- LGRPID: :uint32, # Language group identifier. For a list, see EnumLanguageGroupLocales.
182
- LONG: :long, # 32-bit signed integer. The range is -2,147,483,648 through +...647 decimal.
183
- LONG32: :int32, # 32-bit signed integer. The range is -2,147,483,648 through +...647 decimal.
184
- LONG64: :int64, # 64-bit signed integer. The range is –9,223,372,036,854,775,808 through +...807
185
- LONGLONG: :int64, # 64-bit signed integer. The range is –9,223,372,036,854,775,808 through +...807
186
- LONG_PTR: :long, # Signed long type for pointer precision. Use when casting a pointer to a long to
187
- # perform pointer arithmetic. BaseTsd.h:
188
- #if defined(_WIN64) typedef __int64 LONG_PTR; #else typedef long LONG_PTR;
189
- LPARAM: :long, # Message parameter. WinDef.h as follows: #typedef LONG_PTR LPARAM;
190
- LPBOOL: :pointer, # Pointer to a BOOL. WinDef.h as follows: #typedef BOOL far *LPBOOL;
191
- LPBYTE: :pointer, # Pointer to a BYTE. WinDef.h as follows: #typedef BYTE far *LPBYTE;
192
- LPCOLORREF: :pointer, # Pointer to a COLORREF value. WinDef.h as follows: #typedef DWORD *LPCOLORREF;
193
- LPCSTR: :pointer, # Pointer to a constant null-terminated string of 8-bit Windows (ANSI) characters.
194
- # See Character Sets Used By Fonts. http://msdn.microsoft.com/en-us/library/dd183415%28VS.85%29.aspx
195
- LPCTSTR: :pointer, # An LPCWSTR if UNICODE is defined, an LPCSTR otherwise.
196
- LPCVOID: :pointer, # Pointer to a constant of any type. WinDef.h as follows: typedef CONST void *LPCVOID;
197
- LPCWSTR: :pointer, # Pointer to a constant null-terminated string of 16-bit Unicode characters.
198
- LPDWORD: :pointer, # Pointer to a DWORD. WinDef.h as follows: typedef DWORD *LPDWORD;
199
- LPHANDLE: :pointer, # Pointer to a HANDLE. WinDef.h as follows: typedef HANDLE *LPHANDLE;
200
- LPINT: :pointer, # Pointer to an INT.
201
- LPLONG: :pointer, # Pointer to an LONG.
202
- LPSTR: :pointer, # Pointer to a null-terminated string of 8-bit Windows (ANSI) characters.
203
- LPTSTR: :pointer, # An LPWSTR if UNICODE is defined, an LPSTR otherwise.
204
- LPVOID: :pointer, # Pointer to any type.
205
- LPWORD: :pointer, # Pointer to a WORD.
206
- LPWSTR: :pointer, # Pointer to a null-terminated string of 16-bit Unicode characters.
207
- LRESULT: :long, # Signed result of message processing. WinDef.h: typedef LONG_PTR LRESULT;
208
- PBOOL: :pointer, # Pointer to a BOOL.
209
- PBOOLEAN: :pointer, # Pointer to a BOOL.
210
- PBYTE: :pointer, # Pointer to a BYTE.
211
- PCHAR: :pointer, # Pointer to a CHAR.
212
- PCSTR: :pointer, # Pointer to a constant null-terminated string of 8-bit Windows (ANSI) characters.
213
- PCTSTR: :pointer, # A PCWSTR if UNICODE is defined, a PCSTR otherwise.
214
- PCWSTR: :pointer, # Pointer to a constant null-terminated string of 16-bit Unicode characters.
215
- PDWORD: :pointer, # Pointer to a DWORD.
216
- PDWORDLONG: :pointer, # Pointer to a DWORDLONG.
217
- PDWORD_PTR: :pointer, # Pointer to a DWORD_PTR.
218
- PDWORD32: :pointer, # Pointer to a DWORD32.
219
- PDWORD64: :pointer, # Pointer to a DWORD64.
220
- PFLOAT: :pointer, # Pointer to a FLOAT.
221
- PHALF_PTR: :pointer, # Pointer to a HALF_PTR.
222
- PHANDLE: :pointer, # Pointer to a HANDLE.
223
- PHKEY: :pointer, # Pointer to an HKEY.
224
- PINT: :pointer, # Pointer to an INT.
225
- PINT_PTR: :pointer, # Pointer to an INT_PTR.
226
- PINT32: :pointer, # Pointer to an INT32.
227
- PINT64: :pointer, # Pointer to an INT64.
228
- PLCID: :pointer, # Pointer to an LCID.
229
- PLONG: :pointer, # Pointer to a LONG.
230
- PLONGLONG: :pointer, # Pointer to a LONGLONG.
231
- PLONG_PTR: :pointer, # Pointer to a LONG_PTR.
232
- PLONG32: :pointer, # Pointer to a LONG32.
233
- PLONG64: :pointer, # Pointer to a LONG64.
234
- 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.
235
- 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.
236
- POINTER_SIGNED: :pointer, # A signed pointer.
237
- POINTER_UNSIGNED: :pointer, # An unsigned pointer.
238
- PSHORT: :pointer, # Pointer to a SHORT.
239
- PSIZE_T: :pointer, # Pointer to a SIZE_T.
240
- PSSIZE_T: :pointer, # Pointer to a SSIZE_T.
241
- PSTR: :pointer, # Pointer to a null-terminated string of 8-bit Windows (ANSI) characters. For more information, see Character Sets Used By Fonts.
242
- PTBYTE: :pointer, # Pointer to a TBYTE.
243
- PTCHAR: :pointer, # Pointer to a TCHAR.
244
- PTSTR: :pointer, # A PWSTR if UNICODE is defined, a PSTR otherwise.
245
- PUCHAR: :pointer, # Pointer to a UCHAR.
246
- PUHALF_PTR: :pointer, # Pointer to a UHALF_PTR.
247
- PUINT: :pointer, # Pointer to a UINT.
248
- PUINT_PTR: :pointer, # Pointer to a UINT_PTR.
249
- PUINT32: :pointer, # Pointer to a UINT32.
250
- PUINT64: :pointer, # Pointer to a UINT64.
251
- PULONG: :pointer, # Pointer to a ULONG.
252
- PULONGLONG: :pointer, # Pointer to a ULONGLONG.
253
- PULONG_PTR: :pointer, # Pointer to a ULONG_PTR.
254
- PULONG32: :pointer, # Pointer to a ULONG32.
255
- PULONG64: :pointer, # Pointer to a ULONG64.
256
- PUSHORT: :pointer, # Pointer to a USHORT.
257
- PVOID: :pointer, # Pointer to any type.
258
- PWCHAR: :pointer, # Pointer to a WCHAR.
259
- PWORD: :pointer, # Pointer to a WORD.
260
- PWSTR: :pointer, # Pointer to a null- terminated string of 16-bit Unicode characters.
261
- # For more information, see Character Sets Used By Fonts.
262
- SC_HANDLE: :ulong, # (L) Handle to a service control manager database.
263
- # See SCM Handles http://msdn.microsoft.com/en-us/library/ms685104%28VS.85%29.aspx
264
- SC_LOCK: :pointer, # Lock to a service control manager database. For more information, see SCM Handles.
265
- SERVICE_STATUS_HANDLE: :ulong, # (L) Handle to a service status value. See SCM Handles.
266
- SHORT: :short, # A 16-bit integer. The range is –32768 through 32767 decimal.
267
- 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.
268
- SSIZE_T: :long, # Signed SIZE_T.
269
- TBYTE: :short, # A WCHAR if UNICODE is defined, a CHAR otherwise.TCHAR:
270
- TCHAR: :short, # A WCHAR if UNICODE is defined, a CHAR otherwise.TCHAR:
271
- UCHAR: :uchar, # Unsigned CHAR (8 bit)
272
- UHALF_PTR: :uint, # Unsigned HALF_PTR. Use within a structure that contains a pointer and two small fields.
273
- UINT: :uint, # Unsigned INT. The range is 0 through 4294967295 decimal.
274
- UINT_PTR: :uint, # Unsigned INT_PTR.
275
- UINT32: :uint32, # Unsigned INT32. The range is 0 through 4294967295 decimal.
276
- UINT64: :uint64, # Unsigned INT64. The range is 0 through 18446744073709551615 decimal.
277
- ULONG: :ulong, # Unsigned LONG. The range is 0 through 4294967295 decimal.
278
- ULONGLONG: :ulong_long, # 64-bit unsigned integer. The range is 0 through 18446744073709551615 decimal.
279
- ULONG_PTR: :ulong, # Unsigned LONG_PTR.
280
- ULONG32: :uint32, # Unsigned INT32. The range is 0 through 4294967295 decimal.
281
- ULONG64: :uint64, # Unsigned LONG64. The range is 0 through 18446744073709551615 decimal.
282
- UNICODE_STRING: :pointer, # Pointer to some string structure??
283
- USHORT: :ushort, # Unsigned SHORT. The range is 0 through 65535 decimal.
284
- USN: :ulong_long, # Update sequence number (USN).
285
- VOID: [], # Any type ? Only use it to indicate no arguments or no return value
286
- WCHAR: :ushort, # 16-bit Unicode character. For more information, see Character Sets Used By Fonts.
287
- # In WinNT.h: typedef wchar_t WCHAR;
288
- #WINAPI: K, # Calling convention for system functions. WinDef.h: define WINAPI __stdcall
289
- WORD: :ushort, # 16-bit unsigned integer. The range is 0 through 65535 decimal.
290
- WPARAM: :uint # Message parameter. WinDef.h as follows: typedef UINT_PTR WPARAM;
291
- }
292
-
293
- ##
294
- # Defines new method wrappers for Windows API function call:
295
- # - Defines method with original (CamelCase) API function name and original signature (matches MSDN description)
296
- # - Defines method with snake_case name (converted from CamelCase function name) with enhanced API signature
297
- # When defined snake_case method is called, it converts the arguments you provided into ones required by
298
- # original API (adding defaults, mute and transitory args as necessary), executes API function call
299
- # and (optionally) transforms the result before returning it. If a block is attached to
300
- # method invocation, raw result is yielded to this block before final transformation take place
301
- # - Defines aliases for enhanced method with more Rubyesque names for getters, setters and tests:
302
- # GetWindowText -> window_test, SetWindowText -> window_text=, IsZoomed -> zoomed?
303
- # ---
304
- # You may modify default behavior of defined method by providing optional *def_block* to function definition.
305
- # If you do so, snake_case method is defined based on your *def_block*. It receives callable API
306
- # object for function being defined, arguments and (optional) runtime block with which the method
307
- # will be called. Results coming from &def_block are then transformed and returned.
308
- # So, your *def_block* should specify all the behavior of the method being defined. You can use *def_block* to:
309
- # - Change original signature of API function, provide argument defaults, check argument types
310
- # - Pack arguments into strings/structs for <in> or <in/out> parameters that expect a pointer
311
- # - Allocate buffers/structs for pointers required by API functions <out> parameters
312
- # - Unpack <out> and <in/out> parameters returned as pointers
313
- # - Explicitly return results of API call that are returned in <out> and <in/out> parameters
314
- # - Convert attached runtime blocks into callback functions and stuff them into <in> callback parameters
315
- # - do other stuff that you think is appropriate to make Windows API function behavior more Ruby-like...
316
- # ---
317
- # Accepts following options:
318
- # :dll:: Use this dll instead of default 'user32'
319
- # :rename:: Use this name instead of standard (conventional) function name
320
- # :alias(es):: Provides additional alias(es) for defined method
321
- # :boolean:: Forces method to return true/false instead of nonzero/zero
322
- # :zeronil:: Forces method to return nil if function result is zero
323
- #
324
- def function(name, params, returns, options={}, &def_block)
325
- snake_name, effective_names, aliases = generate_names(name, options)
326
- params, returns = generate_signature(params, returns)
327
- libs = ffi_libraries.map(&:name)
328
- boolean = options[:boolean]
329
- zeronil = options[:zeronil]
330
-
331
- effective_name = effective_names.inject(nil) do |func, effective_name|
332
- func || begin
333
- # tries to attach basic CamelCase method via FFI
334
- attach_function(name, effective_name, params.dup, returns)
335
- effective_name
336
- rescue FFI::NotFoundError
337
- nil
338
- end
339
- end
340
-
341
- raise Win::Errors::NotFoundError.new(name, libs) unless effective_name
342
-
343
- # Create API object that holds information about function names, params, etc
344
- api = API.new(namespace, name, effective_name, params, returns, libs)
345
-
346
- # Only define enhanced API if snake_name is different from original name (e.g. keybd_event),
347
- # If names are the same, this function is already "attached", not possible to enhance its API
348
- unless snake_name.to_s == name.to_s
349
- method_body = if def_block
350
- if zeronil
351
- ->(*args, &block){ (res = def_block.(api, *args, &block)) != 0 ? res : nil }
352
- elsif boolean
353
- ->(*args, &block){ def_block.(api, *args, &block) != 0 }
354
- else
355
- ->(*args, &block){ def_block.(api, *args, &block) }
356
- end
357
- else
358
- if zeronil
359
- ->(*args, &block){ (res = block ? block[api.call(*args)] : api.call(*args)) != 0 ? res : nil }
360
- elsif boolean
361
- ->(*args, &block){ block ? block[api.call(*args)] : api.call(*args) != 0 }
362
- else
363
- ->(*args, &block){ block ? block[api.call(*args)] : api.call(*args) }
364
- end
365
- end
366
-
367
- define_method snake_name, &method_body # define snake_case instance method
368
-
369
- eigen_class = class << self; self; end # Extracting eigenclass
370
- eigen_class.class_eval do
371
- define_method snake_name, &method_body # define snake_case class method
372
- end
373
- end
374
-
375
- aliases.each {|ali| alias_method ali, snake_name } # define aliases
376
- api #return api object from function declaration
377
- end
378
-
379
- # Try to define platform-specific function, rescue error, return message
380
- #
381
- def try_function(name, params, returns, options={}, &def_block)
382
- begin
383
- function name, params, returns, options={}, &def_block
384
- rescue Win::Errors::NotFoundError
385
- "This platform does not support function #{name}"
386
- end
387
- end
388
-
389
- # Generates possible effective names for function in Win32 dll (name+A/W),
390
- # Rubyesque name and aliases for method(s) defined based on function name,
391
- #
392
- def generate_names(name, options={})
393
- name = name.to_s
394
- effective_names = [name]
395
- effective_names += ["#{name}A", "#{name}W"] unless name =~ /[WA]$/
396
- aliases = ([options[:alias]] + [options[:aliases]]).flatten.compact
397
- snake_name = options[:rename] || name.snake_case
398
- case snake_name
399
- when /^is_/
400
- aliases << snake_name.sub(/^is_/, '') + '?'
401
- when /^set_/
402
- aliases << snake_name.sub(/^set_/, '')+ '='
403
- when /^get_/
404
- aliases << snake_name.sub(/^get_/, '')
405
- end
406
- [snake_name, effective_names, aliases]
407
- end
408
-
409
- ##
410
- # Generates params and returns (signature) containing only FFI-compliant types
411
- #
412
- def generate_signature(params, returns)
413
- params = params.split(//) if params.respond_to?(:split) # Convert params string into array
414
- params.map! {|param| TYPES[param.to_sym] || param} # Convert chars into FFI type symbols
415
- returns = TYPES[returns.to_sym] || returns # Convert chars into FFI type symbols
416
- [params, returns]
417
- end
418
-
419
- ##
420
- # Wrapper for FFI::Library#callback() that converts Win32/shortcut argument types into FFI-compliant types.
421
- # This method overrides FFI.callback which must be aliased to FFI.attach_callback
422
- #
423
- def callback(name, params, returns)
424
- params, returns = generate_signature(params, returns)
425
- attach_callback name.to_sym, params, returns
426
- end
427
-
428
- ##
429
- # :method: namespace
430
- # This method is meta-generated when Win::Library module is included into other module/class.
431
- # It returns reference to including (host) class/module for use by Win::Library::API and class methods.
432
-
433
- ##
434
- # Ensures that args count is equal to params count plus diff
435
- #
436
- def enforce_count(args, params, diff = 0)
437
- num_args = args.size
438
- num_params = params.size + diff #params == 'V' ? 0 : params.size + diff
439
- if num_args != num_params
440
- raise ArgumentError, "wrong number of arguments (#{num_args} for #{num_params})"
441
- end
442
- end
443
-
444
- end
445
-
446
- ##
447
- # Hook executed when Win::Library is included into class or module. It extends host class/module
448
- # with both FFI::Library methods and Win::Library macro methods like 'function'.
449
- #
450
- def self.included(host_class)
451
- host_class.extend FFI::Library
452
-
453
- # Extracting host class's eigenclass
454
- # :stopdoc:
455
- eigen_class = class << host_class; self; end # :nodoc:
456
-
457
- eigen_class.class_eval do
458
- define_method(:namespace) {host_class} # Defining new class method for host class pointing to itself
459
- alias_method :attach_callback, :callback
460
-
461
- include ClassMethods
462
- end
463
- # :startdoc:
464
-
465
- host_class.ffi_lib 'user32', 'kernel32' # Default libraries
466
- host_class.ffi_convention :stdcall
459
+ # alias_method :[], :call
467
460
  end
468
461
  end
469
462
  end
@@ -29,11 +29,11 @@ module WinGuiDialogTest
29
29
 
30
30
  it "creates, displays, and operates a message box" do
31
31
  pending 'Not possible to test message_box directly, it blocks all related threads :('
32
- t = Thread.new do
33
- selected_item = message_box(handle=0, text="Text", caption="Caption", type=MB_YESNO | MB_HELP)
34
- puts selected_item
35
- end
36
- t.join
32
+ t = Thread.new do
33
+ selected_item = message_box(handle=0, text="Text", caption="Caption", type=MB_YESNO | MB_HELP)
34
+ puts selected_item
35
+ end
36
+ t.join
37
37
  end
38
38
  end # describe message_box
39
39
 
@@ -58,6 +58,25 @@ module WinGuiDialogTest
58
58
  end
59
59
  end
60
60
 
61
+ describe "#get_dlg_ctrl_id" do
62
+ spec{ use{ control_id = GetDlgCtrlID(control_handle=0) }}
63
+ spec{ use{ control_id = get_dlg_ctrl_id(control_handle=0) }}
64
+
65
+ it "retrieves the identifier of the specified control" do
66
+ test_app_with_dialog do |app, dialog|
67
+ control = find_window_ex(dialog, 0, "Button", "&Yes")
68
+ get_dlg_ctrl_id(control).should == IDYES
69
+ end
70
+ end
71
+
72
+ it "returns 0/nil for invalid control (say, if given handle is top level window" do
73
+ invalid_control = find_window(nil, nil) # Top level, so it must be invalid
74
+ GetDlgCtrlID(invalid_control).should == 0
75
+ get_dlg_ctrl_id(invalid_control).should == nil
76
+ end
77
+
78
+ end # describe get_dlg_ctrl_id
79
+
61
80
  end
62
81
  end
63
82
  end
@@ -85,10 +85,6 @@ module WinGuiMessageTest
85
85
  end
86
86
  end # describe '#send_message'
87
87
 
88
- # :call-seq:
89
- # success = send_message_callback(handle, msg, w_param, l_param, data)
90
- # {|handle, msg, data, l_result| callback code }
91
-
92
88
  describe "#send_message_callback" do
93
89
  before(:all){@app=launch_test_app}
94
90
  after(:all){close_test_app if @launched_test_app}
@@ -6,7 +6,7 @@ module WinLibraryTest
6
6
  include WinTest
7
7
 
8
8
  module MyLib # namespace for defined functions
9
- include Win::Library
9
+ extend Win::Library
10
10
  end
11
11
  include MyLib
12
12
 
@@ -87,6 +87,7 @@ module WinLibraryTest
87
87
  it 'defines new instance methods with appropriate names' do
88
88
  MyLib.function :FindWindow, 'PP', 'L'
89
89
  respond_to?(:FindWindow).should be_true
90
+ MyLib.respond_to?(:find_window).should be_true
90
91
  respond_to?(:find_window).should be_true
91
92
  end
92
93
 
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 3
8
- - 8
9
- version: 0.3.8
8
+ - 11
9
+ version: 0.3.11
10
10
  platform: ruby
11
11
  authors:
12
12
  - arvicco
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-06-02 00:00:00 +04:00
17
+ date: 2010-06-03 00:00:00 +04:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency