win 0.0.6 → 0.1.0

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.
@@ -0,0 +1,497 @@
1
+ require 'win/library'
2
+
3
+ module Win
4
+ module Gui
5
+ # Contains constants and Win32API functions related to window manipulation
6
+ #
7
+ module Window
8
+ include Win::Library
9
+
10
+ # ShowWindow constants:
11
+
12
+ # Hides the window and activates another window.
13
+ SW_HIDE = 0
14
+ # Same as SW_SHOWNORMAL
15
+ SW_NORMAL = 1
16
+ # Activates and displays a window. If the window is minimized or maximized, the system restores it to its
17
+ # original size and position. An application should specify this flag when displaying the window for the first time.
18
+ SW_SHOWNORMAL = 1
19
+ # Activates the window and displays it as a minimized window.
20
+ SW_SHOWMINIMIZED = 2
21
+ # Activates the window and displays it as a maximized window.
22
+ SW_SHOWMAXIMIZED = 3
23
+ # Activates the window and displays it as a maximized window.
24
+ SW_MAXIMIZE = 3
25
+ # Displays a window in its most recent size and position. Similar to SW_SHOWNORMAL, but the window is not activated.
26
+ SW_SHOWNOACTIVATE = 4
27
+ # Activates the window and displays it in its current size and position.
28
+ SW_SHOW = 5
29
+ # Minimizes the specified window, activates the next top-level window in the Z order.
30
+ SW_MINIMIZE = 6
31
+ # Displays the window as a minimized window. Similar to SW_SHOWMINIMIZED, except the window is not activated.
32
+ SW_SHOWMINNOACTIVE= 7
33
+ # Displays the window in its current size and position. Similar to SW_SHOW, except the window is not activated.
34
+ SW_SHOWNA = 8
35
+ # Activates and displays the window. If the window is minimized or maximized, the system restores it to its original
36
+ # size and position. An application should specify this flag when restoring a minimized window.
37
+ SW_RESTORE = 9
38
+ # Sets the show state based on the SW_ value specified in the STARTUPINFO structure passed to the CreateProcess
39
+ # function by the program that started the application.
40
+ SW_SHOWDEFAULT = 10
41
+ # Windows 2000/XP: Minimizes a window, even if the thread that owns the window is not responding. Only use this
42
+ # flag when minimizing windows from a different thread.
43
+ SW_FORCEMINIMIZE = 11
44
+
45
+ class << self
46
+ # Def_block that calls API function expecting EnumWindowsProc callback (EnumWindows, EnumChildWindows, ...).
47
+ # Default callback pushes all passed handles into Array that is returned if Enum function call was successful.
48
+ # If runtime block is given it is called after the end of default callback (handle Array is still being
49
+ # collected and returned by the method). If Enum... function call fails, method returns nil, otherwise
50
+ # an Array of all window handles passed into callback.
51
+ #
52
+ def return_enum #:nodoc:
53
+ lambda do |api, *args, &block|
54
+ args.push 0 if args.size == api.prototype.size - 2 # If value is missing, it defaults to 0
55
+ handles = []
56
+
57
+ # Insert callback proc into appropriate place of args Array
58
+ args[api.prototype.find_index(:enum_callback), 0] =
59
+ proc do |handle, message|
60
+ handles << handle
61
+ block ? block[handle, message] : true
62
+ end
63
+ handles if api.call *args
64
+ end
65
+ end
66
+
67
+ # Helper method that creates def_block returning (possibly encoded) string as a result of
68
+ # api function call or nil if zero characters was returned by api call
69
+ #
70
+ def return_string( encode = nil ) #:nodoc:
71
+ lambda do |api, *args|
72
+ namespace.enforce_count( args, api.prototype, -2)
73
+ buffer = FFI::MemoryPointer.new :char, 1024
74
+ args += [buffer, buffer.size]
75
+ num_chars = api.call(*args)
76
+ return nil if num_chars == 0
77
+ if encode
78
+ string = buffer.get_bytes(0, num_chars*2)
79
+ string = string.force_encoding('utf-16LE').encode(encode)
80
+ else
81
+ string = buffer.get_bytes(0, num_chars)
82
+ end
83
+ string.rstrip
84
+ end
85
+ end
86
+
87
+ private :return_enum, :return_string
88
+ end
89
+
90
+ # Windows GUI API definitions:
91
+
92
+ ##
93
+ # Tests whether the specified window handle identifies an existing window.
94
+ # A thread should not use IsWindow for a window that it did not create because the window
95
+ # could be destroyed after this function was called. Further, because window handles are
96
+ # recycled the handle could even point to a different window.
97
+ #
98
+ # :call-seq:
99
+ # window?( win_handle )
100
+ #
101
+ function 'IsWindow', 'L', 'L'
102
+
103
+ ##
104
+ # Tests if the specified window, its parent window, its parent's parent window, and so forth,
105
+ # have the WS_VISIBLE style. Because the return value specifies whether the window has the
106
+ # WS_VISIBLE style, it may be true even if the window is totally obscured by other windows.
107
+ #
108
+ # :call-seq:
109
+ # [window_]visible?( win_handle )
110
+ #
111
+ function 'IsWindowVisible', 'L', 'L', aliases: :visible?
112
+
113
+ ##
114
+ # Tests whether the specified window is maximized.
115
+ #
116
+ # :call-seq:
117
+ # zoomed?( win_handle ), maximized?( win_handle )
118
+ #
119
+ function 'IsZoomed', 'L', 'L', aliases: :maximized?
120
+
121
+ ##
122
+ # Tests whether the specified window is maximized.
123
+ #
124
+ # :call-seq:
125
+ # iconic?( win_handle ), minimized?( win_handle )
126
+ #
127
+ function 'IsIconic', 'L', 'L', aliases: :minimized?
128
+
129
+ ##
130
+ # Tests whether a window is a child (or descendant) window of a specified parent window.
131
+ # A child window is the direct descendant of a specified parent window if that parent window
132
+ # is in the chain of parent windows; the chain of parent windows leads from the original overlapped
133
+ # or pop-up window to the child window.
134
+ #
135
+ # :call-seq:
136
+ # child?( win_handle )
137
+ #
138
+ function 'IsChild', 'LL', 'L'
139
+
140
+ ##
141
+ # Returns a handle to the top-level window whose class and window name match the specified strings.
142
+ # This function does not search child windows. This function does not perform a case-sensitive search.
143
+ #
144
+ # Parameters:
145
+ # class_name (P) - String that specifies (window) class name OR class atom created by a previous
146
+ # call to the RegisterClass(Ex) function. The atom must be in the low-order word of class_name;
147
+ # the high-order word must be zero. The class name can be any name registered with RegisterClass(Ex),
148
+ # or any of the predefined control-class names. If this parameter is nil, it finds any window whose
149
+ # title matches the win_title parameter.
150
+ # win_name (P) - String that specifies the window name (title). If nil, all names match.
151
+ # Return Value (L): found window handle or NIL if nothing found
152
+ #
153
+ # :call-seq:
154
+ # win_handle = find_window( class_name, win_name )
155
+ #
156
+ function 'FindWindow', 'PP', 'L', zeronil: true
157
+
158
+ ##
159
+ # Unicode version of find_window (strings must be encoded as utf-16LE AND terminate with "\x00\x00")
160
+ #
161
+ # :call-seq:
162
+ # win_handle = find_window_w( class_name, win_name )
163
+ #
164
+ function 'FindWindowW', 'PP', 'L', zeronil: true
165
+
166
+ ##
167
+ # Retrieves a handle to a CHILD window whose class name and window name match the specified strings.
168
+ # The function searches child windows, beginning with the one following the specified child window.
169
+ # This function does NOT perform a case-sensitive search.
170
+ #
171
+ # Parameters:
172
+ # parent (L) - Handle to the parent window whose child windows are to be searched.
173
+ # If nil, the function uses the desktop window as the parent window.
174
+ # The function searches among windows that are child windows of the desktop.
175
+ # after_child (L) - Handle to a child window. Search begins with the NEXT child window in the Z order.
176
+ # The child window must be a direct child window of parent, not just a descendant window.
177
+ # If after_child is nil, the search begins with the first child window of parent.
178
+ # win_class (P), win_title (P) - Strings that specify window class and name(title). If nil, anything matches.
179
+ # Returns (L): found child window handle or NIL if nothing found
180
+ #
181
+ # :call-seq:
182
+ # win_handle = find_window_ex( win_handle, after_child, class_name, win_name )
183
+ #
184
+ function 'FindWindowEx', 'LLPP', 'L', zeronil: true
185
+
186
+ ##
187
+ # Returns the text of the specified window's title bar (if it has one).
188
+ # If the specified window is a control, the text of the control is copied. However, GetWindowText
189
+ # cannot retrieve the text of a control in another application.
190
+ #
191
+ # Original Parameters:
192
+ # win_handle (L) - Handle to the window and, indirectly, the class to which the window belongs.
193
+ # text (P) - Long Pointer to the buffer that is to receive the text string.
194
+ # max_count (I) - Specifies the length, in TCHAR, of the buffer pointed to by the text parameter.
195
+ # The class name string is truncated if it is longer than the buffer and is always null-terminated.
196
+ # Original Return Value (L): Length, in characters, of the copied string, not including the terminating null
197
+ # character, indicates success. Zero indicates that the window has no title bar or text, if the title bar
198
+ # is empty, or if the window or control handle is invalid. For extended error information, call GetLastError.
199
+ #
200
+ # Enhanced API requires only win_handle and returns rstripped text
201
+ #
202
+ # Enhanced Parameters:
203
+ # win_handle (L) - Handle to the window and, indirectly, the class to which the window belongs.
204
+ # Returns: Window title bar text or nil
205
+ # If the window has no title bar or text, if the title bar is empty, or if the window or control handle
206
+ # is invalid, the return value is NIL. To get extended error information, call GetLastError.
207
+ #
208
+ # Remarks: This function CANNOT retrieve the text of an edit control in ANOTHER app.
209
+ # If the target window is owned by the current process, GetWindowText causes a WM_GETTEXT message to
210
+ # be sent to the specified window or control. If the target window is owned by another process and has
211
+ # a caption, GetWindowText retrieves the window caption text. If the window does not have a caption,
212
+ # the return value is a null string. This allows to call GetWindowText without becoming unresponsive
213
+ # if the target window owner process is not responding. However, if the unresponsive target window
214
+ # belongs to the calling app, GetWindowText will cause the calling app to become unresponsive.
215
+ # To retrieve the text of a control in another process, send a WM_GETTEXT message directly instead
216
+ # of calling GetWindowText.
217
+ #
218
+ #:call-seq:
219
+ # text = [get_]window_text( win_handle )
220
+ #
221
+ function 'GetWindowText', 'LPI', 'L', &return_string
222
+
223
+ ##
224
+ # Unicode version of get_window_text (returns rstripped utf-8 string)
225
+ # API improved to require only win_handle and return rstripped string
226
+ #
227
+ #:call-seq:
228
+ # text = [get_]window_text_w( win_handle )
229
+ #
230
+ function 'GetWindowTextW', 'LPI', 'L', &return_string('utf-8')
231
+
232
+ ##
233
+ # Retrieves the name of the class to which the specified window belongs.
234
+ #
235
+ # Original Parameters:
236
+ # win_handle (L) - Handle to the window and, indirectly, the class to which the window belongs.
237
+ # class_name (P) - Long Pointer to the buffer that is to receive the class name string.
238
+ # max_count (I) - Specifies the length, in TCHAR, of the buffer pointed to by the class_name parameter.
239
+ # The class name string is truncated if it is longer than the buffer and is always null-terminated.
240
+ # Original Return Value (L): Length, in characters, of the copied string, not including the terminating null
241
+ # character, indicates success. Zero indicates that the window has no title bar or text, if the title bar
242
+ # is empty, or if the window or control handle is invalid. For extended error information, call GetLastError.
243
+ #
244
+ # API improved to require only win_handle and return rstripped string
245
+ #
246
+ # Enhanced Parameters:
247
+ # win_handle (L) - Handle to the window and, indirectly, the class to which the window belongs.
248
+ # Returns: Name of the class or NIL if function fails. For extended error information, call GetLastError.
249
+ #
250
+ #:call-seq:
251
+ # text = [get_]class_name( win_handle )
252
+ #
253
+ function 'GetClassName', 'LPI', 'I', &return_string
254
+
255
+ ##
256
+ # Unicode version of get_class_name (returns rstripped utf-8 string)
257
+ # API improved to require only win_handle and return rstripped string
258
+ #
259
+ #:call-seq:
260
+ # text = [get_]class_name_w( win_handle )
261
+ #
262
+ function 'GetClassNameW', 'LPI', 'I', &return_string('utf-8')
263
+
264
+ ##
265
+ # Shows and hides windows.
266
+ #
267
+ # Parameters:
268
+ # win_handle (L) - Handle to the window.
269
+ # cmd (I) - Specifies how the window is to be shown. This parameter is ignored the first time an
270
+ # application calls ShowWindow, if the program that launched the application provides a STARTUPINFO
271
+ # structure. Otherwise, the first time ShowWindow is called, the value should be the value obtained
272
+ # by the WinMain function in its nCmdShow parameter. In subsequent calls, cmd may be:
273
+ # SW_HIDE, SW_MAXIMIZE, SW_MINIMIZE, SW_SHOW, SW_SHOWMAXIMIZED, SW_SHOWMINIMIZED, SW_SHOWMINNOACTIVE,
274
+ # SW_SHOWNA, SW_SHOWNOACTIVATE, SW_SHOWNORMAL, SW_RESTORE, SW_SHOWDEFAULT, SW_FORCEMINIMIZE
275
+ #
276
+ # Original Return Value: - Nonzero if the window was PREVIOUSLY visible, otherwise zero
277
+ # Enhanced Returns: - True if the window was PREVIOUSLY visible, otherwise false
278
+ #
279
+ #:call-seq:
280
+ # was_visible = show_window( win_handle, cmd )
281
+ #
282
+ function 'ShowWindow', 'LI', 'I', boolean: true
283
+
284
+ ##
285
+ # Retrieves the identifier of the thread that created the specified window
286
+ # and, optionally, the identifier of the process that created the window.
287
+ #
288
+ # Original Parameters:
289
+ # handle (L) - Handle to the window.
290
+ # process (P) - A POINTER to a (Long) variable that receives the process identifier.
291
+ # Original Return (L): Identifier of the thread that created the window.
292
+ #
293
+ # API improved to accept window handle as a single arg and return a pair of [thread, process] ids
294
+ #
295
+ # New Parameters:
296
+ # handle (L) - Handle to the window.
297
+ # Returns: Pair of identifiers of the thread and process_id that created the window.
298
+ #
299
+ #:call-seq:
300
+ # thread, process_id = [get_]window_tread_process_id( win_handle )
301
+ #
302
+ function 'GetWindowThreadProcessId', [:long, :pointer], :long,
303
+ &->(api, *args) {
304
+ namespace.enforce_count( args, api.prototype, -1)
305
+ process = FFI::MemoryPointer.new(:long)
306
+ process.write_long(1)
307
+ thread = api.call(args.first, process)
308
+ thread == 0 ? [nil, nil] : [thread, process.read_long()] }
309
+ # weird lambda literal instead of normal block is needed because current version of RDoc
310
+ # goes crazy if block is attached to meta-definition
311
+
312
+ ##
313
+ # Retrieves the dimensions of the specified window bounding rectangle.
314
+ # Dimensions are given relative to the upper-left corner of the screen.
315
+ #
316
+ # Original Parameters:
317
+ # win_handle (L) - Handle to the window.
318
+ # rect (P) - Long pointer to a RECT structure that receives the screen coordinates of the upper-left and
319
+ # lower-right corners of the window.
320
+ # Original Return Value: Nonzero indicates success. Zero indicates failure. For error info, call GetLastError.
321
+ #
322
+ # API improved to accept only window handle and return 4-member dimensions array (left, top, right, bottom)
323
+ #
324
+ # New Parameters:
325
+ # win_handle (L) - Handle to the window
326
+ # New Return: Array(left, top, right, bottom) - rectangle dimensions
327
+ #
328
+ # Remarks: As a convention for the RECT structure, the bottom-right coordinates of the returned rectangle
329
+ # are exclusive. In other words, the pixel at (right, bottom) lies immediately outside the rectangle.
330
+ #
331
+ #:call-seq:
332
+ # rect = [get_]window_rect( win_handle )
333
+ #
334
+ function 'GetWindowRect', 'LP', 'I',
335
+ &->(api, *args) {
336
+ namespace.enforce_count( args, api.prototype, -1)
337
+ rect = FFI::MemoryPointer.new(:long, 4)
338
+ rect.write_array_of_long([0, 0, 0, 0])
339
+ res = api.call args.first, rect
340
+ res == 0 ? [nil, nil, nil, nil] : rect.read_array_of_long(4) }
341
+ # weird lambda literal instead of normal block is needed because current version of RDoc
342
+ # goes crazy if block is attached to meta-definition
343
+
344
+ # This is an application-defined callback function that receives top-level window handles as a result of a call
345
+ # to the EnumWindows, EnumChildWindows or EnumDesktopWindows function.
346
+ #
347
+ # Syntax: BOOL CALLBACK EnumWindowsProc( HWND hwnd, LPARAM lParam );
348
+ #
349
+ # Parameters:
350
+ # hwnd (L) - [out] Handle to a top-level window.
351
+ # lParam (L) - [in] Specifies the application-defined value given in EnumWindows or EnumDesktopWindows.
352
+ # Return Values:
353
+ # TRUE continues enumeration. FALSE stops enumeration.
354
+ #
355
+ # Remarks: An application must register this callback function by passing its address to EnumWindows,
356
+ # EnumChildWindows or EnumDesktopWindows.
357
+ callback :enum_callback, 'LL', :bool
358
+
359
+ ##
360
+ # The EnumWindows function enumerates all top-level windows on the screen by passing the handle to
361
+ # each window, in turn, to an application-defined callback function. EnumWindows continues until
362
+ # the last top-level window is enumerated or the callback function returns FALSE.
363
+ #
364
+ # Original Parameters:
365
+ # callback [K] - Pointer to an application-defined callback function (see EnumWindowsProc).
366
+ # value [P] - Specifies an application-defined value(message) to be passed to the callback function.
367
+ # Original Return: Nonzero if the function succeeds, zero if the function fails. GetLastError for error info.
368
+ # If callback returns zero, the return value is also zero. In this case, the callback function should
369
+ # call SetLastError to obtain a meaningful error code to be returned to the caller of EnumWindows.
370
+ #
371
+ # API improved to accept blocks (instead of callback objects) and message as a single arg
372
+ #
373
+ # New Parameters:
374
+ # message [P] - Specifies an application-defined value(message) to be passed to the callback function.
375
+ # block given to method invocation serves as an application-defined callback function (see EnumWindowsProc).
376
+ # Returns: True if the function succeeds, false if the function fails. GetLastError for error info.
377
+ # If callback returns zero, the return value is also zero. In this case, the callback function should
378
+ # call SetLastError to obtain a meaningful error code to be returned to the caller of EnumWindows.
379
+ #
380
+ # Remarks: The EnumWindows function does not enumerate child windows, with the exception of a few top-level
381
+ # windows owned by the system that have the WS_CHILD style. This function is more reliable than calling
382
+ # the GetWindow function in a loop. An application that calls GetWindow to perform this task risks being
383
+ # caught in an infinite loop or referencing a handle to a window that has been destroyed.
384
+ #
385
+ # :call-seq:
386
+ # handles = enum_windows( [value=0] ) {|handle, value| your callback procedure }
387
+ #
388
+ function'EnumWindows', [:enum_callback, :long], :bool, &return_enum
389
+
390
+ ##
391
+ #EnumDesktopWindows Function
392
+ #
393
+ #Enumerates all top-level windows associated with the specified desktop. It passes the handle to each window, in turn, to an application-defined callback function.
394
+ #
395
+ #
396
+ #Syntax
397
+ #BOOL WINAPI EnumDesktopWindows(
398
+ # __in_opt HDESK hDesktop,
399
+ # __in WNDENUMPROC lpfn,
400
+ # __in LPARAM lParam
401
+ #);
402
+ #
403
+ #Parameters
404
+ #hDesktop
405
+ #A handle to the desktop whose top-level windows are to be enumerated. This handle is returned by the CreateDesktop, GetThreadDesktop, OpenDesktop, or OpenInputDesktop function, and must have the DESKTOP_ENUMERATE access right. For more information, see Desktop Security and Access Rights.
406
+ #
407
+ #If this parameter is NULL, the current desktop is used.
408
+ #
409
+ #lpfn
410
+ #A pointer to an application-defined EnumWindowsProc callback function.
411
+ #
412
+ #lParam
413
+ #An application-defined value to be passed to the callback function.
414
+ #
415
+ #Return Value
416
+ #If the function fails or is unable to perform the enumeration, the return value is zero.
417
+ #
418
+ #To get extended error information, call GetLastError.
419
+ #
420
+ #You must ensure that the callback function sets SetLastError if it fails.
421
+ #
422
+ #Windows Server 2003 and Windows XP/2000: If there are no windows on the desktop, GetLastError returns ERROR_INVALID_HANDLE.
423
+ #Remarks
424
+ #The EnumDesktopWindows function repeatedly invokes the lpfn callback function until the last top-level window is enumerated or the callback function returns FALSE.
425
+ #
426
+ #Requirements
427
+ #Client Requires Windows Vista, Windows XP, or Windows 2000 Professional.
428
+ #
429
+ # :call-seq:
430
+ # handles = enum_desktop_windows( desktop_handle, [value=0] ) {|handle, value| your callback procedure }
431
+ #
432
+ function'EnumDesktopWindows', [:ulong, :enum_callback, :long], :bool, &return_enum
433
+
434
+ ##
435
+ # Enumerates child windows to a given window.
436
+ #
437
+ # Original Parameters:
438
+ # parent (L) - Handle to the parent window whose child windows are to be enumerated.
439
+ # callback [K] - Pointer to an application-defined callback function (see EnumWindowsProc).
440
+ # message [P] - Specifies an application-defined value(message) to be passed to the callback function.
441
+ # Original Return: Not used (?!)
442
+ # If callback returns zero, the return value is also zero. In this case, the callback function should
443
+ # call SetLastError to obtain a meaningful error code to be returned to the caller of EnumWindows.
444
+ # If it is nil, this function is equivalent to EnumWindows. Windows 95/98/Me: parent cannot be NULL.
445
+ #
446
+ # API improved to accept blocks (instead of callback objects) and parent handle (value is optional, default 0)
447
+ # New Parameters:
448
+ # parent (L) - Handle to the parent window whose child windows are to be enumerated.
449
+ # value (P) - Specifies an application-defined value(message) to be passed to the callback function.
450
+ # block given to method invocation serves as an application-defined callback function (see EnumChildProc).
451
+ #
452
+ # Remarks:
453
+ # If a child window has created child windows of its own, EnumChildWindows enumerates those windows as well.
454
+ # A child window that is moved or repositioned in the Z order during the enumeration process will be properly enumerated.
455
+ # The function does not enumerate a child window that is destroyed before being enumerated or that is created during the enumeration process.
456
+ #
457
+ #:call-seq:
458
+ # handles = enum_child_windows( parent_handle, [value=0] ) {|handle, value| your callback procedure }
459
+ #
460
+ function 'EnumChildWindows', [:ulong, :enum_callback, :long], :bool, &return_enum
461
+
462
+ ##
463
+ # GetForegroundWindow function returns a handle to the foreground window (the window with which the user
464
+ # is currently working). The system assigns a slightly higher priority to the thread that creates the
465
+ # foreground window than it does to other threads.
466
+ #
467
+ # Syntax: HWND GetForegroundWindow(VOID);
468
+ #
469
+ # Return Value: The return value is a handle to the foreground window. The foreground window can be NULL in
470
+ # certain circumstances, such as when a window is losing activation.
471
+ #
472
+ #:call-seq:
473
+ # win_handle = [get_]foreground_window()
474
+ #
475
+ function 'GetForegroundWindow', [], 'L'
476
+
477
+ ##
478
+ # The GetActiveWindow function retrieves the window handle to the active window attached to
479
+ # the calling thread's message queue.
480
+ #
481
+ # Syntax: HWND GetActiveWindow(VOID);
482
+ #
483
+ # Return Value: The return value is the handle to the active window attached to the calling
484
+ # thread's message queue. Otherwise, the return value is NULL.
485
+ #
486
+ # Remarks: To get the handle to the foreground window, you can use GetForegroundWindow.
487
+ # To get the window handle to the active window in the message queue for another thread, use GetGUIThreadInfo.
488
+ #
489
+ #:call-seq:
490
+ # win_handle = [get_]active_window()
491
+ #
492
+ function 'GetActiveWindow', [], 'L'
493
+
494
+ end
495
+ end
496
+ end
497
+
data/lib/win/gui.rb ADDED
@@ -0,0 +1,17 @@
1
+ require 'win/gui/window'
2
+ require 'win/gui/input'
3
+ require 'win/gui/message'
4
+ require 'win/gui/dialog'
5
+ require 'win/gui/convenience'
6
+
7
+ module Win
8
+ # Contains several modules defining Win32 API functions and constants related to Windows GUI (Graphical User Interface)
9
+ #
10
+ module Gui
11
+ include Win::Gui::Window
12
+ include Win::Gui::Input
13
+ include Win::Gui::Message
14
+ include Win::Gui::Dialog
15
+ include Win::Gui::Convenience
16
+ end
17
+ end
data/lib/win/library.rb CHANGED
@@ -367,6 +367,7 @@ module Win
367
367
  # sets boolean flag for test functions (Is...)
