rdp-win32screenshot 0.0.6.2 → 0.0.6.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/History.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"