rdp-win32screenshot 0.0.6.2 → 0.0.6.3

Sign up to get free protection for your applications and to get access to all the features.
data/History.rdoc CHANGED
@@ -1,6 +1,15 @@
1
- = 0.0.6 2010-XX-XX
1
+ = 0.0.6 2010-08-07
2
2
  * Trying to bring window to the foreground more aggressively (Roger Pack)
3
- * Minor bug fixes with using gdi32.dll BitBlt (Roger Pack)
3
+ * Added utility class Win32::Screenshot.Util with some helper methods not related directly with taking of the screenshots:
4
+ - all_windows - enumerates all windows and returns their titles and window handles as an Array (Roger Pack)
5
+ - window_title(hwnd) - returns title of the window for specified handle (Jarmo Pertman)
6
+ - window_hwnd(title_query) - returns handle of the window for specified title (Jarmo Pertman)
7
+ - dimensions_for(hwnd) - returns a width and height for a window with specified handle (Jarmo Pertman)
8
+ * Removed a file 'win32screenshot.rb' which was solely used for displaying deprecation warnings for versions older than 0.0.4. Make sure than from now on all require statements require 'win32/screenshot'!
9
+
10
+ == Bug Fixes:
11
+ * Fixed usages of gdi32.dll BitBlt (Roger Pack)
12
+ * It was impossible to specify correctly window titles with regular expressions special characters in them (Roger Pack)
4
13
 
5
14
  = 0.0.5 2010-07-07
6
15
  * Added method window_area for capturing specified area of the window instead of full window (Jarmo Pertman)
data/README.rdoc CHANGED
@@ -71,6 +71,25 @@ other formats like png.
71
71
  File.open("picture10.png", "wb") {|file| file.puts png}
72
72
  end
73
73
 
74
+ #
75
+ # Win32::Screenshot has also some utility methods which can be used for various needs
76
+
77
+ # enumerate all windows and return their titles and handles
78
+ Win32::Screenshot::Util.all_windows # => [["title1", 2345], ["title2", 3456]]
79
+
80
+ # retrieve window title for the specified window handle
81
+ Win32::Screenshot::Util.window_title(2345) # => "title1"
82
+
83
+ # retrieve window handle for the specified title
84
+ Win32::Screenshot::Util.window_hwnd("title1") # => 2345
85
+
86
+ # title can be also a regular expression with first matching window retrieved
87
+ Win32::Screenshot::Util.window_hwnd(/tit.*1/) # => 2345
88
+
89
+ # retrive dimensions of a window with specified handle in an Array of [width, height]
90
+ # might be useful for using with different capture_area methods
91
+ Win32::Screenshot::Util.dimensions_for(2345) # => [100, 200]
92
+
74
93
  == Copyright
75
94
 
76
95
  Copyright (c) 2010 Jarmo Pertman, Aslak Hellesøy. See LICENSE for details.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.6.2
1
+ 0.0.6.3
@@ -3,186 +3,164 @@ require 'ffi'
3
3
  module Win32
4
4
  class Screenshot
5
5
  # internal methods
