win 0.3.3 → 0.3.5

Sign up to get free protection for your applications and to get access to all the features.
data/HISTORY CHANGED
@@ -6,3 +6,11 @@
6
6
  == 0.3.3 / 2010-04-17
7
7
 
8
8
  * Moved from Jeweler to own Rake tasks
9
+
10
+ == 0.3.4 / 2010-05-12
11
+
12
+ * Cleanup
13
+
14
+ == 0.3.5 / 2010-05-28
15
+
16
+ * GetParent
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.3
1
+ 0.3.5
@@ -43,6 +43,20 @@ module Win
43
43
  # flag when minimizing windows from a different thread.
44
44
  SW_FORCEMINIMIZE = 11
45
45
 
46
+ # GetWindow constants:
47
+ GW_HWNDFIRST = 0
48
+ GW_HWNDLAST = 1
49
+ GW_HWNDNEXT = 2
50
+ GW_HWNDPREV = 3
51
+ GW_OWNER = 4
52
+ GW_CHILD = 5
53
+ GW_ENABLEDPOPUP = 6
54
+
55
+ # GetAncestor constants:
56
+ GA_PARENT = 1
57
+ GA_ROOT = 2
58
+ GA_ROOTOWNER = 3
59
+
46
60
  class << self
47
61
  # Def_block that calls API function expecting EnumWindowsProc callback (EnumWindows, EnumChildWindows, ...).
48
62
  # Default callback pushes all passed handles into Array that is returned if Enum function call was successful.
@@ -227,7 +241,7 @@ module Win
227
241
 
228
242
  ##
229
243
  # The FindWindowEx function retrieves a handle to a window whose class name and window name match the specified
230
- # strings. The function searches child windows, beginning with the one following the specified child window.
244
+ # strings. The function searches only child windows, beginning with the one following the specified child window.
231
245
  # This function does not perform a case-sensitive search.
232
246
  #
233
247
  # [*Syntax*] HWND FindWindowEx( HWND hwndParent, HWND hwndChildAfter, LPCTSTR lpszClass, LPCTSTR lpszWindow );
@@ -257,7 +271,11 @@ module Win
257
271
  # call GetLastError.
258
272
  # ---
259
273
  # *Remarks*:
260
- # - If the lpszWindow parameter is not NULL, FindWindowEx calls the GetWindowText function to retrieve the window name for comparison. For a description of a potential problem that can arise, see the Remarks section of GetWindowText.
274
+ # - Only DIRECT children of given parent window being searched, not ALL its the descendants. This behavior is
275
+ # different from EnumChildWindows which enumerates also non-direct descendants.
276
+ # - If the lpszWindow parameter is not nil, FindWindowEx calls the GetWindowText function to retrieve the window
277
+ # name for comparison. For a description of a potential problem that can arise, see the Remarks section of
278
+ # GetWindowText.
261
279
  # - An application can call this function in the following way.
262
280
  # find_window_ex( nil, nil, MAKEINTATOM(0x8000), nil )
263
281
  # 0x8000 is the atom for a menu class. When an application calls this function, the function checks whether
@@ -470,11 +488,8 @@ module Win
470
488
  function :GetWindowRect, [:HWND, :pointer], :int,
471
489
  &->(api, handle) {
472
490
  rect = FFI::MemoryPointer.new(:long, 4)
473
- #rect.write_array_of_long([0, 0, 0, 0])
474
491
  res = api.call handle, rect
475
492
  res == 0 ? [nil, nil, nil, nil] : rect.read_array_of_long(4) }
476
- # weird lambda literal instead of normal block is needed because current version of RDoc
477
- # goes crazy if block is attached to meta-definition
478
493
 
479
494
  ##
480
495
  # EnumWindowsProc is an application-defined callback function that receives top-level window handles
@@ -499,8 +514,8 @@ module Win
499
514
 
500
515
  ##
501
516
  # The EnumWindows function enumerates all top-level windows on the screen by passing the handle to
502
- # each window, in turn, to an application-defined callback function. EnumWindows continues until
503
- # the last top-level window is enumerated or the callback function returns FALSE.
517
+ # each window, in turn, to an application-defined callback function. EnumWindows continues until
518
+ # the last top-level window is enumerated or the callback function returns FALSE.
504
519
  #
505
520
  # [*Syntax*] BOOL EnumWindows( WNDENUMPROC lpEnumFunc, LPARAM lParam );
506
521
  #
@@ -636,7 +651,112 @@ module Win
636
651
  #
637
652
  function :GetActiveWindow, [], :HWND, zeronil: true
638
653
 
