win 0.3.8 → 0.3.11

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