6
- module BitmapMaker #:nodoc:all
7
- extend FFI::Library
8
-
9
- ffi_lib 'user32', 'gdi32'
10
- ffi_convention :stdcall
11
-
12
- callback :enum_callback, [:long, :pointer], :bool
13
-
14
- # user32.dll
15
- attach_function :enum_windows, :EnumWindows,
16
- [:enum_callback, :pointer], :long
17
- attach_function :window_text, :GetWindowTextA,
18
- [:long, :pointer, :int], :int
19
- attach_function :window_text_length, :GetWindowTextLengthA,
20
- [:long], :int
21
- attach_function :window_visible, :IsWindowVisible,
22
- [:long], :bool
23
- attach_function :dc, :GetDC,
24
- [:long], :long
25
- attach_function :client_rect, :GetClientRect,
26
- [:long, :pointer], :bool
27
- attach_function :minimized, :IsIconic,
28
- [:long], :bool
29
- attach_function :show_window, :ShowWindow,
30
- [:long, :int], :bool
31
- attach_function :foreground_window, :GetForegroundWindow,
32
- [], :long
33
- attach_function :desktop_window, :GetDesktopWindow,
34
- [], :long
35
- attach_function :window_thread_process_id, :GetWindowThreadProcessId,
36
- [:long, :pointer], :long
37
- attach_function :attach_thread_input, :AttachThreadInput,
38
- [:long, :long, :bool], :bool
39
- attach_function :set_foreground_window, :SetForegroundWindow,
40
- [:long], :bool
41
- attach_function :bring_window_to_top, :BringWindowToTop,
42
- [:long], :bool
43
- attach_function :set_active_window, :SetActiveWindow,
44
- [:long], :long
45
-
46
-
47
- # gdi32.dll
48
- attach_function :create_compatible_dc, :CreateCompatibleDC,
49
- [:long], :long
50
- attach_function :create_compatible_bitmap, :CreateCompatibleBitmap,
51
- [:long, :int, :int], :long
52
- attach_function :select_object, :SelectObject,
53
- [:long, :long], :long
54
- attach_function :bit_blt, :BitBlt,
55
- [:long, :int, :int, :int, :int, :long, :int, :int, :long], :bool
56
- attach_function :di_bits, :GetDIBits,
57
- [:long, :long, :int, :int, :pointer, :pointer, :int], :int
58
- attach_function :delete_object, :DeleteObject,
59
- [:long], :bool
60
- attach_function :delete_dc, :DeleteDC,
61
- [:long], :bool
62
- attach_function :release_dc, :ReleaseDC,
63
- [:long, :long], :int
64
-
65
-
66
- EnumWindowCallback = Proc.new do |hwnd, param|
67
- searched_window = WindowStruct.new param
68
- title_length = window_text_length(hwnd) + 1
69
- title = FFI::MemoryPointer.new :char, title_length
70
- window_text(hwnd, title, title_length)
71
- title = title.read_string
72
- if title =~ Regexp.new(searched_window[:title].read_string) && window_visible(hwnd)
73
- searched_window[:hwnd] = hwnd
74
- false
75
- else
76
- true
6
+ class BitmapMaker #:nodoc:all
7
+ class << self
8
+ extend FFI::Library
9
+
10
+ ffi_lib 'user32', 'gdi32'
11
+ ffi_convention :stdcall
12
+ callback :enum_callback, [:long, :pointer], :bool
13
+
14
+ # user32.dll
15
+ attach_function :enum_windows, :EnumWindows,
16
+ [:enum_callback, :pointer], :long
17
+ attach_function :window_text, :GetWindowTextA,
18
+ [:long, :pointer, :int], :int
19
+ attach_function :window_text_length, :GetWindowTextLengthA,
20
+ [:long], :int
21
+ attach_function :window_visible, :IsWindowVisible,
22
+ [:long], :bool
23
+ attach_function :dc, :GetDC,
24
+ [:long], :long
25
+ attach_function :client_rect, :GetClientRect,
26
+ [:long, :pointer], :bool
27
+ attach_function :minimized, :IsIconic,
28
+ [:long], :bool
29
+ attach_function :show_window, :ShowWindow,
30
+ [:long, :int], :bool
31
+ attach_function :foreground_window, :GetForegroundWindow,
32
+ [], :long
33
+ attach_function :desktop_window, :GetDesktopWindow,
34
+ [], :long
35
+ attach_function :window_thread_process_id, :GetWindowThreadProcessId,
36
+ [:long, :pointer], :long
37
+ attach_function :attach_thread_input, :AttachThreadInput,
38
+ [:long, :long, :bool], :bool
39
+ attach_function :set_foreground_window, :SetForegroundWindow,
40
+ [:long], :bool
41
+ attach_function :bring_window_to_top, :BringWindowToTop,
42
+ [:long], :bool
43
+ attach_function :set_active_window, :SetActiveWindow,
44
+ [:long], :long
45
+
46
+
47
+ # gdi32.dll
48
+ attach_function :create_compatible_dc, :CreateCompatibleDC,
49
+ [:long], :long
50
+ attach_function :create_compatible_bitmap, :CreateCompatibleBitmap,
51
+ [:long, :int, :int], :long
52
+ attach_function :select_object, :SelectObject,
53
+ [:long, :long], :long
54
+ attach_function :bit_blt, :BitBlt,
55
+ [:long, :int, :int, :int, :int, :long, :int, :int, :long], :bool
56
+ attach_function :di_bits, :GetDIBits,
57
+ [:long, :long, :int, :int, :pointer, :pointer, :int], :int
58
+ attach_function :delete_object, :DeleteObject,
59
+ [:long], :bool
60
+ attach_function :delete_dc, :DeleteDC,
61
+ [:long], :bool
62
+ attach_function :release_dc, :ReleaseDC,
63
+ [:long, :long], :int
64
+
65
+
66
+ EnumWindowCallback = FFI::Function.new(:bool, [ :long, :pointer ], { :convention => :stdcall }) do |hwnd, param|
67
+ searched_window = WindowStruct.new param
68
+ title = Util.window_title(hwnd)
69
+ if title =~ Regexp.new(searched_window[:title].read_string) && window_visible(hwnd)
70
+ searched_window[:hwnd] = hwnd
71
+ false
72
+ else
73
+ true
74
+ end
77
75
  end