654
+ ##
655
+ # The GetWindow function retrieves a handle to a window that has the specified relationship (Z-Order or
656
+ # owner) to the specified window.
657
+ #
658
+ # [*Syntax*] HWND GetWindow( HWND hWnd, UINT uCmd );
659
+ #
660
+ # hWnd:: [in] Handle to a window. The window handle retrieved is relative to this window, based on the
661
+ # value of the uCmd parameter.
662
+ # uCmd:: [in] Specifies the relationship between the specified window and the window whose handle is to
663
+ # be retrieved. This parameter can be one of the following values.
664
+ # GW_CHILD - The retrieved handle identifies the child window at the top of the Z order, if the specified
665
+ # window is a parent window; otherwise, the retrieved handle is NULL. The function examines
666
+ # only child windows of the specified window. It does not examine descendant windows.
667
+ # GW_ENABLEDPOPUP - Windows 2000/XP: The retrieved handle identifies the enabled popup window owned by
668
+ # the specified window (the search uses the first such window found using GW_HWNDNEXT);
669
+ # otherwise, if there are no enabled popup windows, the retrieved handle is that of the
670
+ # specified window.
671
+ # GW_HWNDFIRST - The retrieved handle identifies the window of the same type that is highest in Z order.
672
+ # If the specified window is a topmost window, the handle identifies the topmost window
673
+ # that is highest in the Z order. If the specified window is a top-level window, the handle
674
+ # identifies the top-level window that is highest in the Z order. If the specified window
675
+ # is a child window, the handle identifies the sibling window that is highest in Z order.
676
+ # GW_HWNDLAST - The retrieved handle identifies the window of the same type that is lowest in the Z order.
677
+ # If the specified window is a topmost window, the handle identifies the topmost window that
678
+ # is lowest in the Z order. If the specified window is a top-level window, the handle
679
+ # identifies the top-level window that is lowest in the Z order. If the specified window is
680
+ # a child window, the handle identifies the sibling window that is lowest in the Z order.
681
+ # GW_HWNDNEXT - The retrieved handle identifies the window below the specified window in the Z order.
682
+ # If the specified window is a topmost window, the handle identifies the topmost window
683
+ # below the specified window. If the specified window is a top-level window, the handle
684
+ # identifies the top-level window below the specified window. If the specified window is
685
+ # a child window, the handle identifies the sibling window below the specified window.
686
+ # GW_HWNDPREV - The retrieved handle identifies the window above the specified window in the Z order.
687
+ # If the specified window is a topmost window, the handle identifies the topmost window
688
+ # above the specified window. If the specified window is a top-level window, the handle
689
+ # identifies the top-level window above the specified window. If the specified window is
690
+ # a child window, the handle identifies the sibling window above the specified window.
691
+ # GW_OWNER - The retrieved handle identifies the specified window's owner window, if any. For more
692
+ # information, see Owned Windows.
693
+ # *Returns*:: If the function succeeds, the return value is a window handle. If no window exists with
694
+ # the specified relationship to the specified window, the return value is NULL. To get
695
+ # extended error information, call GetLastError.
696
+ # ---
697
+ # *Remarks*:
698
+ # The EnumChildWindows function is more reliable than calling GetWindow in a loop. An application that
699
+ # calls GetWindow to perform this task risks being caught in an infinite loop or referencing a handle to
700
+ # a window that has been destroyed.
701
+ # Function Information
702
+ #
703
+ # ---
704
+ # <b>Enhanced (snake_case) API: returns nil instead of 0 in case of failure</b>
705
+ #
706
+ # :call-seq:
707
+ # window_handle = get_window(h_wnd, u_cmd)
708
+ #
709
+ function :GetWindow, [:HWND, :UINT], :HWND, zeronil: true
710
+
711
+ ##
712
+ # The GetParent function retrieves a handle to the specified window's parent OR OWNER.
713
+ # To retrieve a handle to a specified ancestor, use the GetAncestor function.
714
+ #
715
+ # [*Syntax*] HWND GetParent( HWND hWnd );
716
+ #
717
+ # hWnd:: [in] Handle to the window whose parent window handle is to be retrieved.
718
+ #
719
+ # *Returns*:: If the window is a child window, the return value is a handle to the parent window. If the
720
+ # window is a top-level window, the return value is a handle to the owner window. If the
721
+ # window is a top-level unowned window or if the function fails, the return value is NULL.
722
+ # To get extended error information, call GetLastError. For example, this would determine,
723
+ # when the function returns NULL, if the function failed or the window was a top-level window.
724
+ # ---
725
+ # *Remarks*:
726
+ # Note that, despite its name, this function can return an owner window instead of a parent window. To
727
+ # obtain the parent window and not the owner, use GetAncestor with the GA_PARENT flag.
728
+ #
729
+ # ---
730
+ # <b>Enhanced (snake_case) API: returns nil instead of 0 in case of failure</b>
731
+ #
732
+ # :call-seq:
733
+ # parent = get_parent(h_wnd)
734
+ #
735
+ function :GetParent, [:HWND], :HWND, zeronil: true
736
+
737
+ ##
738
+ # The GetAncestor function retrieves the handle to the ancestor of the specified window.
739
+ #
740
+ # [*Syntax*] HWND GetAncestor( HWND hwnd, UINT gaFlags );
741
+ #
742
+ # hwnd:: [in] Handle to the window whose ancestor is to be retrieved. If this parameter is the desktop
743
+ # window, the function returns NULL.
744
+ # gaFlags:: [in] Specifies the ancestor to be retrieved. This parameter can be one of the following values:
745
+ # GA_PARENT - Retrieves parent window. Unlike GetParent function, this does NOT include the owner.
746
+ # GA_ROOT - Retrieves the root window by walking the chain of parent windows.
747
+ # GA_ROOTOWNER - Retrieves the owned root window by walking the chain of parent and owner windows
748
+ # returned by GetParent.
749
+ #
750
+ # *Returns*:: The return value is the handle to the ancestor window.
751
+ # ---
752
+ # <b>Enhanced (snake_case) API: returns nil instead of 0 in case of failure</b>
753
+ #
754
+ # :call-seq:
755
+ # ancestor = get_ancestor(hwnd, ga_flags)
756
+ #
757
+ function :GetAncestor, [:HWND, :UINT], :HWND, zeronil: true
639
758
 
759
+
640
760
  # Convenience wrapper methods:
641
761
 
642
762
  ##
data/lib/win/library.rb CHANGED
@@ -365,8 +365,8 @@ module Win
365
365
 
366
366
  define_method snake_name, &method_body # define snake_case instance method
367
367
 
368
- eigenklass = class << self; self; end # Extracting eigenclass
369
- eigenklass.class_eval do
368
+ eigen_class = class << self; self; end # Extracting eigenclass
369
+ eigen_class.class_eval do
370
370
  define_method snake_name, &method_body # define snake_case class method