368
368
  #
369
369
  def generate_names(name, options={})
370
+ name = name.to_s
370
371
  effective_names = [name]
371
372
  effective_names += ["#{name}A", "#{name}W"] unless name =~ /[WA]$/
372
373
  aliases = ([options[:alias]] + [options[:aliases]]).flatten.compact
@@ -394,11 +395,11 @@ module Win
394
395
  end
395
396
 
396
397
  ##
397
- # Wrapper for FFI::Library#callback() that converts Win32/shortcut types into FFI format
398
- #
398
+ # Wrapper for FFI::Library#callback() that converts Win32/shortcut argument types into FFI-compliant types.
399
+ # This method overrides FFI.callback which must be aliased to FFI.attach_callback
399
400
  def callback(name, params, returns)
400
401
  params, returns = generate_signature(params, returns)
401
- ffi_callback name.to_sym, params, returns
402
+ attach_callback name.to_sym, params, returns
402
403
  end
403
404
 
404
405
  ##
@@ -425,15 +426,15 @@ module Win
425
426
  def self.included(klass)
426
427
  klass.extend FFI::Library
427
428
 
428
- eigenklass = class << klass; self; end # Extracting host class's eigenclass
429
- eigenklass.class_eval "
430
- alias_method :ffi_callback, :callback
431
- def namespace; #{klass}; end"
432
-
429
+ eigenklass = class << klass; self; end # Extracting host class's eigenclass
430
+ eigenklass.class_eval do
431
+ define_method(:namespace) {klass} # Defining new class method for host pointing to itself
432
+ alias_method :attach_callback, :callback
433
+ end
434
+
433
435
  klass.extend ClassMethods