78
- end
79
-
80
- module_function
81
-
82
- class WindowStruct < FFI::Struct
83
- layout :title, :pointer,
84
- :hwnd, :long
85
- end
86
76
 
87
- def hwnd(window_title)
88
- window = WindowStruct.new
89
- unless window_title.is_a? Regexp
90
- window_title = Regexp.escape(window_title.to_s)
91
- end
92
- window_title = FFI::MemoryPointer.from_string(window_title.to_s)
93
- window[:title] = window_title
94
- enum_windows(EnumWindowCallback, window.to_ptr)
95
- window[:hwnd] == 0 ? nil : window[:hwnd]
96
- end
97
-
98
- def list_window_titles
99
- out = []
100
- out_proc = Proc.new do |hwnd, param|
101
- title_length = window_text_length(hwnd) + 1
102
- title = FFI::MemoryPointer.new :char, title_length
103
- window_text(hwnd, title, title_length)
104
- out << title.read_string
105
- true
77
+ class WindowStruct < FFI::Struct
78
+ layout :title, :pointer,
79
+ :hwnd, :long
106
80
  end
107
-
108
- enum_windows(out_proc, nil)
109
- out
110
- end
111
81
 
112
- def prepare_window(hwnd, pause)
113
- restore(hwnd) if minimized(hwnd)
114
- set_foreground(hwnd)
115
- sleep pause
116
- end
82
+ def hwnd(window_title)
83
+ window = WindowStruct.new
84
+ unless window_title.is_a?(Regexp)
85
+ window_title = Regexp.escape(window_title.to_s)
86
+ else
87
+ window_title = window_title.to_s
88
+ end
89
+ window_title = FFI::MemoryPointer.from_string(window_title)
90
+ window[:title] = window_title
91
+ enum_windows(EnumWindowCallback, window.to_ptr)
92
+ window[:hwnd] == 0 ? nil : window[:hwnd]
93
+ end
117
94
 
118
- SW_RESTORE = 9
95
+ def prepare_window(hwnd, pause)
96
+ restore(hwnd) if minimized(hwnd)
97
+ set_foreground(hwnd)
98
+ sleep pause
99
+ end
119
100
 
120
- def restore(hwnd)
121
- show_window(hwnd, SW_RESTORE)
122
- end
101
+ SW_RESTORE = 9
123
102
 
124
- def set_foreground(hwnd)
125
- if foreground_window != hwnd
126
- set_foreground_window(hwnd)
127
- set_active_window(hwnd)
128
- bring_window_to_top(hwnd)
129
- # and just in case...
130
- foreground_thread = window_thread_process_id(foreground_window, nil)
131
- other_thread = window_thread_process_id(hwnd, nil)
132
- attach_thread_input(foreground_thread, other_thread, true) unless other_thread == foreground_thread
133
- set_foreground_window(hwnd)
134
- set_active_window(hwnd)
135
- bring_window_to_top(hwnd)
136
- attach_thread_input(foreground_thread, other_thread, false) unless other_thread == foreground_thread
103
+ def restore(hwnd)
104
+ show_window(hwnd, SW_RESTORE)
137
105
  end
138
- end
139
106
 
140
- def dimensions_for(hwnd)
141
- rect = [0, 0, 0, 0].pack('L4')
142
- client_rect(hwnd, rect)
143
- x1, y1, x2, y2 = rect.unpack('L4')
144
- end
107
+ def set_foreground(hwnd)
108
+ if foreground_window != hwnd
109
+ set_foreground_window(hwnd)
110
+ set_active_window(hwnd)
111
+ bring_window_to_top(hwnd)
112
+ # and just in case...
113
+ foreground_thread = window_thread_process_id(foreground_window, nil)
114
+ other_thread = window_thread_process_id(hwnd, nil)
115
+ attach_thread_input(foreground_thread, other_thread, true) unless other_thread == foreground_thread
116
+ set_foreground_window(hwnd)
117
+ set_active_window(hwnd)
118
+ bring_window_to_top(hwnd)
119
+ attach_thread_input(foreground_thread, other_thread, false) unless other_thread == foreground_thread
120
+ end
121
+ end
145
122
 
146
- def capture_all(hwnd, &proc)
147
- x1, y1, x2, y2 = dimensions_for(hwnd)
148
- capture_area(hwnd, x1, y1, x2, y2, &proc)
149
- end
123
+ def capture_all(hwnd, &proc)
124
+ width, height = Util.dimensions_for(hwnd)
125
+ capture_area(hwnd, 0, 0, width, height, &proc)
126
+ end
150
127
 