371
371
  end
372
372
  end
@@ -446,23 +446,23 @@ module Win
446
446
  # Hook executed when Win::Library is included into class or module. It extends host class/module
447
447
  # with both FFI::Library methods and Win::Library macro methods like 'function'.
448
448
  #
449
- def self.included(klass)
450
- klass.extend FFI::Library
449
+ def self.included(host_class)
450
+ host_class.extend FFI::Library
451
451
 
452
452
  # Extracting host class's eigenclass
453
453
  # :stopdoc:
454
- eigenklass = class << klass; self; end # :nodoc:
454
+ eigen_class = class << host_class; self; end # :nodoc:
455
455
 
456
- eigenklass.class_eval do
457
- define_method(:namespace) {klass} # Defining new class method for host pointing to itself
456
+ eigen_class.class_eval do
457
+ define_method(:namespace) {host_class} # Defining new class method for host class pointing to itself
458
458
  alias_method :attach_callback, :callback
459
459
 
460
460
  include ClassMethods
461
461
  end
462
462
  # :startdoc:
463
463
 
464
- klass.ffi_lib 'user32', 'kernel32' # Default libraries
465
- klass.ffi_convention :stdcall
464
+ host_class.ffi_lib 'user32', 'kernel32' # Default libraries
465
+ host_class.ffi_convention :stdcall
466
466
  end
467
467
  end
468
468
  end
data/spec/spec_helper.rb CHANGED
@@ -4,7 +4,7 @@ require 'spec'
4
4
  require 'spec/autorun'
5
5
  require 'win/gui'
6
6
 
7
- $debug = true
7
+ $debug = false
8
8
 
9
9
  # Customize RSpec with my own extensions
10
10
  module ClassMacros
@@ -13,7 +13,6 @@ module ClassMacros
13
13
  # spec { use{ function(arg1 = 4, arg2 = 'string') }}
14
14
  def spec &block
15
15
  it description_from(caller[0]), &block # it description_from(*block.source_location), &block
16
- #do lambda(&block).should_not raise_error end
17
16
  end
18
17
 
19
18
  # reads description line from source file and drops external brackets like its{}, use{}
@@ -46,11 +45,11 @@ Spec::Runner.configure do |config|
46
45
  config.extend(ClassMacros)
47
46
  config.include(InstanceMacros)
48
47
 
49
- class << Spec::ExampleGroup
50
- # def spoc &block
51
- # it description_from(caller[0]), &block
52
- # end
53
- end
48
+ # class << Spec::ExampleGroup
49
+ ## def spoc &block
50
+ ## it description_from(caller[0]), &block
51
+ ## end
52
+ # end
54
53
  end
55
54
 
56
55
  # Global test methods
@@ -72,17 +71,19 @@ end
72
71
 
73
72
  module WinTest
74
73
 
75
- TEST_KEY_DELAY = 0.001
76
- TEST_IMPOSSIBLE = 'Impossible'
77
- TEST_CONVERSION_ERROR = /Can.t convert/
78
- TEST_SLEEP_DELAY = 0.02
79
- TEST_APP_PATH = File.join(File.dirname(__FILE__), "test_apps/locknote/LockNote.exe" )
80
- TEST_APP_START = cygwin? ? "cmd /c start `cygpath -w #{TEST_APP_PATH}`" : 'start "" "' + TEST_APP_PATH + '"'
81
- TEST_WIN_TITLE = 'LockNote - Steganos LockNote'
82
- TEST_WIN_CLASS = 'ATL:00434098'
83
- TEST_WIN_RECT = [710, 400, 1210, 800]
84
- TEST_STATUSBAR_CLASS = 'msctls_statusbar32'
85
- TEST_TEXTAREA_CLASS = 'ATL:00434310'
74
+ KEY_DELAY = 0.001
75
+ IMPOSSIBLE = 'Impossible'
76
+ CONVERSION_ERROR = /Can.t convert/
77
+ SLEEP_DELAY = 0.02
78
+ APP_PATH = File.join(File.dirname(__FILE__), "test_apps/locknote/LockNote.exe" )
79
+ APP_START = cygwin? ? "cmd /c start `cygpath -w #{APP_PATH}`" : 'start "" "' + APP_PATH + '"'
80
+ WIN_TITLE = 'LockNote - Steganos LockNote'
81
+ WIN_RECT = [710, 400, 1210, 800]
82
+ WIN_CLASS = 'ATL:00434098'
83
+ STATUSBAR_CLASS = 'msctls_statusbar32'
84
+ TEXTAREA_CLASS = 'ATL:00434310'
85
+ DESKTOP_CLASS = '#32769'
86
+ MENU_CLASS = '#32768'
86
87
 
87
88
  def any_handle
88
89
  find_window(nil, nil)
@@ -104,14 +105,14 @@ module WinTestApp
104
105
  #include Win::Gui::Convenience
105
106
 
106
107
  def launch_test_app
107
- system TEST_APP_START
108
- sleep TEST_SLEEP_DELAY until (handle = find_window(nil, TEST_WIN_TITLE))
108
+ system APP_START
109
+ sleep SLEEP_DELAY until (handle = find_window(nil, WIN_TITLE))
109
110
 
110
- textarea = find_window_ex(handle, 0, TEST_TEXTAREA_CLASS, nil)
111
+ textarea = find_window_ex(handle, 0, TEXTAREA_CLASS, nil)
111
112
  app = "Locknote" # App identifier
112
113
 
113
- eigenklass = class << app; self; end # Extracting app's eigenclass
114
- eigenklass.class_eval do # Defining singleton methods on app
114
+ eigen_class = class << app; self; end # Extracting app's eigenclass
115
+ eigen_class.class_eval do # Defining singleton methods on app
115
116
  define_method(:handle) {handle}