434
436
  klass.ffi_lib 'user32', 'kernel32' # Default libraries
435
437
  klass.ffi_convention :stdcall
436
438
  end
437
-
438
439
  end
439
440
  end
data/spec/spec_helper.rb CHANGED
@@ -2,18 +2,18 @@ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
2
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
3
  require 'spec'
4
4
  require 'spec/autorun'
5
+ require 'win/gui'
5
6
 
6
7
  $debug = true
7
8
 
8
9
  # Customize RSpec with my own extensions
9
- module SpecMacros
10
+ module ClassMacros
10
11
 
11
12
  # wrapper for it method that extracts description from example source code, such as:
12
13
  # spec { use{ function(arg1 = 4, arg2 = 'string') }}
13
14
  def spec &block
14
- # p (block.methods-Object.methods).sort; exit
15
15
  if RUBY_PLATFORM =~ /java/
16
- it 'dummy JRuby description', &block
16
+ it 'not able to extract description', &block
17
17
  else
18
18
  it description_from(*block.source_location), &block
19
19
  end
@@ -27,7 +27,20 @@ module SpecMacros
27
27
  end
28
28
  end
29
29
 
30
- Spec::Runner.configure { |config| config.extend(SpecMacros) }
30
+ # Customize RSpec with my own extensions
31
+ module InstanceMacros
32
+ def use
33
+ lambda{yield}.should_not raise_error
34
+ end
35
+ def any_block
36
+ lambda{|*args| args}
37
+ end
38
+ end
39
+
40
+ Spec::Runner.configure do |config|
41
+ config.extend(ClassMacros)
42
+ config.include(InstanceMacros)
43
+ end
31
44
 