151
- SRCCOPY = 0x00CC0020
152
- DIB_RGB_COLORS = 0
153
-
154
- def capture_area(hwnd, x1, y1, x2, y2, &proc)
155
- hScreenDC = dc(hwnd)
156
- w = x2-x1
157
- h = y2-y1
158
-
159
- hmemDC = create_compatible_dc(hScreenDC)
160
- hmemBM = create_compatible_bitmap(hScreenDC, w, h)
161
- select_object(hmemDC, hmemBM)
162
- bit_blt(hmemDC, 0, 0, w, h, hScreenDC, x1, y1, SRCCOPY)
163
- bitmap_size = w * h * 3 + w % 4 * h
164
- lpvpxldata = FFI::MemoryPointer.new(bitmap_size)
165
-
166
- # Bitmap header
167
- # http://www.fortunecity.com/skyscraper/windows/364/bmpffrmt.html
168
- bmInfo = [40, w, h, 1, 24, 0, 0, 0, 0, 0, 0, 0].pack('L3S2L6')
169
- di_bits(hmemDC, hmemBM, 0, h, lpvpxldata, bmInfo, DIB_RGB_COLORS)
170
-
171
- bmFileHeader = [
172
- 19778,
173
- bitmap_size + 40 + 14,
174
- 0,
175
- 0,
176
- 54
177
- ].pack('SLSSL')
178
-
179
- bmp_data = bmFileHeader + bmInfo + lpvpxldata.read_string(bitmap_size)
180
- proc.call(w, h, bmp_data)
181
- ensure
182
- lpvpxldata.free
183
- delete_object(hmemBM)
184
- delete_dc(hmemDC)
185
- release_dc(0, hScreenDC)
128
+ SRCCOPY = 0x00CC0020
129
+ DIB_RGB_COLORS = 0
130
+
131
+ def capture_area(hwnd, x1, y1, x2, y2) # block
132
+ hScreenDC = dc(hwnd)
133
+ w = x2-x1
134
+ h = y2-y1
135
+
136
+ hmemDC = create_compatible_dc(hScreenDC)
137
+ hmemBM = create_compatible_bitmap(hScreenDC, w, h)
138
+ select_object(hmemDC, hmemBM)
139
+ bit_blt(hmemDC, 0, 0, w, h, hScreenDC, x1, y1, SRCCOPY)
140
+ bitmap_size = w * h * 3 + w % 4 * h
141
+ lpvpxldata = FFI::MemoryPointer.new(bitmap_size)
142
+
143
+ # Bitmap header
144
+ # http://www.fortunecity.com/skyscraper/windows/364/bmpffrmt.html
145
+ bmInfo = [40, w, h, 1, 24, 0, 0, 0, 0, 0, 0, 0].pack('L3S2L6')
146
+ di_bits(hmemDC, hmemBM, 0, h, lpvpxldata, bmInfo, DIB_RGB_COLORS)
147
+
148
+ bmFileHeader = [
149
+ 19778,
150
+ bitmap_size + 40 + 14,
151
+ 0,
152
+ 0,
153
+ 54
154
+ ].pack('SLSSL')
155
+
156
+ bmp_data = bmFileHeader + bmInfo + lpvpxldata.read_string(bitmap_size)
157
+ yield(w, h, bmp_data)
158
+ ensure
159
+ lpvpxldata.free
160
+ delete_object(hmemBM)
161
+ delete_dc(hmemDC)
162
+ release_dc(0, hScreenDC)
163
+ end
186
164
  end
187
165
  end
188
166
  end
@@ -1,4 +1,5 @@
1
- require 'win32/screenshot/bitmap_maker'
1
+ require File.dirname(__FILE__) + '/screenshot/bitmap_maker'
2
+ require File.dirname(__FILE__) + '/util'
2
3
 
3
4
  module Win32
4
5
  # Captures screenshots with Ruby on Windows
@@ -44,7 +45,7 @@ module Win32
44
45
  # captures window with a *title_query* and waits *pause* (by default is 0.5)
45
46
  # seconds after trying to set window to the foreground
46
47
  def window(title_query, pause=0.5, &proc)
47
- hwnd = window_hwnd(title_query)
48
+ hwnd = Util.window_hwnd(title_query)
48
49
  hwnd(hwnd, pause, &proc)
49
50
  end
50
51
 
@@ -52,7 +53,7 @@ module Win32
52
53
  # where *x1* and *y1* are 0 in the upper left corner and
53
54
  # *x2* specifies the width and *y2* the height of the area to be captured
54
55
  def window_area(title_query, x1, y1, x2, y2, pause=0.5, &proc)
55
- hwnd = window_hwnd(title_query)
56
+ hwnd = Util.window_hwnd(title_query)
56
57
  hwnd_area(hwnd, x1, y1, x2, y2, pause, &proc)
57
58
  end
58
59
 
@@ -73,12 +74,6 @@ module Win32
73
74
 
74
75
  private
75
76
 