116
117
  define_method(:textarea) {textarea}
117
118
  end
@@ -120,9 +121,9 @@ module WinTestApp
120
121
  end
121
122
 
122
123
  def close_test_app(app = @launched_test_app)
123
- while app && app.respond_to?( :handle) && find_window(nil, TEST_WIN_TITLE)
124
+ while app && app.respond_to?( :handle) && find_window(nil, WIN_TITLE)
124
125
  shut_window app.handle
125
- sleep TEST_SLEEP_DELAY
126
+ sleep SLEEP_DELAY
126
127
  end
127
128
  @launched_test_app = nil
128
129
  end
@@ -132,7 +133,7 @@ module WinTestApp
132
133
  app = launch_test_app
133
134
 
134
135
  # def app.textarea #define singleton method retrieving app's text area
135
- # Window::Window.new find_window_ex(self.handle, 0, TEST_TEXTAREA_CLASS, nil)
136
+ # Window::Window.new find_window_ex(self.handle, 0, TEXTAREA_CLASS, nil)
136
137
  # end
137
138
 
138
139
  yield app
@@ -21,14 +21,14 @@ module WinErrorTest
21
21
  spec{ use{ err_message = get_last_error() }}
22
22
 
23
23
  it "original api retrieves the calling thread's last-error code value" do
24
- find_window(TEST_IMPOSSIBLE, TEST_IMPOSSIBLE)
24
+ find_window(IMPOSSIBLE, IMPOSSIBLE)
25
25
  GetLastError().should == ERROR_FILE_NOT_FOUND
26
26
  window_text(0)
27
27
  GetLastError().should == ERROR_INVALID_WINDOW_HANDLE
28
28
  end
29
29
 
30
30
  it "enhanced api retrieves the message corresponding to last error code" do
31
- find_window(TEST_IMPOSSIBLE, TEST_IMPOSSIBLE)
31
+ find_window(IMPOSSIBLE, IMPOSSIBLE)
32
32
  get_last_error.should == "The system cannot find the file specified."
33
33
  window_text(0)
34
34
  get_last_error.should == "Invalid window handle."
@@ -40,7 +40,7 @@ module WinErrorTest
40
40
  spec{ use{ message = format_message(sys_flags, source=nil, message_id=0, language_id=0, :int, 0) }}
41
41
 
42
42
  it "original api formats a message string - system message" do
43
- find_window(TEST_IMPOSSIBLE, TEST_IMPOSSIBLE)
43
+ find_window(IMPOSSIBLE, IMPOSSIBLE)
44
44
  message_id = GetLastError()
45
45
  buf = buffer()
46
46
  num_chars = FormatMessage(sys_flags, nil, message_id, dw_language_id=0, buf, buf.size, :int, 0)
@@ -48,7 +48,7 @@ module WinErrorTest
48
48
  end
49
49
 
50
50
  it "snake_case api Formats a message string - system message" do
51
- find_window(TEST_IMPOSSIBLE, TEST_IMPOSSIBLE)
51
+ find_window(IMPOSSIBLE, IMPOSSIBLE)
52
52
  message = format_message(sys_flags, nil, dw_message_id=GetLastError())
53
53
  message.should == "The system cannot find the file specified."
54
54
  end
@@ -53,20 +53,20 @@ module WinTest
53
53
  end
54
54
 
55
55
  it 'raises error if char is not implemented punctuation' do
56
- ('!'..'/').each {|char| lambda {char.to_vkeys}.should raise_error TEST_CONVERSION_ERROR }
57
- (':'..'@').each {|char| lambda {char.to_vkeys}.should raise_error TEST_CONVERSION_ERROR }
58
- ('['..'`').each {|char| lambda {char.to_vkeys}.should raise_error TEST_CONVERSION_ERROR }
59
- ('{'..'~').each {|char| lambda {char.to_vkeys}.should raise_error TEST_CONVERSION_ERROR }
56
+ ('!'..'/').each {|char| lambda {char.to_vkeys}.should raise_error CONVERSION_ERROR }
57
+ (':'..'@').each {|char| lambda {char.to_vkeys}.should raise_error CONVERSION_ERROR }
58
+ ('['..'`').each {|char| lambda {char.to_vkeys}.should raise_error CONVERSION_ERROR }
59
+ ('{'..'~').each {|char| lambda {char.to_vkeys}.should raise_error CONVERSION_ERROR }
60
60
  end
61
61
 
62
62
  it 'raises error if char is non-printable or non-ascii' do
63
- lambda {1.chr.to_vkeys}.should raise_error TEST_CONVERSION_ERROR
64
- lambda {230.chr.to_vkeys}.should raise_error TEST_CONVERSION_ERROR
63
+ lambda {1.chr.to_vkeys}.should raise_error CONVERSION_ERROR
64
+ lambda {230.chr.to_vkeys}.should raise_error CONVERSION_ERROR
65
65
  end
66
66
 
67
67
  it 'raises error if string is multi-char' do
68
- lambda {'hello'.to_vkeys}.should raise_error TEST_CONVERSION_ERROR
69
- lambda {'23'.to_vkeys}.should raise_error TEST_CONVERSION_ERROR
68
+ lambda {'hello'.to_vkeys}.should raise_error CONVERSION_ERROR
69
+ lambda {'23'.to_vkeys}.should raise_error CONVERSION_ERROR
70
70
  end
71
71
  end
72
72
  end
@@ -17,9 +17,9 @@ module WinWindowTest
17
17
  text = '12 34'
18
18
  text.upcase.each_byte do |b| # upcase needed since user32 keybd_event expects upper case chars
19
19
  keybd_event(b.ord, 0, KEYEVENTF_KEYDOWN, 0)