32
45
  module WinTest
33
46
 
@@ -43,23 +56,48 @@ module WinTest
43
56
  TEST_STATUSBAR_CLASS = 'msctls_statusbar32'
44
57
  TEST_TEXTAREA_CLASS = 'ATL:00434310'
45
58
 
46
- def use
47
- lambda{yield}.should_not raise_error
59
+ def any_handle
60
+ find_window(nil, nil)
48
61
  end
49
62
 
50
- def any_block
51
- lambda{|*args| args}
63
+ def not_a_handle
64
+ 123
52
65
  end
66
+ end
53
67
 
54
- def any_handle
55
- unless respond_to? :find_window
56
- require 'win/window'
57
- include Win::Window
68
+ module WinTestApp
69
+
70
+ include WinTest
71
+ include Win::Gui
72
+ include Win::Gui::Convenience
73
+
74
+ def launch_test_app
75
+ system TEST_APP_START
76
+ sleep TEST_SLEEP_DELAY until (handle = find_window(nil, TEST_WIN_TITLE))
77
+
78
+ @launched_test_app = WrapWindow.new handle
79
+ # app = "Test app" #need to get rid of Window for JRuby
80
+ # class << app; self; end.send( :define_method, :handle, &lambda {handle})
81
+ # @launched_test_app = app
82
+ end
83
+
84
+ def close_test_app(app = @launched_test_app)
85
+ while app and app.respond_to? :handle and find_window(nil, TEST_WIN_TITLE)
86
+ post_message(app.handle, WM_SYSCOMMAND, SC_CLOSE, 0)
87
+ sleep TEST_SLEEP_DELAY
58
88
  end
59
- find_window(nil, nil)
89
+ @launched_test_app = nil
60
90
  end
61
91
 
62
- def not_a_handle
63
- 123
92
+ # Creates test app object and yields it back to the block
93
+ def test_app
94
+ app = launch_test_app
95
+
96
+ def app.textarea #define singleton method retrieving app's text area
97
+ WrapWindow.new find_window_ex(self.handle, 0, TEST_TEXTAREA_CLASS, nil)
98
+ end
99
+
100
+ yield app
101
+ close_test_app app
64
102
  end
65
103
  end
data/spec/win/dde_spec.rb CHANGED
@@ -66,3 +66,4 @@ module WinDDETest
66
66
  end
67
67
  end
68
68
  end
69
+
@@ -60,4 +60,4 @@ module WinTest
60
60
  end
61
61
  end
62
62
  end
63
- end
63
+ end