76
- def window_hwnd(title_query)
77
- hwnd = BitmapMaker.hwnd(title_query)
78
- raise "window with title '#{title_query}' was not found!" unless hwnd
79
- hwnd
80
- end
81
-
82
77
  def validate_coordinates(hwnd, *coords)
83
78
  specified_coordinates = coords.join(', ')
84
79
  if coords.any? {|c| c < 0}
@@ -89,9 +84,9 @@ module Win32
89
84
  raise "specified coordinates (#{specified_coordinates}) are invalid - cannot have x1 > x2 or y1 > y2!"
90
85
  end
91
86
 
92
- x1_always_zero, y1_always_zero, max_x2, max_y2 = BitmapMaker.dimensions_for(hwnd)
93
- if x2 > max_x2 || y2 > max_y2
94
- raise "specified coordinates (#{specified_coordinates}) are invalid - maximum are x2=#{max_x2} and y2=#{max_y2}!"
87
+ max_width, max_height = Util.dimensions_for(hwnd)
88
+ if x2 > max_width || y2 > max_height
89
+ raise "specified coordinates (#{specified_coordinates}) are invalid - maximum are x2=#{max_width} and y2=#{max_height}!"
95
90
  end
96
91
  end
97
92
  end
data/lib/win32/util.rb ADDED
@@ -0,0 +1,40 @@
1
+ module Win32
2
+ class Screenshot
3
+ class Util
4
+ class << self
5
+
6
+ def all_windows
7
+ titles = []
8
+ window_callback = FFI::Function.new(:bool, [ :long, :pointer ], { :convention => :stdcall }) do |hwnd, param|
9
+ titles << [window_title(hwnd), hwnd]
10
+ true
11
+ end
12
+
13
+ BitmapMaker.enum_windows(window_callback, nil)
14
+ titles
15
+ end
16
+
17
+ def window_title hwnd
18
+ title_length = BitmapMaker.window_text_length(hwnd) + 1
19
+ title = FFI::MemoryPointer.new :char, title_length
20
+ BitmapMaker.window_text(hwnd, title, title_length)
21
+ title.read_string
22
+ end
23
+
24
+ def window_hwnd(title_query)
25
+ hwnd = BitmapMaker.hwnd(title_query)
26
+ raise "window with title '#{title_query}' was not found!" unless hwnd
27
+ hwnd
28
+ end
29
+
30
+ def dimensions_for(hwnd)
31
+ rect = [0, 0, 0, 0].pack('L4')
32
+ BitmapMaker.client_rect(hwnd, rect)
33
+ _, _, width, height = rect.unpack('L4')
34
+ return width, height
35
+ end
36
+
37
+ end
38
+ end
39
+ end
40
+ end
data/spec/spec_helper.rb CHANGED
@@ -41,12 +41,21 @@ module SpecHelper
41
41
 
42
42
  def wait_for_programs_to_open
43
43
  until Win32::Screenshot::BitmapMaker.hwnd(/Internet Explorer/) &&
44
- Win32::Screenshot::BitmapMaker.hwnd(/Notepad/) &&
45
- Win32::Screenshot::BitmapMaker.hwnd(/Calculator/)
44
+ Win32::Screenshot::BitmapMaker.hwnd(/Notepad/)
45
+ sleep 0.1
46
+ end
47
+ wait_for_calculator_to_open
48
+
49
+ # just in case of slow PC
50
+ sleep 8
51
+ end
52
+
53
+ def wait_for_calculator_to_open
54
+ until Win32::Screenshot::BitmapMaker.hwnd(/Calculator/)
46
55
  sleep 0.1
47
56
  end
48
57
  # just in case of slow PC
49
- sleep 10
58
+ sleep 2
50
59
  end
51
60
 
52
61
  def maximize title
@@ -1,12 +1,11 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
2
 
3
- describe "win32-screenshot" do
4
- include SpecHelper
5
-
3
+ describe Win32::Screenshot do
4
+ include SpecHelper
5
+
6
6
  before :all do
7
- PROGRAM_FILES = "c:/program files/"
8
7
  @notepad = IO.popen("notepad").pid
9
- @iexplore = IO.popen(File.join(PROGRAM_FILES, "Internet Explorer", "iexplore about:blank")).pid
8
+ @iexplore = Dir.chdir("c:/program files/Internet Explorer") do; IO.popen(".\\iexplore about:blank").pid; end
10
9
  @calc = IO.popen("calc").pid
11
10
  wait_for_programs_to_open
12
11
  cleanup
@@ -16,9 +15,7 @@ describe "win32-screenshot" do
16
15
  Win32::Screenshot.foreground do |width, height, bmp|
17
16
  check_image(bmp, 'foreground')
18
17
  hwnd = Win32::Screenshot::BitmapMaker.foreground_window