20
- sleep TEST_KEY_DELAY
20
+ sleep KEY_DELAY
21
21
  keybd_event(b.ord, 0, KEYEVENTF_KEYUP, 0)
22
- sleep TEST_KEY_DELAY
22
+ sleep KEY_DELAY
23
23
  end
24
24
  text(app.textarea).should =~ Regexp.new(text)
25
25
  5.times {keystroke(VK_CONTROL, 'Z'.ord)} # rolling back changes to allow window closing without dialog!
@@ -52,7 +52,7 @@ module WinGuiMessageTest
52
52
  it 'places (posts) a message in the message queue associated with the thread that created the specified window' do
53
53
  app = launch_test_app
54
54
  post_message(app.handle, WM_SYSCOMMAND, SC_CLOSE, nil).should == true
55
- sleep TEST_SLEEP_DELAY
55
+ sleep SLEEP_DELAY
56
56
  window?(app.handle).should == false
57
57
  end
58
58
 
@@ -80,7 +80,7 @@ module WinGuiMessageTest
80
80
  buffer.get_bytes(0, num_chars).should =~ /Welcome to Steganos LockNote/
81
81
 
82
82
  send_message(app.handle, WM_SYSCOMMAND, SC_CLOSE, nil)
83
- sleep TEST_SLEEP_DELAY # delay to allow window close
83
+ sleep SLEEP_DELAY # delay to allow window close
84
84
  window?(app.handle).should == false
85
85
  end
86
86
  end # describe '#send_message'
@@ -104,7 +104,7 @@ module WinGuiMessageTest
104
104
  @data.should == nil
105
105
  @result.should == nil
106
106
 
107
- sleep TEST_SLEEP_DELAY # small delay to allow message delivery
107
+ sleep SLEEP_DELAY # small delay to allow message delivery
108
108
  peek_message # dispatching sent message (even though there is nothing in queue)
109
109
 
110
110
  @handle.should == @app.handle
@@ -118,7 +118,7 @@ module WinGuiMessageTest
118
118
  sent.should == true
119
119
  @data.should == nil
120
120
 
121
- sleep TEST_SLEEP_DELAY # small delay to allow message delivery
121
+ sleep SLEEP_DELAY # small delay to allow message delivery
122
122
  peek_message # dispatching sent message (even though there is nothing in queue)
123
123
 
124
124
  @data.should == 0
@@ -135,16 +135,16 @@ module WinWindowTest
135
135
 
136
136
  it 'returns either Integer Window handle or nil' do
137
137
  find_window(nil, nil).should be_a_kind_of Integer
138
- find_window(TEST_IMPOSSIBLE, nil).should == nil
138
+ find_window(IMPOSSIBLE, nil).should == nil
139
139
  end
140
140
 
141
141
  it 'returns nil if Window is not found' do
142
- find_window(TEST_IMPOSSIBLE, nil).should == nil
143
- find_window(nil, TEST_IMPOSSIBLE).should == nil
144
- find_window(TEST_IMPOSSIBLE, TEST_IMPOSSIBLE).should == nil
145
- find_window_w(TEST_IMPOSSIBLE, nil).should == nil
146
- find_window_w(nil, TEST_IMPOSSIBLE).should == nil
147
- find_window_w(TEST_IMPOSSIBLE, TEST_IMPOSSIBLE).should == nil
142
+ find_window(IMPOSSIBLE, nil).should == nil
143
+ find_window(nil, IMPOSSIBLE).should == nil
144
+ find_window(IMPOSSIBLE, IMPOSSIBLE).should == nil
145
+ find_window_w(IMPOSSIBLE, nil).should == nil
146
+ find_window_w(nil, IMPOSSIBLE).should == nil
147
+ find_window_w(IMPOSSIBLE, IMPOSSIBLE).should == nil
148
148
  end
149
149
 
150
150
  it 'finds at least one window if both args are nils' do
@@ -154,10 +154,10 @@ module WinWindowTest
154
154
 
155
155
  it 'finds top-level window by window class or title' do
156
156
  test_app do |app|
157
- find_window(TEST_WIN_CLASS, nil).should == app.handle
158
- find_window(nil, TEST_WIN_TITLE).should == app.handle
159
- find_window_w(TEST_WIN_CLASS.to_w, nil).should == app.handle
160
- find_window_w(nil, TEST_WIN_TITLE.to_w).should == app.handle
157
+ find_window(WIN_CLASS, nil).should == app.handle
158
+ find_window(nil, WIN_TITLE).should == app.handle
159
+ find_window_w(WIN_CLASS.to_w, nil).should == app.handle
160
+ find_window_w(nil, WIN_TITLE.to_w).should == app.handle
161
161
  end
162
162
  end
163
163
  end
@@ -168,13 +168,13 @@ module WinWindowTest
168
168
 
169
169
  it 'returns nil if wrong control is given' do
170
170
  parent_handle = any_handle
171
- find_window_ex(parent_handle, 0, TEST_IMPOSSIBLE, nil).should == nil
172
- find_window_ex(parent_handle, 0, nil, TEST_IMPOSSIBLE).should == nil
171
+ find_window_ex(parent_handle, 0, IMPOSSIBLE, nil).should == nil
172
+ find_window_ex(parent_handle, 0, nil, IMPOSSIBLE).should == nil
173
173
  end
174
174
 
175
175
  it 'finds child window/control by class' do
176
176
  test_app do |app|
177
- ta_handle = find_window_ex(app.handle, 0, TEST_TEXTAREA_CLASS, nil)
177
+ ta_handle = find_window_ex(app.handle, 0, TEXTAREA_CLASS, nil)
178
178
  ta_handle.should_not == nil
179
179
  ta_handle.should == app.textarea
