win32-captureie 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. data/History.txt +3 -0
  2. data/License.txt +20 -0
  3. data/Manifest.txt +45 -0
  4. data/README.txt +49 -0
  5. data/Rakefile +4 -0
  6. data/TODO.txt +78 -0
  7. data/bin/prtie +62 -0
  8. data/config/hoe.rb +72 -0
  9. data/config/requirements.rb +17 -0
  10. data/lib/win32/capture_ie/base.rb +4 -0
  11. data/lib/win32/capture_ie/bitmap.rb +115 -0
  12. data/lib/win32/capture_ie/browser.rb +119 -0
  13. data/lib/win32/capture_ie/cli/base.rb +7 -0
  14. data/lib/win32/capture_ie/cli/prt_ie.rb +100 -0
  15. data/lib/win32/capture_ie/commands/base.rb +39 -0
  16. data/lib/win32/capture_ie/commands/prt_ie.rb +66 -0
  17. data/lib/win32/capture_ie/ffi/base.rb +22 -0
  18. data/lib/win32/capture_ie/ffi/gdi32.rb +165 -0
  19. data/lib/win32/capture_ie/ffi/struct.rb +246 -0
  20. data/lib/win32/capture_ie/ffi/user32.rb +101 -0
  21. data/lib/win32/capture_ie/ffi.rb +3 -0
  22. data/lib/win32/capture_ie/screen_captor.rb +131 -0
  23. data/lib/win32/capture_ie/version.rb +11 -0
  24. data/lib/win32/capture_ie/window.rb +47 -0
  25. data/lib/win32/capture_ie.rb +92 -0
  26. data/script/destroy +14 -0
  27. data/script/destroy.cmd +1 -0
  28. data/script/generate +14 -0
  29. data/script/generate.cmd +1 -0
  30. data/script/rdoc_filter.rb +75 -0
  31. data/script/txt2html +74 -0
  32. data/script/txt2html.cmd +1 -0
  33. data/setup.rb +1585 -0
  34. data/spec/spec.opts +1 -0
  35. data/spec/spec_helper.rb +7 -0
  36. data/spec/win32/capture_ie_spec.rb +11 -0
  37. data/tasks/deployment.rake +34 -0
  38. data/tasks/deployment2.rake +90 -0
  39. data/tasks/environment.rake +7 -0
  40. data/tasks/helper/rake.rb +58 -0
  41. data/tasks/helper/rake_sh_filter.rb +23 -0
  42. data/tasks/helper/util.rb +19 -0
  43. data/tasks/helper.rb +3 -0
  44. data/tasks/rspec.rake +21 -0
  45. data/tasks/website.rake +17 -0
  46. metadata +95 -0
data/History.txt ADDED
@@ -0,0 +1,3 @@
1
+ == 0.1.0 / 2007-11-23
2
+
3
+ * Initial release
data/License.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2007 MIYAMUKO Katsuyuki.
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Manifest.txt ADDED
@@ -0,0 +1,45 @@
1
+ History.txt
2
+ License.txt
3
+ Manifest.txt
4
+ README.txt
5
+ Rakefile
6
+ TODO.txt
7
+ bin/prtie
8
+ config/hoe.rb
9
+ config/requirements.rb
10
+ lib/win32/capture_ie.rb
11
+ lib/win32/capture_ie/base.rb
12
+ lib/win32/capture_ie/bitmap.rb
13
+ lib/win32/capture_ie/browser.rb
14
+ lib/win32/capture_ie/cli/base.rb
15
+ lib/win32/capture_ie/cli/prt_ie.rb
16
+ lib/win32/capture_ie/commands/base.rb
17
+ lib/win32/capture_ie/commands/prt_ie.rb
18
+ lib/win32/capture_ie/ffi.rb
19
+ lib/win32/capture_ie/ffi/base.rb
20
+ lib/win32/capture_ie/ffi/gdi32.rb
21
+ lib/win32/capture_ie/ffi/struct.rb
22
+ lib/win32/capture_ie/ffi/user32.rb
23
+ lib/win32/capture_ie/screen_captor.rb
24
+ lib/win32/capture_ie/version.rb
25
+ lib/win32/capture_ie/window.rb
26
+ script/destroy
27
+ script/destroy.cmd
28
+ script/generate
29
+ script/generate.cmd
30
+ script/rdoc_filter.rb
31
+ script/txt2html
32
+ script/txt2html.cmd
33
+ setup.rb
34
+ spec/spec.opts
35
+ spec/spec_helper.rb
36
+ spec/win32/capture_ie_spec.rb
37
+ tasks/deployment.rake
38
+ tasks/deployment2.rake
39
+ tasks/environment.rake
40
+ tasks/helper.rb
41
+ tasks/helper/rake.rb
42
+ tasks/helper/rake_sh_filter.rb
43
+ tasks/helper/util.rb
44
+ tasks/rspec.rake
45
+ tasks/website.rake
data/README.txt ADDED
@@ -0,0 +1,49 @@
1
+ == Win32::CaptureIE - Capture whole web pages using Internet Explorer
2
+
3
+ === SYNOPSIS
4
+
5
+ require "rubygems"
6
+ require "win32/capture_ie"
7
+
8
+ Win32::CaptureIE.start("http://www.ruby-lang.org/") do |ie|
9
+ ie.capture_page("ruby-lang-whole-page.bmp")
10
+ ie.capture_browser("ruby-lang-browser.bmp")
11
+ ie.capture_browser("ruby-lang-onepage.bmp", :only_drawing_area => true)
12
+ end
13
+
14
+
15
+ === COMMAND
16
+
17
+ win32-captureie provies _prtie_ command.
18
+
19
+ For more details, please see {prtie}[link:files/bin/prtie.html] document.
20
+
21
+
22
+ === INSTALL
23
+
24
+ gem install win32-captureie
25
+
26
+
27
+ === ACKNOWLEDGMENTS
28
+
29
+ Thanks to P.Smejkal author for his Perl's <tt>Win32-CaptureIE</tt>,
30
+ from which I borrowed a lot of code and ideas.
31
+
32
+ * {Win32-CaptureIE}[http://search.cpan.org/~psme/Win32-CaptureIE/]
33
+ * {Win32-Screenshot}[http://search.cpan.org/~psme/Win32-Screenshot/]
34
+
35
+
36
+ === COPYRIGHT
37
+
38
+ Copyright (c) 2007 MIYAMUKO Katsuyuki.
39
+
40
+ win32-captureie is released under an MIT license.
41
+ See {License.txt}[link:files/License_txt.html] for full license.
42
+
43
+
44
+ === OTHER STUFF
45
+
46
+ Author:: MIYAMUKO Katsuyuki <mailto:miyamuko@gmail.com>
47
+ Home URL:: http://win32-captureie.rubyforge.org
48
+ Project URL:: http://rubyforge.org/projects/win32-captureie
49
+ Blog (Japanese):: {id:miyamuko}[http://d.hatena.ne.jp/miyamuko/]
data/Rakefile ADDED
@@ -0,0 +1,4 @@
1
+ require 'config/requirements'
2
+ require 'config/hoe' # setup Hoe + all gem configuration
3
+
4
+ Dir['tasks/**/*.rake'].sort.each { |rake| load rake }
data/TODO.txt ADDED
@@ -0,0 +1,78 @@
1
+ == TODO
2
+
3
+ === lib
4
+
5
+ * RMagick
6
+ * png, jpg, ...
7
+ * capture_element
8
+ * capture_page(1)
9
+ * filter, effect
10
+
11
+ === bin/capture-ie
12
+
13
+ * basic auth
14
+ * watir?
15
+
16
+ Usage: capture-ie [options ...] URL [ [options ...] URL ]...
17
+
18
+ -T, --type
19
+ -o, --output
20
+ --stdout
21
+ -N --worker=1
22
+ --page
23
+ --area
24
+ --geometry
25
+ -V, --version print version information and exit
26
+ -h, --help print this help and exit
27
+ -E, --element
28
+ --thumbnail
29
+ --filter
30
+ timestamp
31
+ sepia
32
+ monochrome
33
+ rotate
34
+ frame
35
+ pile
36
+ glid
37
+
38
+ --filename=digest/md5
39
+ --filename=time/unixepoch
40
+ --filename=time/iso8859-1
41
+ --filename=url/encode
42
+ --filename=url/hierarchy
43
+ --filename=%M-%T
44
+
45
+ --remove-query-string
46
+ --allow-same-filename
47
+ --before-visit=URL
48
+ --font-size
49
+ --encode
50
+
51
+ -t, --tries=NUMBER set number of retries to NUMBER (0 unlimits).
52
+ --retry-connrefused retry even if connection is refused.
53
+ -i, --input-file=FILE download URLs found in FILE.
54
+ -B, --base=URL prepends URL to relative links in -F -i file.
55
+ -nc, --no-clobber skip downloads that would download to
56
+ existing files.
57
+ -w, --wait=SECONDS wait SECONDS between retrievals.
58
+ --waitretry=SECONDS wait 1..SECONDS between retries of a retrieval.
59
+ --random-wait wait from 0...2*WAIT secs between retrievals.
60
+ --restrict-file-names=OS restrict chars in file names to ones OS allows.
61
+ --capture-if-match
62
+ --capture-unless-match
63
+ --capture-even-if-error
64
+ --no-cache
65
+ --max-filesize
66
+ --max-width
67
+ --max-height
68
+ --auto-pageize
69
+ --max-auto-pageize
70
+ --log
71
+ --fail-on-error
72
+
73
+ --width
74
+ --height
75
+ --capture-browser
76
+ --capture-browser-drawing-area
77
+ --capture-page=N
78
+ --capture-whole-page
data/bin/prtie ADDED
@@ -0,0 +1,62 @@
1
+ #!/usr/bin/ruby
2
+
3
+ #
4
+ # == NAME
5
+ #
6
+ # prtie - Print Internet Explorer to image file
7
+ #
8
+ #
9
+ # == SYNOPSIS
10
+ #
11
+ # Usage: prtie [options] URL
12
+ #
13
+ #
14
+ # == DESCRIPTION
15
+ #
16
+ # _prtie_ is a command line tool to capture whole web page as image
17
+ # using Internet Explorer rendering engine.
18
+ #
19
+ #
20
+ # == USAGE
21
+ #
22
+ # Usage: prtie [options] URL
23
+ #
24
+ # -w, --wait=SECONDS wait SECONDS between retrievals
25
+ # -d, --output-directory=DIRECTORY save capture to DIRECTORY/...
26
+ # -o, --output=FILE save capture to FILE
27
+ # -D, --output-digest=ALGORITHM use output filename as hex-encoded version
28
+ # of a given URL
29
+ # ALGORITHM: MD5, SHA1, SHA512 ...
30
+ #
31
+ # -v, --version print the version
32
+ # -h, --help print this message
33
+ #
34
+ # Default options:
35
+ # --output-digest=MD5
36
+ #
37
+
38
+ module Win32
39
+ module CaptureIE
40
+ class Launcher #:nodoc:
41
+
42
+ def self.testing?
43
+ ["../Manifest.txt", "../lib"].all?{|e|
44
+ File.exist?(File.join(File.dirname($0), e))
45
+ }
46
+ end
47
+
48
+ def self.add_lib_to_load_path
49
+ $LOAD_PATH << File.join(File.dirname(__FILE__), "../lib")
50
+ end
51
+
52
+ def self.launch
53
+ add_lib_to_load_path if testing?
54
+ require "win32/capture_ie/cli/prt_ie"
55
+ ::Win32::CaptureIE::CLI::PrtIE.start(ARGV)
56
+ end
57
+
58
+ end
59
+ end
60
+ end
61
+
62
+ Win32::CaptureIE::Launcher.launch
data/config/hoe.rb ADDED
@@ -0,0 +1,72 @@
1
+ require 'win32/capture_ie/version'
2
+
3
+ AUTHOR = "MIYAMUKO Katsuyuki" # can also be an array of Authors
4
+ EMAIL = "miyamuko@gmail.com"
5
+ DESCRIPTION = "Win32::CaptureIE - Capture web pages using Internet Explorer"
6
+ GEM_NAME = "win32-captureie" # what ppl will type to install your gem
7
+ RUBYFORGE_PROJECT = "win32-captureie" # The unix name for your project
8
+ HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
9
+ DOWNLOAD_PATH = "http://rubyforge.org/projects/#{RUBYFORGE_PROJECT}"
10
+ RDOC_DIR = "html"
11
+
12
+ @config_file = "~/.rubyforge/user-config.yml"
13
+ @config = nil
14
+ RUBYFORGE_USERNAME = "unknown"
15
+ def rubyforge_username
16
+ unless @config
17
+ begin
18
+ @config = YAML.load(File.read(File.expand_path(@config_file)))
19
+ rescue
20
+ puts <<-EOS
21
+ ERROR: No rubyforge config file found: #{@config_file}
22
+ Run 'rubyforge setup' to prepare your env for access to Rubyforge
23
+ - See http://newgem.rubyforge.org/rubyforge.html for more details
24
+ EOS
25
+ exit
26
+ end
27
+ end
28
+ RUBYFORGE_USERNAME.replace @config["username"]
29
+ end
30
+
31
+
32
+ REV = nil
33
+ # UNCOMMENT IF REQUIRED:
34
+ # REV = `svn info`.each {|line| if line =~ /^Revision:/ then k,v = line.split(': '); break v.chomp; else next; end} rescue nil
35
+ VERS = Win32::CaptureIE::VERSION::STRING + (REV ? ".#{REV}" : "")
36
+ RDOC_OPTS = ['--quiet', '--title', 'win32-captureie documentation',
37
+ "--opname", "index.html",
38
+ "--line-numbers",
39
+ "--main", "README",
40
+ "--inline-source"]
41
+
42
+ class Hoe
43
+ def extra_deps
44
+ @extra_deps.reject! { |x| Array(x).first == 'hoe' }
45
+ @extra_deps
46
+ end
47
+ end
48
+
49
+ # Generate all the Rake tasks
50
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
51
+ hoe = Hoe.new(GEM_NAME, VERS) do |p|
52
+ p.author = AUTHOR
53
+ p.description = DESCRIPTION
54
+ p.email = EMAIL
55
+ p.summary = DESCRIPTION
56
+ p.url = HOMEPATH
57
+ p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
58
+ p.test_globs = ["test/**/test_*.rb"]
59
+ p.clean_globs |= ['**/.*.sw?', '*.gem', '.config', '**/.DS_Store'] #An array of file patterns to delete on clean.
60
+
61
+ # == Optional
62
+ p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
63
+ #p.extra_deps = [] # An array of rubygem dependencies [name, version], e.g. [ ['active_support', '>= 1.3.1'] ]
64
+
65
+ #p.spec_extras = {} # A hash of extra values to set in the gemspec.
66
+
67
+ end
68
+
69
+ CHANGES = hoe.paragraphs_of('History.txt', 0..1).join("\n\n")
70
+ PATH = (RUBYFORGE_PROJECT == GEM_NAME) ? RUBYFORGE_PROJECT : "#{RUBYFORGE_PROJECT}/#{GEM_NAME}"
71
+ hoe.remote_rdoc_dir = File.join(PATH.gsub(/^#{RUBYFORGE_PROJECT}\/?/,''), 'rdoc')
72
+ hoe.rsync_args = '-av --delete --ignore-errors'
@@ -0,0 +1,17 @@
1
+ require 'fileutils'
2
+ include FileUtils
3
+
4
+ require 'rubygems'
5
+ %w[rake hoe newgem rubigen].each do |req_gem|
6
+ begin
7
+ require req_gem
8
+ rescue LoadError
9
+ puts "This Rakefile requires the '#{req_gem}' RubyGem."
10
+ puts "Installation: gem install #{req_gem} -y"
11
+ exit
12
+ end
13
+ end
14
+
15
+ $:.unshift(File.join(File.dirname(__FILE__), %w[.. lib]))
16
+
17
+ require 'win32/capture_ie'
@@ -0,0 +1,4 @@
1
+ module Win32
2
+ module CaptureIE
3
+ end
4
+ end
@@ -0,0 +1,115 @@
1
+ require "win32/capture_ie/base"
2
+ require "win32/capture_ie/ffi"
3
+
4
+ module Win32::CaptureIE
5
+
6
+ class BitMapSizeError < StandardError #:nodoc:
7
+ end
8
+
9
+ class BitMap #:nodoc:
10
+ include Win32::CaptureIE::FFI::GDI32
11
+
12
+ attr_reader :width, :height
13
+ def initialize(width, height)
14
+ @width = width
15
+ @height = height
16
+ @data = nil
17
+ end
18
+
19
+ def header_size
20
+ BITMAPINFOHEADER.packed_size + BITMAPFILEHEADER.packed_size
21
+ end
22
+
23
+ def data_size
24
+ width * height * 4
25
+ end
26
+
27
+ def data
28
+ @data ||= "\0" * data_size
29
+ end
30
+
31
+ def rows
32
+ (0..height).map{|i| data[i * width * 4, width * 4] }
33
+ end
34
+
35
+ def replace(bmp)
36
+ @width = bmp.width
37
+ @height = bmp.height
38
+ @data = bmp.data
39
+ end
40
+
41
+
42
+ def concat_bottom!(bmp)
43
+ if width.zero?
44
+ replace(bmp)
45
+ else
46
+ check_bitmap_size(:width, @width, bmp.width)
47
+ @data << bmp.data
48
+ @height += bmp.height
49
+ end
50
+ end
51
+ alias << concat_bottom!
52
+
53
+ def concat_right!(bmp)
54
+ if height.zero?
55
+ replace(bmp)
56
+ else
57
+ check_bitmap_size(:height, @height, bmp.height)
58
+ @data = rows.zip(bmp.rows).flatten.join
59
+ @width += bmp.width
60
+ end
61
+ end
62
+
63
+ def check_bitmap_size(key, expected, actual)
64
+ if expected != actual
65
+ raise BitMapSizeError, "wrong bitmap #{key}: expected #{expected}px, but was #{actual}px."
66
+ end
67
+ end
68
+ private :check_bitmap_size
69
+
70
+
71
+ def create_bitmapfileheader
72
+ header = BITMAPFILEHEADER.new
73
+ header.bfType = "BM".unpack("S")[0]
74
+ header.bfSize = header_size + data_size
75
+ header.bfOffBits = header_size
76
+ header
77
+ end
78
+ alias header create_bitmapfileheader
79
+
80
+ def create_bitmapinfo
81
+ info = BITMAPINFO.new
82
+ info.bmiHeader.biSize = BITMAPINFOHEADER.packed_size
83
+ info.bmiHeader.biWidth = width
84
+ info.bmiHeader.biHeight = -height # negative because we want top-down bitmap
85
+ info.bmiHeader.biPlanes = 1
86
+ info.bmiHeader.biBitCount = 32 # we want RGBQUAD data
87
+ info.bmiHeader.biCompression = BI_RGB
88
+ info
89
+ end
90
+ alias info create_bitmapinfo
91
+
92
+ def save(filename)
93
+ open(filename, "wb") do |w|
94
+ pack {|data|
95
+ w.write data
96
+ }
97
+ end
98
+ nil
99
+ end
100
+
101
+ def pack(&block)
102
+ v = [create_bitmapfileheader.pack, create_bitmapinfo.bmiHeader.pack, @data]
103
+ if block
104
+ v.each(&block)
105
+ else
106
+ v.join
107
+ end
108
+ end
109
+
110
+ def inspect
111
+ "#<%s:0x%x @width=%d @height=%d @data=...>" % [self.class, self.object_id << 1, @height, @width]
112
+ end
113
+
114
+ end
115
+ end
@@ -0,0 +1,119 @@
1
+ require "win32/capture_ie/base"
2
+ require "win32/capture_ie/ffi"
3
+ require "win32/capture_ie/window"
4
+ require "win32/capture_ie/screen_captor"
5
+
6
+ module Win32::CaptureIE
7
+ class Browser < Window
8
+ module ReadyState
9
+ UNINITIALIZED = 0
10
+ LOADING = 1
11
+ LOADED = 2
12
+ INTERACTIVE = 3
13
+ COMPLETE = 4
14
+ end
15
+
16
+ include Win32::CaptureIE::FFI::User32
17
+ include Win32::CaptureIE::Browser::ReadyState
18
+
19
+ EMBEDDING_IE_WINDOW_CLASS_NAME = "Internet Explorer_Server"
20
+
21
+ attr_reader :doc_hwnd, :browser
22
+
23
+ def initialize(toplevel_hwnd, doc_hwnd=nil, browser=nil, document=nil, window=nil)
24
+ super(toplevel_hwnd)
25
+ @doc_hwnd = doc_hwnd || toplevel_hwnd
26
+ @browser = browser
27
+ @document = document
28
+ @window = window
29
+ @body = nil
30
+ @embedding_ie_hwnd = nil
31
+ end
32
+
33
+ def document
34
+ @document ||= browser.document rescue nil if browser
35
+ end
36
+
37
+ def window
38
+ @window ||= document.parentWindow rescue nil if document
39
+ end
40
+
41
+ def body
42
+ @body ||= body0 if document
43
+ end
44
+
45
+ def body0
46
+ if compatible_mode?
47
+ document.body rescue nil
48
+ else
49
+ document.body.parentNode rescue nil
50
+ end
51
+ end
52
+ private :body0
53
+
54
+ def compatible_mode?
55
+ v = document.compatMode rescue nil
56
+ return (v.nil? or v == "BackCompat")
57
+ end
58
+
59
+ def load_error?
60
+ url = document.url rescue ""
61
+ [/\Ares:\/\//, /\bshdoclc\b/].all?{|re| re.match(url) }
62
+ end
63
+
64
+ def navigate(url, wait=true)
65
+ browser.Navigate(url)
66
+ wait_for_complete if wait
67
+ end
68
+
69
+ def wait_for_complete(interval=0.5)
70
+ sleep(interval) while browser.ReadyState != COMPLETE
71
+ end
72
+
73
+ def embedding_ie_hwnd
74
+ @embedding_ie_hwnd ||= find_embedding_ie_hwnd
75
+ end
76
+
77
+ def find_embedding_ie_hwnd #:nodoc:
78
+ find_child_window_by_classname(doc_hwnd, EMBEDDING_IE_WINDOW_CLASS_NAME)
79
+ end
80
+ private :find_embedding_ie_hwnd
81
+
82
+ def save_excursion
83
+ top, left = body.scrollTop, body.scrollLeft
84
+ begin
85
+ yield
86
+ ensure
87
+ body.scrollTop, body.scrollLeft = top, left
88
+ end
89
+ end
90
+
91
+ # call-seq:
92
+ # capture_browser(filename)
93
+ # capture_browser(filename, :only_drawing_area => true)
94
+ #
95
+ # capture IE window to +filename+.
96
+ def capture_browser(filename, opts=nil)
97
+ captor.capture_browser(opts).save(filename)
98
+ end
99
+
100
+ # capture whole web page to +filename+.
101
+ def capture_page(filename)
102
+ captor.capture_page.save(filename)
103
+ end
104
+
105
+ def captor
106
+ Win32::CaptureIE::ScreenCaptor.new(self)
107
+ end
108
+
109
+
110
+ def ==(other)
111
+ @doc_hwnd == other.doc_hwnd
112
+ end
113
+
114
+ def hash
115
+ @doc_hwnd.hash
116
+ end
117
+
118
+ end
119
+ end
@@ -0,0 +1,7 @@
1
+ module Win32
2
+ module CaptureIE
3
+ module CLI #:nodoc:
4
+ end
5
+ end
6
+ end
7
+