19
- dimensions = Win32::Screenshot::BitmapMaker.dimensions_for(hwnd)
20
- width.should == dimensions[2]
21
- height.should == dimensions[3]
18
+ [width, height].should == Win32::Screenshot::Util.dimensions_for(hwnd)
22
19
  end
23
20
  end
24
21
 
@@ -39,9 +36,7 @@ describe "win32-screenshot" do
39
36
  Win32::Screenshot.desktop do |width, height, bmp|
40
37
  check_image(bmp, 'desktop')
41
38
  hwnd = Win32::Screenshot::BitmapMaker.desktop_window
42
- dimensions = Win32::Screenshot::BitmapMaker.dimensions_for(hwnd)
43
- width.should == dimensions[2]
44
- height.should == dimensions[3]
39
+ [width, height].should == Win32::Screenshot::Util.dimensions_for(hwnd)
45
40
  end
46
41
  end
47
42
 
@@ -64,9 +59,7 @@ describe "win32-screenshot" do
64
59
  Win32::Screenshot.window(title) do |width, height, bmp|
65
60
  check_image(bmp, 'iexplore')
66
61
  hwnd = Win32::Screenshot::BitmapMaker.hwnd(title)
67
- dimensions = Win32::Screenshot::BitmapMaker.dimensions_for(hwnd)
68
- width.should == dimensions[2]
69
- height.should == dimensions[3]
62
+ [width, height].should == Win32::Screenshot::Util.dimensions_for(hwnd)
70
63
  end
71
64
  end
72
65
 
@@ -76,9 +69,7 @@ describe "win32-screenshot" do
76
69
  Win32::Screenshot.window(title) do |width, height, bmp|
77
70
  check_image(bmp, 'calc')
78
71
  hwnd = Win32::Screenshot::BitmapMaker.hwnd(title)
79
- dimensions = Win32::Screenshot::BitmapMaker.dimensions_for(hwnd)
80
- width.should == dimensions[2]
81
- height.should == dimensions[3]
72
+ [width, height].should == Win32::Screenshot::Util.dimensions_for(hwnd)
82
73
  end
83
74
  end
84
75
 
@@ -91,9 +82,7 @@ describe "win32-screenshot" do
91
82
  # screenshot doesn't include titlebar and the size
92
83
  # varies between different themes and Windows versions
93
84
  hwnd = Win32::Screenshot::BitmapMaker.hwnd(title)
94
- dimensions = Win32::Screenshot::BitmapMaker.dimensions_for(hwnd)
95
- width.should == dimensions[2]
96
- height.should == dimensions[3]
85
+ [width, height].should == Win32::Screenshot::Util.dimensions_for(hwnd)
97
86
  end
98
87
  end
99
88
 
@@ -109,11 +98,11 @@ describe "win32-screenshot" do
109
98
  it "captures whole window if window size is specified as coordinates" do
110
99
  title = /calculator/i
111
100
  hwnd = Win32::Screenshot::BitmapMaker.hwnd(title)
112
- dimensions = Win32::Screenshot::BitmapMaker.dimensions_for(hwnd)
113
- Win32::Screenshot.window_area(title, 0, 0, dimensions[2], dimensions[3]) do |width, height, bmp|
101
+ expected_width, expected_height = Win32::Screenshot::Util.dimensions_for(hwnd)
102
+ Win32::Screenshot.window_area(title, 0, 0, expected_width, expected_height) do |width, height, bmp|
114
103
  check_image(bmp, 'calc_area_full_window')
115
- width.should == dimensions[2]
116
- height.should == dimensions[3]
104
+ width.should == expected_width
105
+ height.should == expected_height
117
106
  end
118
107
  end
119
108
 
@@ -138,9 +127,9 @@ describe "win32-screenshot" do
138
127
  it "doesn't allow to capture area of the window with too big coordinates" do
139
128
  title = /calculator/i
140
129
  hwnd = Win32::Screenshot::BitmapMaker.hwnd(title)
141
- dimensions = Win32::Screenshot::BitmapMaker.dimensions_for(hwnd)
130
+ expected_width, expected_height = Win32::Screenshot::Util.dimensions_for(hwnd)
142
131
  lambda {Win32::Screenshot.window_area(title, 0, 0, 10, 1000) {|width, height, bmp| check_image('calc3')}}.
143
- should raise_exception("specified coordinates (0, 0, 10, 1000) are invalid - maximum are x2=#{dimensions[2]} and y2=#{dimensions[3]}!")
132
+ should raise_exception("specified coordinates (0, 0, 10, 1000) are invalid - maximum are x2=#{expected_width} and y2=#{expected_height}!")
144
133
  end
145
134
 
146
135
  it "captures by window with handle" do