180
180
  end
@@ -252,10 +252,10 @@ module WinWindowTest
252
252
 
253
253
  it 'returns correct window text' do
254
254
  test_app do |app|
255
- get_window_text(app.handle).should == TEST_WIN_TITLE
256
- get_window_text_w(app.handle).should == TEST_WIN_TITLE
257
- window_text(app.handle).should == TEST_WIN_TITLE
258
- window_text_w(app.handle).should == TEST_WIN_TITLE
255
+ get_window_text(app.handle).should == WIN_TITLE
256
+ get_window_text_w(app.handle).should == WIN_TITLE
257
+ window_text(app.handle).should == WIN_TITLE
258
+ window_text_w(app.handle).should == WIN_TITLE
259
259
  end
260
260
  end
261
261
  end
@@ -272,10 +272,10 @@ module WinWindowTest
272
272
 
273
273
  it 'returns correct window class name' do
274
274
  test_app do |app|
275
- get_class_name(app.handle).should == TEST_WIN_CLASS
276
- class_name(app.handle).should == TEST_WIN_CLASS
277
- class_name_w(app.handle).should == TEST_WIN_CLASS #!!!!!!!!!!! nil?
278
- get_class_name_w(app.handle).should == TEST_WIN_CLASS #!!!!!! nil?
275
+ get_class_name(app.handle).should == WIN_CLASS
276
+ class_name(app.handle).should == WIN_CLASS
277
+ class_name_w(app.handle).should == WIN_CLASS #!!!!!!!!!!! nil?
278
+ get_class_name_w(app.handle).should == WIN_CLASS #!!!!!! nil?
279
279
  end
280
280
  end
281
281
  end
@@ -310,7 +310,7 @@ module WinWindowTest
310
310
 
311
311
  it 'returns window`s border rectangle' do
312
312
  test_app do |app|
313
- get_window_rect(app.handle).should == TEST_WIN_RECT
313
+ get_window_rect(app.handle).should == WIN_RECT
314
314
  end
315
315
  end
316
316
  end
@@ -399,12 +399,128 @@ module WinWindowTest
399
399
  end
400
400
  end # describe 'destroy_window'
401
401
 
402
+
402
403
  end # context 'ensuring test app closes'
403
404
 
404
405
  context 'with single test app' do
405
406
  before(:all){@app = launch_test_app}
406
407
  after(:all){close_test_app}
407
408
 
409
+ describe "#get_parent" do
410
+ spec{ use{ parent = GetParent(any_handle) }}
411
+ spec{ use{ parent = get_parent(any_handle) }}
412
+
413
+ it "retrieves a handle to the specified window's parent or owner." do
414
+ child = find_window_ex(@app.handle, 0, nil, nil)
415
+ parent1 = GetParent(child)
416
+ parent2 = get_parent(child)
417
+ parent1.should == parent2
418
+ parent1.should == @app.handle
419
+ end
420
+
421
+ it "returns 0/nil if the specified window has no parent or owner." do
422
+ GetParent(@app.handle).should == 0
423
+ get_parent(@app.handle).should == nil
424
+ end
425
+ end # describe get_parent
426
+
427
+ describe "#get_ancestor" do
428
+ spec{ use{ ancestor = GetAncestor(any_handle, ga_flags=0) }}
429
+ spec{ use{ ancestor = get_ancestor(any_handle, ga_flags=0) }}
430
+
431
+ context 'GA_PARENT - Retrieves parent window. Unlike GetParent function, this does NOT include the owner.' do
432
+ it "retrieves a handle to the specified window's parent" do
433
+ child = find_window_ex(@app.handle, 0, nil, nil)
434
+ parent1 = GetAncestor(child, GA_PARENT)
435
+ parent2 = get_ancestor(child, GA_PARENT)
436
+ parent1.should == parent2
437
+ parent1.should == @app.handle
438
+ end
439
+
440
+ it "returns desktop handle for top-level window" do
441
+ parent = get_ancestor(@app.handle, GA_PARENT)
442
+ class_name(parent).should == DESKTOP_CLASS
443
+ end
444
+
445
+ it "returns 0/nil if the specified window is a desktop (has REALLY no parent)" do
446
+ desktop = get_ancestor(@app.handle, GA_PARENT)
447
+ GetAncestor(desktop, GA_PARENT).should == 0
448
+ get_ancestor(desktop, GA_PARENT).should == nil
449
+ end
450
+ end # context GA_PARENT
451
+
452
+ # GA_ROOT - Retrieves the root window by walking the chain of parent windows.
453
+ # GA_ROOTOWNER - Retrieves the owned root window by walking the chain of parent and owner windows
454
+ # returned by GetParent.
455
+ it "original api retrieves the handle to the ancestor of the specified window. " do
456
+ pending
457
+ success = GetAncestor(hwnd=0, ga_flags=0)
458
+ end
459
+
460
+ it "snake_case api retrieves the handle to the ancestor of the specified window. " do
461
+ pending
462
+ success = get_ancestor(hwnd=0, ga_flags=0)
463
+ end
464
+
465
+ end # describe get_ancestor
466
+
467
+ describe "#get_window" do
468
+ spec{ use{ handle = GetWindow(any_handle, command=0) }}
469
+ spec{ use{ handle = get_window(any_handle, command=0) }}
470
+
471
+ context "GW_CHILD retrieves a window handle to a first (top of the Z order) child of given window" do
472
+ before(:all) do
473
+ # GW_CHILD - The retrieved handle identifies the child window at the top of the Z order, if the specified
474
+ @child1 = GetWindow(@app.handle, GW_CHILD)
475
+ @child2 = get_window(@app.handle, GW_CHILD)
476
+ end
477
+
478
+ it 'returns active window handle' do
479
+ window?(@child1).should == true
480
+ end
481
+ it 'returns the same value for original and snake case API' do
482
+ @child1.should == @child2
483
+ end
484
+ it 'returns first direct child of a given window' do
485
+ @child1.should == find_window_ex(@app.handle, 0, nil, nil)
486
+ end
487
+ it 'returns nil/0 if no children for a given window' do
488
+ GetWindow(@child1, GW_CHILD).should == 0
489
+ get_window(@child1, GW_CHILD).should == nil
490
+ end
491
+ end # context GW_CHILD
492
+
493
+ context "GW_OWNER - retrieves a handle to an owner of a given Window" do
494
+ # GW_OWNER - The retrieved handle identifies the specified window's owner window, if any. For more
495
+
496
+ it 'returns owner (but NOT parent!) of a given window' do
497
+ pending
498
+
499
+ child = find_window_ex(@app.handle, 0, nil, nil)
500
+ p owner1 = GetWindow(child, GW_OWNER)
501
+ p owner2 = get_window(child, GW_OWNER)
502
+ owner1.should == owner2
503
+ owner1.should == @app.handle
504
+ end
505
+
506
+ it 'returns nil/0 if no owner for a given window' do
507
+ GetWindow(@app.handle, GW_OWNER).should == 0
508
+ get_window(@app.handle, GW_OWNER).should == nil
509
+ end
510
+
511
+ end
512
+
513
+ it "GW_OWNER - retrieves a handle to a window that has the specified relationship to given Window" do
514
+ pending
515
+ # GW_ENABLEDPOPUP - Windows 2000/XP: The retrieved handle identifies the enabled popup window owned by
516
+ # GW_HWNDFIRST - The retrieved handle identifies the window of the same type that is highest in Z order.
517
+ # GW_HWNDLAST - The retrieved handle identifies the window of the same type that is lowest in the Z order.
518
+ # GW_HWNDNEXT - The retrieved handle identifies the window below the specified window in the Z order.
519
+ # GW_HWNDPREV - The retrieved handle identifies the window above the specified window in the Z order.
520
+ # GW_OWNER - The retrieved handle identifies the specified window's owner window, if any. For more
521
+ end
522
+ end # describe get_window
523
+
408
524
  describe '#enum_windows' do
