win32screenshot 2.1.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.yardopts +2 -2
- data/CHANGES.md +185 -0
- data/Gemfile.lock +45 -39
- data/README.md +48 -0
- data/Rakefile +1 -0
- data/ext/{ImageMagick-6.9.3-0-portable-Q16-x86 → ImageMagick-7.0.9-8-portable-Q16-x86}/LICENSE.txt +103 -103
- data/ext/{ImageMagick-6.9.3-0-portable-Q16-x86 → ImageMagick-7.0.9-8-portable-Q16-x86}/convert.exe +0 -0
- data/ext/{ImageMagick-6.9.3-0-portable-Q16-x86/mogrify.exe → ImageMagick-7.0.9-8-portable-Q16-x86/identify.exe} +0 -0
- data/ext/{ImageMagick-6.9.3-0-portable-Q16-x86/identify.exe → ImageMagick-7.0.9-8-portable-Q16-x86/mogrify.exe} +0 -0
- data/lib/win32/screenshot/bitmap_maker.rb +121 -100
- data/lib/win32/screenshot/desktop.rb +5 -0
- data/lib/win32/screenshot/take.rb +79 -109
- data/lib/win32/screenshot/version.rb +5 -5
- data/lib/win32/screenshot.rb +12 -11
- data/spec/spec_helper.rb +47 -47
- data/spec/win32/screenshot/image_spec.rb +78 -78
- data/spec/win32/screenshot/take_spec.rb +83 -151
- data/win32screenshot.gemspec +25 -25
- metadata +18 -19
- data/History.rdoc +0 -113
- data/README.rdoc +0 -47
@@ -1,100 +1,121 @@
|
|
1
|
-
module Win32
|
2
|
-
module Screenshot
|
3
|
-
# @private
|
4
|
-
# This is an internal class for taking the actual screenshots and not part of a public API.
|
5
|
-
class BitmapMaker
|
6
|
-
class << self
|
7
|
-
extend FFI::Library
|
8
|
-
|
9
|
-
ffi_lib 'user32', 'gdi32'
|
10
|
-
ffi_convention :stdcall
|
11
|
-
|
12
|
-
# user32.dll
|
13
|
-
attach_function :window_dc, :GetWindowDC,
|
14
|
-
[:long], :long
|
15
|
-
attach_function :
|
16
|
-
[:long], :
|
17
|
-
attach_function :
|
18
|
-
[
|
19
|
-
attach_function :
|
20
|
-
[
|
21
|
-
attach_function :
|
22
|
-
[], :
|
23
|
-
attach_function :
|
24
|
-
[], :
|
25
|
-
|
26
|
-
# gdi32.dll
|
27
|
-
attach_function :create_compatible_dc, :CreateCompatibleDC,
|
28
|
-
[:long], :long
|
29
|
-
attach_function :create_compatible_bitmap, :CreateCompatibleBitmap,
|
30
|
-
[:long, :int, :int], :long
|
31
|
-
attach_function :select_object, :SelectObject,
|
32
|
-
[:long, :long], :long
|
33
|
-
attach_function :
|
34
|
-
[:long, :
|
35
|
-
attach_function :
|
36
|
-
[:long
|
37
|
-
attach_function :
|
38
|
-
[:long], :bool
|
39
|
-
attach_function :
|
40
|
-
[:long], :
|
41
|
-
attach_function :
|
42
|
-
[:long, :long], :
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
hmemDC
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
lpvpxldata.
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
end
|
1
|
+
module Win32
|
2
|
+
module Screenshot
|
3
|
+
# @private
|
4
|
+
# This is an internal class for taking the actual screenshots and not part of a public API.
|
5
|
+
class BitmapMaker
|
6
|
+
class << self
|
7
|
+
extend FFI::Library
|
8
|
+
|
9
|
+
ffi_lib 'user32', 'gdi32'
|
10
|
+
ffi_convention :stdcall
|
11
|
+
|
12
|
+
# user32.dll
|
13
|
+
attach_function :window_dc, :GetWindowDC,
|
14
|
+
[:long], :long
|
15
|
+
attach_function :window_rect, :GetWindowRect,
|
16
|
+
[:long, :pointer], :bool
|
17
|
+
attach_function :foreground_window, :GetForegroundWindow,
|
18
|
+
[], :long
|
19
|
+
attach_function :desktop_window, :GetDesktopWindow,
|
20
|
+
[], :long
|
21
|
+
attach_function :print_window, :PrintWindow,
|
22
|
+
[:long, :long, :int], :bool
|
23
|
+
attach_function :get_system_metrics, :GetSystemMetrics,
|
24
|
+
[:int], :int
|
25
|
+
|
26
|
+
# gdi32.dll
|
27
|
+
attach_function :create_compatible_dc, :CreateCompatibleDC,
|
28
|
+
[:long], :long
|
29
|
+
attach_function :create_compatible_bitmap, :CreateCompatibleBitmap,
|
30
|
+
[:long, :int, :int], :long
|
31
|
+
attach_function :select_object, :SelectObject,
|
32
|
+
[:long, :long], :long
|
33
|
+
attach_function :di_bits, :GetDIBits,
|
34
|
+
[:long, :long, :int, :int, :pointer, :pointer, :int], :int
|
35
|
+
attach_function :delete_object, :DeleteObject,
|
36
|
+
[:long], :bool
|
37
|
+
attach_function :delete_dc, :DeleteDC,
|
38
|
+
[:long], :bool
|
39
|
+
attach_function :release_dc, :ReleaseDC,
|
40
|
+
[:long, :long], :int
|
41
|
+
attach_function :bit_blt, :BitBlt,
|
42
|
+
[:long, :int, :int, :int, :int, :long, :int, :int, :long], :bool
|
43
|
+
|
44
|
+
DIB_RGB_COLORS = 0
|
45
|
+
PW_RENDERFULLCONTENT = 0x00000002
|
46
|
+
SRCCOPY = 0x00CC0020
|
47
|
+
|
48
|
+
SM_XVIRTUALSCREEN = 76
|
49
|
+
SM_YVIRTUALSCREEN = 77
|
50
|
+
SM_CXVIRTUALSCREEN = 78
|
51
|
+
SM_CYVIRTUALSCREEN = 79
|
52
|
+
|
53
|
+
def capture_window(hwnd)
|
54
|
+
width, height = dimensions_for(hwnd)
|
55
|
+
|
56
|
+
hScreenDC, hmemDC, hmemBM = prepare_object(hwnd, width, height)
|
57
|
+
print_window(hwnd, hmemDC, PW_RENDERFULLCONTENT)
|
58
|
+
create_bitmap(hScreenDC, hmemDC, hmemBM, width, height)
|
59
|
+
end
|
60
|
+
|
61
|
+
def capture_screen(hwnd)
|
62
|
+
left, top, width, height = desktop.dimensions
|
63
|
+
|
64
|
+
hScreenDC, hmemDC, hmemBM = prepare_object(hwnd, width, height)
|
65
|
+
bit_blt(hmemDC, 0, 0, width, height, hScreenDC, left, top, SRCCOPY)
|
66
|
+
create_bitmap(hScreenDC, hmemDC, hmemBM, width, height)
|
67
|
+
end
|
68
|
+
|
69
|
+
def prepare_object(hwnd, width, height)
|
70
|
+
hScreenDC = window_dc(hwnd)
|
71
|
+
hmemDC = create_compatible_dc(hScreenDC)
|
72
|
+
hmemBM = create_compatible_bitmap(hScreenDC, width, height)
|
73
|
+
select_object(hmemDC, hmemBM)
|
74
|
+
[hScreenDC, hmemDC, hmemBM]
|
75
|
+
end
|
76
|
+
|
77
|
+
def create_bitmap(hScreenDC, hmemDC, hmemBM, width, height)
|
78
|
+
bitmap_size = width * height * 3 + width % 4 * height
|
79
|
+
lpvpxldata = FFI::MemoryPointer.new(bitmap_size)
|
80
|
+
|
81
|
+
# Bitmap header
|
82
|
+
# http://www.fortunecity.com/skyscraper/windows/364/bmpffrmt.html
|
83
|
+
bmInfo = [40, width, height, 1, 24, 0, 0, 0, 0, 0, 0, 0].pack('L3S2L6')
|
84
|
+
di_bits(hmemDC, hmemBM, 0, height, lpvpxldata, bmInfo, DIB_RGB_COLORS)
|
85
|
+
|
86
|
+
bmFileHeader = [
|
87
|
+
19778,
|
88
|
+
bitmap_size + 40 + 14,
|
89
|
+
0,
|
90
|
+
0,
|
91
|
+
54
|
92
|
+
].pack('SLSSL')
|
93
|
+
|
94
|
+
Image.new(bmFileHeader + bmInfo + lpvpxldata.read_string(bitmap_size), width, height)
|
95
|
+
ensure
|
96
|
+
lpvpxldata.free
|
97
|
+
delete_object(hmemBM)
|
98
|
+
delete_dc(hmemDC)
|
99
|
+
release_dc(0, hScreenDC)
|
100
|
+
end
|
101
|
+
|
102
|
+
def desktop
|
103
|
+
Win32::Screenshot::Desktop.new(
|
104
|
+
get_system_metrics(SM_XVIRTUALSCREEN),
|
105
|
+
get_system_metrics(SM_YVIRTUALSCREEN),
|
106
|
+
get_system_metrics(SM_CXVIRTUALSCREEN),
|
107
|
+
get_system_metrics(SM_CYVIRTUALSCREEN)
|
108
|
+
)
|
109
|
+
end
|
110
|
+
|
111
|
+
def dimensions_for(hwnd)
|
112
|
+
rect = [0, 0, 0, 0].pack('l4')
|
113
|
+
window_rect(hwnd.to_i, rect)
|
114
|
+
left, top, width, height = rect.unpack('l4')
|
115
|
+
|
116
|
+
[width - left, height - top]
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -1,109 +1,79 @@
|
|
1
|
-
module Win32
|
2
|
-
module Screenshot
|
3
|
-
# Capture Screenshots on Windows with Ruby
|
4
|
-
class Take
|
5
|
-
|
6
|
-
class << self
|
7
|
-
# Takes a screenshot of the specified object
|
8
|
-
#
|
9
|
-
# @example Take a screenshot of the window with the specified title
|
10
|
-
# Win32::Screenshot::Take.of(:window, :title => "Windows Internet Explorer")
|
11
|
-
#
|
12
|
-
# @example Take a screenshot of the foreground
|
13
|
-
# Win32::Screenshot::Take.of(:foreground)
|
14
|
-
#
|
15
|
-
# @example Take a screenshot of the
|
16
|
-
# Win32::Screenshot::Take.of(:
|
17
|
-
#
|
18
|
-
# @example Take a screenshot of the window with the specified handle
|
19
|
-
# Win32::Screenshot::Take.of(:window, :hwnd => 123456)
|
20
|
-
#
|
21
|
-
# @example Take a screenshot of the window's client area (e.g. without title bar) with the specified handle
|
22
|
-
# Win32::Screenshot::Take.of(:window, :hwnd => 123456, :context => :client)
|
23
|
-
#
|
24
|
-
# @example Take a screenshot of the child window with the specified internal class name
|
25
|
-
# Win32::Screenshot::Take.of(:rautomation, RAutomation::Window.new(:hwnd => 123456).child(:class => "Internet Explorer_Server"))
|
26
|
-
#
|
27
|
-
# @param [Symbol] what the type of the object to take a screenshot of,
|
28
|
-
# possible values are _:foreground_, _:desktop_ and _:window_.
|
29
|
-
# @param [Hash] opts options are optional for specifying
|
30
|
-
# It is possible to specify as many options as are needed for searching for the unique window.
|
31
|
-
# By default the first window with matching identifiers will be taken screenshot of.
|
32
|
-
# It is possible to use in addition to other options a 0-based _:index_ option to search for other windows if multiple
|
33
|
-
# windows match the specified criteria.
|
34
|
-
# @option opts [String,
|
35
|
-
# @option opts [String, Regexp] :
|
36
|
-
# @option opts [String,
|
37
|
-
# @option opts [String,
|
38
|
-
# @option opts [String, Fixnum] :
|
39
|
-
#
|
40
|
-
# @option opts [
|
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
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
def take_screenshot(hwnd, opts)
|
82
|
-
if opts[:area]
|
83
|
-
validate_coordinates(hwnd, opts[:context], *opts[:area])
|
84
|
-
BitmapMaker.capture_area(hwnd, opts[:context], *opts[:area])
|
85
|
-
else
|
86
|
-
BitmapMaker.capture_all(hwnd, opts[:context])
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
def validate_coordinates(hwnd, context, x1, y1, x2, y2)
|
91
|
-
specified_coordinates = "x1: #{x1}, y1: #{y1}, x2: #{x2}, y2: #{y2}"
|
92
|
-
if [x1, y1, x2, y2].any? {|c| c < 0}
|
93
|
-
raise "specified coordinates (#{specified_coordinates}) are invalid - cannot be negative!"
|
94
|
-
end
|
95
|
-
|
96
|
-
if x1 >= x2 || y1 >= y2
|
97
|
-
raise "specified coordinates (#{specified_coordinates}) are invalid - cannot be x1 >= x2 or y1 >= y2!"
|
98
|
-
end
|
99
|
-
|
100
|
-
max_width, max_height = BitmapMaker.dimensions_for(hwnd, context)
|
101
|
-
if x2 > max_width || y2 > max_height
|
102
|
-
raise "specified coordinates (#{specified_coordinates}) are invalid - maximum x2: #{max_width} and y2: #{max_height}!"
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
end
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
1
|
+
module Win32
|
2
|
+
module Screenshot
|
3
|
+
# Capture Screenshots on Windows with Ruby
|
4
|
+
class Take
|
5
|
+
|
6
|
+
class << self
|
7
|
+
# Takes a screenshot of the specified object.
|
8
|
+
#
|
9
|
+
# @example Take a screenshot of the window with the specified title
|
10
|
+
# Win32::Screenshot::Take.of(:window, :title => "Windows Internet Explorer")
|
11
|
+
#
|
12
|
+
# @example Take a screenshot of the foreground
|
13
|
+
# Win32::Screenshot::Take.of(:foreground)
|
14
|
+
#
|
15
|
+
# @example Take a screenshot of the desktop
|
16
|
+
# Win32::Screenshot::Take.of(:desktop)
|
17
|
+
#
|
18
|
+
# @example Take a screenshot of the window with the specified handle
|
19
|
+
# Win32::Screenshot::Take.of(:window, :hwnd => 123456)
|
20
|
+
#
|
21
|
+
# @example Take a screenshot of the window's client area (e.g. without title bar) with the specified handle
|
22
|
+
# Win32::Screenshot::Take.of(:window, :hwnd => 123456, :context => :client)
|
23
|
+
#
|
24
|
+
# @example Take a screenshot of the child window with the specified internal class name
|
25
|
+
# Win32::Screenshot::Take.of(:rautomation, RAutomation::Window.new(:hwnd => 123456).child(:class => "Internet Explorer_Server"))
|
26
|
+
#
|
27
|
+
# @param [Symbol] what the type of the object to take a screenshot of,
|
28
|
+
# possible values are _:foreground_, _:desktop_ and _:window_.
|
29
|
+
# @param [Hash] opts options are optional for specifying _:context_ to take a screenshot.
|
30
|
+
# It is possible to specify as many options as are needed for searching for the unique window.
|
31
|
+
# By default the first window with matching identifiers will be taken screenshot of.
|
32
|
+
# It is possible to use in addition to other options a 0-based _:index_ option to search for other windows if multiple
|
33
|
+
# windows match the specified criteria.
|
34
|
+
# @option opts [String, Regexp] :title Title of the window
|
35
|
+
# @option opts [String, Regexp] :text Visible text of the window
|
36
|
+
# @option opts [String, Fixnum] :hwnd Window handle in decimal format
|
37
|
+
# @option opts [String, Fixnum] :pid Window process ID (PID)
|
38
|
+
# @option opts [String, Fixnum] :index 0-based index to specify n-th window to take a screenshot of if
|
39
|
+
# all other criteria match
|
40
|
+
# @option opts [RAutomation::Window] :rautomation RAutomation::Window object to take a screenshot of. Useful for
|
41
|
+
# taking screenshots of the child windows
|
42
|
+
# @return [Image] the {Image} of the specified object
|
43
|
+
def of(what, opts = {})
|
44
|
+
valid_whats = [:foreground, :desktop, :window]
|
45
|
+
raise "It is not possible to take a screenshot of '#{what}', possible values are #{valid_whats.join(", ")}" unless valid_whats.include?(what)
|
46
|
+
|
47
|
+
self.send(what, opts)
|
48
|
+
end
|
49
|
+
|
50
|
+
alias_method :new, :of
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def foreground(opts)
|
55
|
+
hwnd = BitmapMaker.foreground_window
|
56
|
+
BitmapMaker.capture_window(hwnd)
|
57
|
+
end
|
58
|
+
|
59
|
+
def desktop(opts)
|
60
|
+
hwnd = BitmapMaker.desktop_window
|
61
|
+
BitmapMaker.capture_screen(hwnd)
|
62
|
+
end
|
63
|
+
|
64
|
+
def window(opts)
|
65
|
+
win = opts[:rautomation] || RAutomation::Window.new(opts)
|
66
|
+
timeout = Time.now + 10
|
67
|
+
until win.active?
|
68
|
+
if Time.now >= timeout
|
69
|
+
Kernel.warn "[WARN] Failed to set window '#{win.locators.inspect}' into focus for taking the screenshot"
|
70
|
+
break
|
71
|
+
end
|
72
|
+
win.activate
|
73
|
+
end
|
74
|
+
BitmapMaker.capture_window(win.hwnd)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
|
-
module Win32
|
2
|
-
module Screenshot
|
3
|
-
VERSION = "
|
4
|
-
end
|
5
|
-
end
|
1
|
+
module Win32
|
2
|
+
module Screenshot
|
3
|
+
VERSION = "4.0.0"
|
4
|
+
end
|
5
|
+
end
|
data/lib/win32/screenshot.rb
CHANGED
@@ -1,11 +1,12 @@
|
|
1
|
-
require 'ffi'
|
2
|
-
require 'mini_magick'
|
3
|
-
require 'rautomation'
|
4
|
-
|
5
|
-
require File.dirname(__FILE__) + '/screenshot/version'
|
6
|
-
require File.dirname(__FILE__) + '/screenshot/take'
|
7
|
-
require File.dirname(__FILE__) + '/screenshot/image'
|
8
|
-
require File.dirname(__FILE__) + '/screenshot/bitmap_maker'
|
9
|
-
|
10
|
-
|
11
|
-
|
1
|
+
require 'ffi'
|
2
|
+
require 'mini_magick'
|
3
|
+
require 'rautomation'
|
4
|
+
|
5
|
+
require File.dirname(__FILE__) + '/screenshot/version'
|
6
|
+
require File.dirname(__FILE__) + '/screenshot/take'
|
7
|
+
require File.dirname(__FILE__) + '/screenshot/image'
|
8
|
+
require File.dirname(__FILE__) + '/screenshot/bitmap_maker'
|
9
|
+
require File.dirname(__FILE__) + '/screenshot/desktop'
|
10
|
+
|
11
|
+
# add bundled ImageMagick into path
|
12
|
+
ENV["PATH"] = "#{File.dirname(__FILE__) + "/../../ext/ImageMagick-7.0.9-8-portable-Q16-x86"};#{ENV["PATH"]}"
|
data/spec/spec_helper.rb
CHANGED
@@ -1,47 +1,47 @@
|
|
1
|
-
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
|
-
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
|
-
require 'win32/screenshot'
|
4
|
-
require 'rspec'
|
5
|
-
require 'fileutils'
|
6
|
-
|
7
|
-
module SpecHelper
|
8
|
-
HWND_TOPMOST = -1
|
9
|
-
HWND_NOTOPMOST = -2
|
10
|
-
SWP_NOSIZE = 1
|
11
|
-
SWP_NOMOVE = 2
|
12
|
-
SWP_SHOWWINDOW = 40
|
13
|
-
|
14
|
-
extend FFI::Library
|
15
|
-
ffi_lib 'user32'
|
16
|
-
ffi_convention :stdcall
|
17
|
-
|
18
|
-
# user32.dll
|
19
|
-
attach_function :set_window_pos, :SetWindowPos,
|
20
|
-
[:long, :long, :int, :int, :int, :int, :int], :bool
|
21
|
-
|
22
|
-
def save_and_verify_image(img, file=nil)
|
23
|
-
FileUtils.mkdir @temp_dir unless File.exists?(@temp_dir)
|
24
|
-
file_name = File.join @temp_dir, "#{file}.bmp"
|
25
|
-
img.write file_name
|
26
|
-
img.bitmap[0..1].
|
27
|
-
end
|
28
|
-
|
29
|
-
def resize title
|
30
|
-
hwnd = RAutomation::Window.new(:title => title).hwnd
|
31
|
-
set_window_pos(hwnd,
|
32
|
-
HWND_TOPMOST,
|
33
|
-
0, 0, 150, 238,
|
34
|
-
SWP_NOMOVE)
|
35
|
-
set_window_pos(hwnd,
|
36
|
-
HWND_NOTOPMOST,
|
37
|
-
0, 0, 0, 0,
|
38
|
-
SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE)
|
39
|
-
sleep 1
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
RSpec.configure do |config|
|
44
|
-
config.include(SpecHelper)
|
45
|
-
config.before(:suite) {FileUtils.rm Dir.glob(File.join(File.dirname(__FILE__), "tmp/*"))}
|
46
|
-
config.before(:all) {@temp_dir = File.join(File.dirname(__FILE__), 'tmp')}
|
47
|
-
end
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
|
+
require 'win32/screenshot'
|
4
|
+
require 'rspec'
|
5
|
+
require 'fileutils'
|
6
|
+
|
7
|
+
module SpecHelper
|
8
|
+
HWND_TOPMOST = -1
|
9
|
+
HWND_NOTOPMOST = -2
|
10
|
+
SWP_NOSIZE = 1
|
11
|
+
SWP_NOMOVE = 2
|
12
|
+
SWP_SHOWWINDOW = 40
|
13
|
+
|
14
|
+
extend FFI::Library
|
15
|
+
ffi_lib 'user32'
|
16
|
+
ffi_convention :stdcall
|
17
|
+
|
18
|
+
# user32.dll
|
19
|
+
attach_function :set_window_pos, :SetWindowPos,
|
20
|
+
[:long, :long, :int, :int, :int, :int, :int], :bool
|
21
|
+
|
22
|
+
def save_and_verify_image(img, file=nil)
|
23
|
+
FileUtils.mkdir @temp_dir unless File.exists?(@temp_dir)
|
24
|
+
file_name = File.join @temp_dir, "#{file}.bmp"
|
25
|
+
img.write file_name
|
26
|
+
expect(img.bitmap[0..1]).to eq('BM')
|
27
|
+
end
|
28
|
+
|
29
|
+
def resize title
|
30
|
+
hwnd = RAutomation::Window.new(:title => title).hwnd
|
31
|
+
set_window_pos(hwnd,
|
32
|
+
HWND_TOPMOST,
|
33
|
+
0, 0, 150, 238,
|
34
|
+
SWP_NOMOVE)
|
35
|
+
set_window_pos(hwnd,
|
36
|
+
HWND_NOTOPMOST,
|
37
|
+
0, 0, 0, 0,
|
38
|
+
SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE)
|
39
|
+
sleep 1
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
RSpec.configure do |config|
|
44
|
+
config.include(SpecHelper)
|
45
|
+
config.before(:suite) {FileUtils.rm Dir.glob(File.join(File.dirname(__FILE__), "tmp/*"))}
|
46
|
+
config.before(:all) {@temp_dir = File.join(File.dirname(__FILE__), 'tmp')}
|
47
|
+
end
|