@@ -148,9 +137,7 @@ describe "win32-screenshot" do
148
137
  hwnd = Win32::Screenshot::BitmapMaker.hwnd(title)
149
138
  Win32::Screenshot.hwnd(hwnd) do |width, height, bmp|
150
139
  check_image(bmp, 'calc_hwnd')
151
- dimensions = Win32::Screenshot::BitmapMaker.dimensions_for(hwnd)
152
- width.should == dimensions[2]
153
- height.should == dimensions[3]
140
+ [width, height].should == Win32::Screenshot::Util.dimensions_for(hwnd)
154
141
  end
155
142
  end
156
143
 
@@ -168,7 +155,7 @@ describe "win32-screenshot" do
168
155
  lambda {Win32::Screenshot.hwnd_area(hwnd, 0, 0, -1, 100) {|width, height, bmp| check_image('desktop2')}}.
169
156
  should raise_exception("specified coordinates (0, 0, -1, 100) are invalid - cannot be negative!")
170
157
  end
171
-
158
+
172
159
  it "captures based on coordinates" do
173
160
  hwnd = Win32::Screenshot::BitmapMaker.hwnd(/calculator/i)
174
161
  bmp1 = bmp2 = nil
@@ -177,15 +164,13 @@ describe "win32-screenshot" do
177
164
  bmp1.length.should == bmp2.length
178
165
  bmp1.should_not == bmp2
179
166
  end
180
-
181
- it "enumerates the available windows" do
182
- got = Win32::Screenshot::BitmapMaker.list_window_titles
183
- got.length.should be > 1
184
- got[0].should be_a String
185
- end
186
-
187
- it "allow for parentheses in window names" do
188
- Win32::Screenshot::BitmapMaker.hwnd("VLC (Direct")
167
+
168
+ it "allows window titles to include regular expressions' special characters" do
169
+ lambda {Win32::Screenshot::BitmapMaker.hwnd("Window title *^$?([.")}.should_not raise_exception
170
+ end
171
+
172
+ it "raises an 'no block given' Exception if no block was given" do
173
+ lambda {Win32::Screenshot.foreground}.should raise_exception(LocalJumpError)
189
174
  end
190
175
 
191
176
  after :all do