409
525
  # before(:each){@app = launch_test_app}
410
526
  # after(:each){close_test_app}
@@ -460,8 +576,8 @@ module WinWindowTest
460
576
  enum = enum_child_windows(@app.handle, 13)
461
577
  enum.should be_a_kind_of Array
462
578
  enum.should have(2).elements
463
- class_name(enum.first).should == TEST_STATUSBAR_CLASS
464
- class_name(enum.last).should == TEST_TEXTAREA_CLASS
579
+ class_name(enum.first).should == STATUSBAR_CLASS
580
+ class_name(enum.last).should == TEXTAREA_CLASS
465
581
  end
466
582
 
467
583
  it 'loops through all children of given window, passing each found window handle and a message to a given block' do
@@ -471,8 +587,8 @@ module WinWindowTest
471
587
  message.should == 13
472
588
  end
473
589
  enum.should have(2).elements
474
- class_name(enum.first).should == TEST_STATUSBAR_CLASS
475
- class_name(enum.last).should == TEST_TEXTAREA_CLASS
590
+ class_name(enum.first).should == STATUSBAR_CLASS
591
+ class_name(enum.last).should == TEXTAREA_CLASS
476
592
  end
477
593
 
478
594
  it 'breaks loop if given block returns false' do
@@ -482,7 +598,7 @@ module WinWindowTest
482
598
  false
483
599
  end
484
600
  enum.should have(1).element
485
- class_name(enum.first).should == TEST_STATUSBAR_CLASS
601
+ class_name(enum.first).should == STATUSBAR_CLASS
486
602
  end
487
603
 
488
604
  it 'defaults message to 0 if it is omitted from method call' do
@@ -528,7 +644,7 @@ module WinWindowTest
528
644
  app = launch_test_app
529
645
 
530
646
  shut_window(app.handle).should == true
531
- sleep TEST_SLEEP_DELAY
647
+ sleep SLEEP_DELAY
532
648
 
533
649
  window?(app.handle).should == false
534
650
  end
@@ -540,7 +656,7 @@ module WinWindowTest
540
656
  it 'returns text associated with window by sending WM_GETTEXT message to it' do
541
657
  test_app do |app|
542
658
 
543
- text(app.handle).should == TEST_WIN_TITLE
659
+ text(app.handle).should == WIN_TITLE
544
660
  text(app.textarea).should =~ /Welcome to Steganos LockNote/
545
661
  end
546
662
  end
@@ -92,12 +92,12 @@ module WinLibraryTest
92
92
 
93
93
  it 'constructs argument prototype from uppercase string, enforces the args count' do
94
94
  expect { MyLib.function :FindWindow, 'PP', 'L' }.to_not raise_error
95
- should_count_args :find_window, :FindWindow, [nil, nil], [nil, TEST_IMPOSSIBLE, 'cmd']
95
+ should_count_args :find_window, :FindWindow, [nil, nil], [nil, IMPOSSIBLE, 'cmd']
96
96
  end
97
97
 
98
98
  it 'constructs argument prototype from (mixed) array, enforces the args count' do
99
99
  expect { MyLib.function :FindWindow, [:pointer, 'P'], 'L' }.to_not raise_error
100
- should_count_args :find_window, :FindWindow, [nil, nil], [nil, TEST_IMPOSSIBLE, 'cmd']
100
+ should_count_args :find_window, :FindWindow, [nil, nil], [nil, IMPOSSIBLE, 'cmd']
101
101
  end
102
102
 
