win32screenshot 0.0.8 → 1.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.
data/lib/win32/util.rb DELETED
@@ -1,93 +0,0 @@
1
- module Win32
2
- class Screenshot
3
- class Util
4
- class << self
5
-
6
- def all_desktop_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
- # just returns a long list of hwnd's...
18
- # unless with_info is true
19
- # then it will return all hwnds with full info about each window
20
- def windows_hierarchy with_info = false
21
- all = {}
22
- desktop_hwnd = BitmapMaker.desktop_window
23
- root = {:hwnd => desktop_hwnd, :children => []}
24
- root.merge!(get_info(desktop_hwnd)) if with_info
25
- parents = []
26
- parents << root
27
- window_callback = FFI::Function.new(:bool, [ :long, :pointer ], { :convention => :stdcall }) do |hwnd, param|
28
- # this is a child of the most recent parent
29
- myself = {:hwnd => hwnd, :children => []}
30
- myself.merge!(get_info(hwnd)) if with_info
31
- parents[-1][:children] << myself
32
- parents << myself
33
- if !all[hwnd]
34
- all[hwnd] = true
35
- BitmapMaker.enum_child_windows(hwnd, window_callback, nil)
36
- end
37
-
38
- parents.pop
39
- true
40
- end
41
- BitmapMaker.enum_child_windows(desktop_hwnd, window_callback, nil)
42
- root
43
- end
44
-
45
- def get_info hwnd
46
- {:title => window_title(hwnd),
47
- :class => window_class(hwnd),
48
- :dimensions => dimensions_for(hwnd),
49
- :starting_coordinates => location_of(hwnd)
50
- }
51
- end
52
-
53
- def window_title hwnd
54
- title_length = BitmapMaker.window_text_length(hwnd) + 1
55
- title = FFI::MemoryPointer.new :char, title_length
56
- BitmapMaker.window_text(hwnd, title, title_length)
57
- title.read_string
58
- end
59
-
60
- def window_class hwnd
61
- title = FFI::MemoryPointer.new :char, 100
62
- BitmapMaker.class_name(hwnd, title, 99)
63
- title.read_string
64
- end
65
-
66
- def window_hwnd(title_query)
67
- hwnd = BitmapMaker.hwnd(title_query)
68
- raise "window with title '#{title_query}' was not found!" unless hwnd
69
- hwnd
70
- end
71
-
72
- def location_of(hwnd)
73
- rect = [0, 0, 0, 0].pack('L4')
74
- BitmapMaker.window_rect(hwnd, rect)
75
- x, y, width, height = rect.unpack('L4')
76
- return x, y
77
- end
78
-
79
- def dimensions_for(hwnd)
80
- rect = [0, 0, 0, 0].pack('L4')
81
- BitmapMaker.client_rect(hwnd, rect)
82
- _, _, width, height = rect.unpack('L4')
83
- return width, height
84
- end
85
-
86
- def window_process_id(hwnd)
87
- BitmapMaker.get_process_id_from_hwnd(hwnd)
88
- end
89
-
90
- end
91
- end
92
- end
93
- end
@@ -1,194 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
-
3
- describe Win32::Screenshot do
4
- include SpecHelper
5
-
6
- before :all do
7
- @notepad = IO.popen("notepad").pid
8
- @iexplore = Dir.chdir("c:/program files/Internet Explorer") do; IO.popen(".\\iexplore about:blank").pid; end
9
- @calc = IO.popen("calc").pid
10
- wait_for_programs_to_open
11
- cleanup
12
- end
13
-
14
- it "captures foreground" do
15
- Win32::Screenshot.foreground do |width, height, bmp|
16
- check_image(bmp, 'foreground')
17
- hwnd = Win32::Screenshot::BitmapMaker.foreground_window
18
- [width, height].should == Win32::Screenshot::Util.dimensions_for(hwnd)
19
- end
20
- end
21
-
22
- it "captures area of the foreground" do
23
- Win32::Screenshot.foreground_area(30, 30, 100, 150) do |width, height, bmp|
24
- check_image(bmp, 'foreground_area')
25
- width.should == 70
26
- height.should == 120
27
- end
28
- end
29
-
30
- it "doesn't allow to capture area of the foreground with invalid coordinates" do
31
- lambda {Win32::Screenshot.foreground_area(0, 0, -1, 100) {|width, height, bmp| check_image('foreground2')}}.
32
- should raise_exception("specified coordinates (0, 0, -1, 100) are invalid - cannot be negative!")
33
- end
34
-
35
- it "captures desktop" do
36
- Win32::Screenshot.desktop do |width, height, bmp|
37
- check_image(bmp, 'desktop')
38
- hwnd = Win32::Screenshot::BitmapMaker.desktop_window
39
- [width, height].should == Win32::Screenshot::Util.dimensions_for(hwnd)
40
- end
41
- end
42
-
43
- it "captures area of the desktop" do
44
- Win32::Screenshot.desktop_area(30, 30, 100, 150) do |width, height, bmp|
45
- check_image(bmp, 'desktop_area')
46
- width.should == 70
47
- height.should == 120
48
- end
49
- end
50
-
51
- it "doesn't allow to capture area of the desktop with invalid coordinates" do
52
- lambda {Win32::Screenshot.desktop_area(0, 0, -1, 100) {|width, height, bmp| check_image('desktop2')}}.
53
- should raise_exception("specified coordinates (0, 0, -1, 100) are invalid - cannot be negative!")
54
- end
55
-
56
- it "captures maximized window by window title" do
57
- title = "Internet Explorer"
58
- maximize(title)
59
- Win32::Screenshot.window(title) do |width, height, bmp|
60
- check_image(bmp, 'iexplore')
61
- hwnd = Win32::Screenshot::BitmapMaker.hwnd(title)
62
- [width, height].should == Win32::Screenshot::Util.dimensions_for(hwnd)
63
- end
64
- end
65
-
66
- it "captures minimized window by window title as a regexp" do
67
- title = /calculator/i
68
- minimize(title)
69
- Win32::Screenshot.window(title) do |width, height, bmp|
70
- check_image(bmp, 'calc')
71
- hwnd = Win32::Screenshot::BitmapMaker.hwnd(title)
72
- [width, height].should == Win32::Screenshot::Util.dimensions_for(hwnd)
73
- end
74
- end
75
-
76
- it "can also search by window class name" do
77
- good_pid = Win32::Screenshot::BitmapMaker.hwnd(/calculator/i)
78
- good_pid.should_not be_nil
79
- good_pid.should == Win32::Screenshot::BitmapMaker.hwnd(/calcframe/i, true)
80
- end
81
-
82
- it "can find sub windows as well" do
83
- # search for an IE sub-window by class (doesn't have text)
84
- Win32::Screenshot::BitmapMaker.hwnd(/CommandBarClass/i, true).should_not be_nil
85
- end
86
-
87
- it "captures small windows" do
88
- title = /Notepad/
89
- resize(title)
90
- Win32::Screenshot.window(title) do |width, height, bmp|
91
- check_image(bmp, 'notepad')
92
- # we should get the size of the picture because
93
- # screenshot doesn't include titlebar and the size
94
- # varies between different themes and Windows versions
95
- hwnd = Win32::Screenshot::BitmapMaker.hwnd(title)
96
- [width, height].should == Win32::Screenshot::Util.dimensions_for(hwnd)
97
- end
98
- end
99
-
100
- it "captures area of the window" do
101
- title = /calculator/i
102
- Win32::Screenshot.window_area(title, 30, 30, 100, 150) do |width, height, bmp|
103
- check_image(bmp, 'calc_area')
104
- width.should == 70
105
- height.should == 120
106
- end
107
- end
108
-
109
- it "captures whole window if window size is specified as coordinates" do
110
- title = /calculator/i
111
- hwnd = Win32::Screenshot::BitmapMaker.hwnd(title)
112
- expected_width, expected_height = Win32::Screenshot::Util.dimensions_for(hwnd)
113
- Win32::Screenshot.window_area(title, 0, 0, expected_width, expected_height) do |width, height, bmp|
114
- check_image(bmp, 'calc_area_full_window')
115
- width.should == expected_width
116
- height.should == expected_height
117
- end
118
- end
119
-
120
- it "doesn't allow to capture area of the window with negative coordinates" do
121
- title = /calculator/i
122
- lambda {Win32::Screenshot.window_area(title, 0, 0, -1, 100) {|width, height, bmp| check_image('calc2')}}.
123
- should raise_exception("specified coordinates (0, 0, -1, 100) are invalid - cannot be negative!")
124
- end
125
-
126
- it "doesn't allow to capture area of the window if coordinates are the same" do
127
- title = /calculator/i
128
- lambda {Win32::Screenshot.window_area(title, 10, 0, 10, 20) {|width, height, bmp| check_image('calc4')}}.
129
- should raise_exception("specified coordinates (10, 0, 10, 20) are invalid - cannot have x1 > x2 or y1 > y2!")
130
- end
131
-
132
- it "doesn't allow to capture area of the window if second coordinate is smaller than first one" do
133
- title = /calculator/i
134
- lambda {Win32::Screenshot.window_area(title, 0, 10, 10, 9) {|width, height, bmp| check_image('calc5')}}.
135
- should raise_exception("specified coordinates (0, 10, 10, 9) are invalid - cannot have x1 > x2 or y1 > y2!")
136
- end
137
-
138
- it "doesn't allow to capture area of the window with too big coordinates" do
139
- title = /calculator/i
140
- hwnd = Win32::Screenshot::BitmapMaker.hwnd(title)
141
- expected_width, expected_height = Win32::Screenshot::Util.dimensions_for(hwnd)
142
- 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=#{expected_width} and y2=#{expected_height}!")
144
- end
145
-
146
- it "captures by window with handle" do
147
- title = /calculator/i
148
- hwnd = Win32::Screenshot::BitmapMaker.hwnd(title)
149
- Win32::Screenshot.hwnd(hwnd) do |width, height, bmp|
150
- check_image(bmp, 'calc_hwnd')
151
- [width, height].should == Win32::Screenshot::Util.dimensions_for(hwnd)
152
- end
153
- end
154
-
155
- it "captures area of the window with handle" do
156
- hwnd = Win32::Screenshot::BitmapMaker.hwnd(/calculator/i)
157
- Win32::Screenshot.hwnd_area(hwnd, 30, 30, 100, 150) do |width, height, bmp|
158
- check_image(bmp, 'calc_hwnd_area')
159
- width.should == 70
160
- height.should == 120
161
- end
162
- end
163
-
164
- it "doesn't allow to capture area of the window with handle with invalid coordinates" do
165
- hwnd = Win32::Screenshot::BitmapMaker.hwnd(/calculator/i)
166
- lambda {Win32::Screenshot.hwnd_area(hwnd, 0, 0, -1, 100) {|width, height, bmp| check_image('desktop2')}}.
167
- should raise_exception("specified coordinates (0, 0, -1, 100) are invalid - cannot be negative!")
168
- end
169
-
170
- it "captures based on coordinates" do
171
- hwnd = Win32::Screenshot::BitmapMaker.hwnd(/calculator/i)
172
- bmp1 = bmp2 = nil
173
- Win32::Screenshot.hwnd_area(hwnd, 100, 100, 170, 180) do |width, height, bmp|; bmp1 = bmp; end
174
- Win32::Screenshot.hwnd_area(hwnd, 0, 0, 70, 80) do |width, height, bmp|; bmp2 = bmp; end
175
- bmp1.length.should == bmp2.length
176
- bmp1.should_not == bmp2
177
- end
178
-
179
- it "allows window titles to include regular expressions' special characters" do
180
- lambda {Win32::Screenshot::BitmapMaker.hwnd("Window title *^$?([.")}.should_not raise_exception
181
- end
182
-
183
- it "raises an 'no block given' Exception if no block was given" do
184
- lambda {Win32::Screenshot.foreground}.should raise_exception(LocalJumpError)
185
- end
186
-
187
- after :all do
188
- for name in [/calculator/i, /Notepad/, /Internet Explorer/] do
189
- # kill them in a jruby friendly way
190
- pid = Win32::Screenshot::Util.window_process_id(Win32::Screenshot::Util.window_hwnd(name))
191
- system("taskkill /PID #{pid}")
192
- end
193
- end
194
- end
@@ -1,75 +0,0 @@
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
- # should not have any running calculators yet...
8
- proc {Win32::Screenshot::Util.window_hwnd("Calculator") }.should raise_exception("window with title 'Calculator' was not found!")
9
- @calc = IO.popen("calc").pid
10
- wait_for_calculator_to_open
11
- @calc_hwnd = Win32::Screenshot::Util.window_hwnd("Calculator")
12
- end
13
-
14
- it ".all_desktop_windows enumerates all available windows" do
15
- all_windows = Win32::Screenshot::Util.all_desktop_windows
16
- all_windows.should_not be_empty
17
- all_windows[0].should be_an(Array)
18
- all_windows[0][0].should be_a(String)
19
- all_windows[0][1].should be_a(Fixnum)
20
-
21
- calculator = all_windows.find {|title, hwnd| title =~ /Calculator/}
22
- calculator.should_not be_nil
23
- calculator[0].should == "Calculator"
24
- calculator[1].should == @calc_hwnd
25
- end
26
-
27
- it ".window_title returns title of a specified window's handle" do
28
- Win32::Screenshot::Util.window_title(@calc_hwnd).should == "Calculator"
29
- end
30
-
31
- it ".dimensions_for window handle returns dimensions of the window in pixels" do
32
- width, height = Win32::Screenshot::Util.dimensions_for(@calc_hwnd)
33
- width.should be > 100
34
- height.should be > 100
35
- end
36
-
37
- it ".window_class returns classname of a specified window's handle" do
38
- Win32::Screenshot::Util.window_class(@calc_hwnd).should == "CalcFrame"
39
- end
40
-
41
- it ".get_info returns lots of info about an hwnd" do
42
- desktop_hwnd = Win32::Screenshot::BitmapMaker.desktop_window
43
- info = Win32::Screenshot::Util.get_info desktop_hwnd
44
- info.should be_a(Hash)
45
- info.keys.map {|k| k.to_s}.sort.should == ["class", "dimensions", "starting_coordinates", "title"]
46
- end
47
-
48
- it ".windows_hierarchy returns hwnds" do
49
- a = Win32::Screenshot::Util.windows_hierarchy
50
- # should have root as "desktop"
51
- # though in reality some windows might not be descendants of the desktop
52
- # (see the WinCheat source which discusses this further)
53
- # but we don't worry about that edge case yet
54
- a.should be_a(Hash)
55
- a[:children].should be_an(Array)
56
- a[:children].length.should be > 0
57
- a[:children][0].should be_a(Hash)
58
- a[:hwnd].should == Win32::Screenshot::BitmapMaker.desktop_window
59
- end
60
-
61
- it ".windows_hierarchy can return info" do
62
- a = Win32::Screenshot::Util.windows_hierarchy true
63
- # check for right structure
64
- for hash_example in [a, a[:children][0]] do
65
- hash_example.keys.map {|k| k.to_s}.sort.should == ["children", "class", "dimensions", "hwnd", "starting_coordinates", "title"]
66
- end
67
- end
68
-
69
- after :all do
70
- # tests our hwnd -> pid method, and conveniently, shuts down the calculator process
71
- calc_pid = Win32::Screenshot::Util.window_process_id(@calc_hwnd)
72
- system("taskkill /PID #{calc_pid}")
73
- proc {Win32::Screenshot::Util.window_hwnd("Calculator") }.should raise_exception("window with title 'Calculator' was not found!")
74
- end
75
- end