@@ -0,0 +1,38 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe Win32::Screenshot::Util do
4
+ include SpecHelper
5
+
6
+ before :all do
7
+ @calc = IO.popen("calc").pid
8
+ wait_for_calculator_to_open
9
+ @calc_hwnd = Win32::Screenshot::Util.window_hwnd("Calculator")
10
+ end
11
+
12
+ it ".all_windows enumerates all available windows" do
13
+ all_windows = Win32::Screenshot::Util.all_windows
14
+ all_windows.should_not be_empty
15
+ all_windows[0].should be_an(Array)
16
+ all_windows[0][0].should be_a(String)
17
+ all_windows[0][1].should be_a(Fixnum)
18
+
19
+ calculator = all_windows.find {|title, hwnd| title =~ /Calculator/}
20
+ calculator.should_not be_nil
21
+ calculator[0].should == "Calculator"
22
+ calculator[1].should == @calc_hwnd
23
+ end
24
+
25
+ it ".window_title returns title of a specified window's handle" do
26
+ Win32::Screenshot::Util.window_title(@calc_hwnd).should == "Calculator"
27
+ end
28
+
29
+ it ".dimensions_for window handle returns dimensions of the window in pixels" do
30
+ width, height = Win32::Screenshot::Util.dimensions_for(@calc_hwnd)
31
+ width.should be > 100
32
+ height.should be > 100
33
+ end
34
+
35
+ after :all do
36
+ Process.kill 9, @calc
37
+ end
38
+ end
@@ -0,0 +1,69 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{win32screenshot}
8
+ s.version = "0.0.6"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Jarmo Pertman", "Aslak Helles\303\270y"]
12
+ s.date = %q{2010-08-07}
13
+ s.description = %q{Capture Screenshots on Windows with Ruby}
14
+ s.email = ["jarmo.p@gmail.com", "aslak.hellesoy@gmail.com"]
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".gitignore",
22
+ "History.rdoc",
23
+ "LICENSE",
24
+ "README.rdoc",
25
+ "Rakefile",
26
+ "VERSION",
27
+ "lib/win32/screenshot.rb",
28
+ "lib/win32/screenshot/bitmap_maker.rb",
29
+ "lib/win32/util.rb",
30
+ "spec/spec.opts",
31
+ "spec/spec_helper.rb",
32
+ "spec/win32_screenshot_spec.rb",
33
+ "spec/win32_screenshot_util_spec.rb",
34
+ "win32screenshot.gemspec"
35
+ ]
36
+ s.homepage = %q{http://github.com/jarmo/win32screenshot}
37
+ s.rdoc_options = ["--main", "README.rdoc"]
38
+ s.require_paths = ["lib"]
39
+ s.rubygems_version = %q{1.3.6}
40
+ s.summary = %q{Capture Screenshots on Windows with Ruby}
41
+ s.test_files = [
42
+ "spec/spec_helper.rb",
43
+ "spec/win32_screenshot_spec.rb",
44
+ "spec/win32_screenshot_util_spec.rb"
45
+ ]
46
+
47
+ if s.respond_to? :specification_version then
48
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
49
+ s.specification_version = 3
50
+
51
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
52
+ s.add_runtime_dependency(%q<ffi>, [">= 0"])
53
+ s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
54
+ s.add_development_dependency(%q<os>, [">= 0"])
55
+ s.add_development_dependency(%q<rmagick>, [">= 0"])
56
+ else
57
+ s.add_dependency(%q<ffi>, [">= 0"])
58
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
59
+ s.add_dependency(%q<os>, [">= 0"])
60
+ s.add_dependency(%q<rmagick>, [">= 0"])
61
+ end
62
+ else
63
+ s.add_dependency(%q<ffi>, [">= 0"])
64
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
65
+ s.add_dependency(%q<os>, [">= 0"])
66
+ s.add_dependency(%q<rmagick>, [">= 0"])
67
+ end
68
+ end
69
+
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rdp-win32screenshot
3
3
  version: !ruby/object:Gem::Version
4
- hash: 83
5
4
  prerelease: false
6
5
  segments:
7
6
  - 0
8
7
  - 0
9
8
  - 6
10
- - 2
11
- version: 0.0.6.2
9
+ - 3
10
+ version: 0.0.6.3
12
11
  platform: ruby
13
12
  authors:
14
13
  - Jarmo Pertman
@@ -17,7 +16,7 @@ autorequire:
17
16
  bindir: bin
18
17
  cert_chain: []
19
18
 
20
- date: 2010-07-14 00:00:00 -06:00
19
+ date: 2010-08-16 00:00:00 -06:00
21
20
  default_executable:
22
21
  dependencies:
23
22
  - !ruby/object:Gem::Dependency
@@ -28,7 +27,6 @@ dependencies:
28
27
  requirements:
29
28
  - - ">="
30
29
  - !ruby/object:Gem::Version
31
- hash: 3
32
30
  segments:
33
31
  - 0
34
32
  version: "0"
@@ -42,7 +40,6 @@ dependencies:
42
40
  requirements:
43
41
  - - ">="
44
42
  - !ruby/object:Gem::Version
45
- hash: 13
46
43
  segments:
47
44
  - 1
48
45
  - 2
@@ -58,7 +55,6 @@ dependencies:
58
55
  requirements:
59
56
  - - ">="
60
57
  - !ruby/object:Gem::Version
61
- hash: 3
62
58
  segments:
63
59
  - 0
64
60
  version: "0"
@@ -72,7 +68,6 @@ dependencies:
72
68
  requirements:
73
69
  - - ">="
74
70
  - !ruby/object:Gem::Version
75
- hash: 3
76
71
  segments:
77
72
  - 0
78
73
  version: "0"
@@ -99,10 +94,12 @@ files:
99
94
  - VERSION
100
95
  - lib/win32/screenshot.rb
101
96
  - lib/win32/screenshot/bitmap_maker.rb
102
- - lib/win32screenshot.rb
97
+ - lib/win32/util.rb
103
98
  - spec/spec.opts
104
99
  - spec/spec_helper.rb
105
100
  - spec/win32_screenshot_spec.rb
101
+ - spec/win32_screenshot_util_spec.rb
102
+ - win32screenshot.gemspec
106
103
  has_rdoc: true
107
104
  homepage: http://github.com/jarmo/win32screenshot
108
105
  licenses: []
@@ -118,7 +115,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
118
115
  requirements:
119
116
  - - ">="
120
117
  - !ruby/object:Gem::Version
121
- hash: 3
122
118
  segments:
123
119
  - 0
124
120
  version: "0"
@@ -127,7 +123,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
127
123
  requirements:
128
124
  - - ">="
129
125
  - !ruby/object:Gem::Version
130
- hash: 3
131
126
  segments:
132
127
  - 0
133
128
  version: "0"
@@ -141,3 +136,4 @@ summary: Capture Screenshots on Windows with Ruby
141
136
  test_files:
142
137
  - spec/spec_helper.rb
143
138
  - spec/win32_screenshot_spec.rb
139
+ - spec/win32_screenshot_util_spec.rb
@@ -1,3 +0,0 @@
1
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), 'lib'))
2
- Kernel.warn %q(DEPRECATION: use "require 'win32/screenshot'" instead of "require 'win32screenshot'")
3
- require "win32/screenshot"