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 +11 -2
- data/README.rdoc +19 -0
- data/VERSION +1 -1
- data/lib/win32/screenshot/bitmap_maker.rb +147 -169
- data/lib/win32/screenshot.rb +7 -12
- data/lib/win32/util.rb +40 -0
- data/spec/spec_helper.rb +12 -3
- data/spec/win32_screenshot_spec.rb +24 -39
- data/spec/win32_screenshot_util_spec.rb +38 -0
- data/win32screenshot.gemspec +69 -0
- metadata +7 -11
- data/lib/win32screenshot.rb +0 -3
data/History.rdoc
CHANGED
@@ -1,6 +1,15 @@
|
|
1
|
-
= 0.0.6 2010-
|
1
|
+
= 0.0.6 2010-08-07
|
2
2
|
* Trying to bring window to the foreground more aggressively (Roger Pack)
|
3
|
-
*
|
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.
|
1
|
+
0.0.6.3
|
@@ -3,186 +3,164 @@ require 'ffi'
|
|
3
3
|
module Win32
|
4
4
|
class Screenshot
|
5
5
|
# internal methods
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
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
|
-
|
88
|
-
|
89
|
-
|
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
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
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
|
-
|
95
|
+
def prepare_window(hwnd, pause)
|
96
|
+
restore(hwnd) if minimized(hwnd)
|
97
|
+
set_foreground(hwnd)
|
98
|
+
sleep pause
|
99
|
+
end
|
119
100
|
|
120
|
-
|
121
|
-
show_window(hwnd, SW_RESTORE)
|
122
|
-
end
|
101
|
+
SW_RESTORE = 9
|
123
102
|
|
124
|
-
|
125
|
-
|
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
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
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
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
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
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
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
|
data/lib/win32/screenshot.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
require '
|
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
|
-
|
93
|
-
if x2 >
|
94
|
-
raise "specified coordinates (#{specified_coordinates}) are invalid - maximum are x2=#{
|
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
|
-
|
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
|
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
|
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 =
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
113
|
-
Win32::Screenshot.window_area(title, 0, 0,
|
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 ==
|
116
|
-
height.should ==
|
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
|
-
|
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=#{
|
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
|
-
|
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 "
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
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
|
-
-
|
11
|
-
version: 0.0.6.
|
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-
|
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/
|
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
|
data/lib/win32screenshot.rb
DELETED