win32screenshot 0.0.8 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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