103
103
  it 'with :rename option, overrides snake_case name for defined method but leaves CamelCase intact' do
@@ -110,17 +110,17 @@ module WinLibraryTest
110
110
  it 'defined snake_case method returns expected value when called' do
111
111
  MyLib.function :FindWindow, 'PP', 'L'
112
112
  find_window(nil, nil).should_not == 0
113
- find_window(nil, TEST_IMPOSSIBLE).should == 0
114
- find_window(TEST_IMPOSSIBLE, nil).should == 0
115
- find_window(TEST_IMPOSSIBLE, TEST_IMPOSSIBLE).should == 0
113
+ find_window(nil, IMPOSSIBLE).should == 0
114
+ find_window(IMPOSSIBLE, nil).should == 0
115
+ find_window(IMPOSSIBLE, IMPOSSIBLE).should == 0
116
116
  end
117
117
 
118
118
  it 'defined CamelCase method returns expected value when called' do
119
119
  MyLib.function :FindWindow, 'PP', 'L'
120
120
  FindWindow(nil, nil).should_not == 0
121
- FindWindow(nil, TEST_IMPOSSIBLE).should == 0
122
- FindWindow(TEST_IMPOSSIBLE, nil).should == 0
123
- FindWindow(TEST_IMPOSSIBLE, TEST_IMPOSSIBLE).should == 0
121
+ FindWindow(nil, IMPOSSIBLE).should == 0
122
+ FindWindow(IMPOSSIBLE, nil).should == 0
123
+ FindWindow(IMPOSSIBLE, IMPOSSIBLE).should == 0
124
124
  end
125
125
 
126
126
  # it 'returns underlying Win32::API object if defined method is called with (:api) argument ' do
@@ -172,17 +172,17 @@ module WinLibraryTest
172
172
 
173
173
  it 'defined snake_case method returns false/true instead of zero/non-zero' do
174
174
  find_window(nil, nil).should == true
175
- find_window(nil, TEST_IMPOSSIBLE).should == false
175
+ find_window(nil, IMPOSSIBLE).should == false
176
176
  end
177
177
 
178
178
  it 'defined CamelCase method still returns zero/non-zero' do
179
179
  FindWindow(nil, nil).should_not == true
180
180
  FindWindow(nil, nil).should_not == 0
181
- FindWindow(nil, TEST_IMPOSSIBLE).should == 0
181
+ FindWindow(nil, IMPOSSIBLE).should == 0
182
182
  end
183
183
 
184
184
  it 'defined methods enforce the argument count' do
185
- should_count_args :find_window, :FindWindow, [nil, nil], [nil, TEST_IMPOSSIBLE, 'cmd']
185
+ should_count_args :find_window, :FindWindow, [nil, nil], [nil, IMPOSSIBLE, 'cmd']
186
186
  end
187
187
  end
188
188
 
@@ -197,12 +197,12 @@ module WinLibraryTest
197
197
  it 'defined CamelCase method still returns zero/non-zero' do
198
198
  FindWindow(nil, nil).should_not == true
199
199
  FindWindow(nil, nil).should_not == 0
200
- FindWindow(nil, TEST_IMPOSSIBLE).should == 0
200
+ FindWindow(nil, IMPOSSIBLE).should == 0
201
201
  end
202
202
 
203
203
  it 'defined method returns nil (but NOT false) instead of zero' do
204
- find_window(nil, TEST_IMPOSSIBLE).should_not == false
205
- find_window(nil, TEST_IMPOSSIBLE).should == nil
204
+ find_window(nil, IMPOSSIBLE).should_not == false
205
+ find_window(nil, IMPOSSIBLE).should == nil
206
206
  end
207
207
 
208
208
  it 'defined method does not return true when result is non-zero' do
@@ -211,7 +211,7 @@ module WinLibraryTest
211
211
  end
212
212
 
213
213
  it 'defined methods enforce the argument count' do
214
- should_count_args :find_window, :FindWindow, [nil, nil], [nil, TEST_IMPOSSIBLE, 'cmd']
214
+ should_count_args :find_window, :FindWindow, [nil, nil], [nil, IMPOSSIBLE, 'cmd']
215
215
  end
216
216
  end
217
217
 
@@ -292,18 +292,18 @@ module WinLibraryTest
292
292
  context 'calling defined methods with attached block to preprocess the API function results' do
293
293
  it 'defined method yields raw result to block attached to its invocation' do
294
294
  MyLib.function :FindWindow, 'PP', 'L', zeronil: true
295
- find_window(nil, TEST_IMPOSSIBLE) {|result| result.should == 0 }
295
+ find_window(nil, IMPOSSIBLE) {|result| result.should == 0 }
296
296
  end
297
297
 
298
298
  it 'defined method returns result of block attached to its invocation' do
299
299
  MyLib.function :FindWindow, 'PP', 'L', zeronil: true
300
- return_value = find_window(nil, TEST_IMPOSSIBLE) {|result| 'Value'}
300
+ return_value = find_window(nil, IMPOSSIBLE) {|result| 'Value'}
301
301
  return_value.should == 'Value'
302
302
  end
303
303
 
304
304
  it 'defined method transforms result of block before returning it' do
305
305
  MyLib.function :FindWindow, 'PP', 'L', zeronil: true
306
- return_value = find_window(nil, TEST_IMPOSSIBLE) {|result| 0 }
306
+ return_value = find_window(nil, IMPOSSIBLE) {|result| 0 }
307
307
  return_value.should_not == 0
308
308
  return_value.should == nil
309
309
  end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 3
8
- - 3
9
- version: 0.3.3
8
+ - 5
9
+ version: 0.3.5
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-04-17 00:00:00 +04:00
17
+ date: 2010-05-28 00:00:00 +04:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency