win32-clipboard 0.5.2 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,232 @@
1
+ # The Win32 module serves as a namespace only.
2
+ #
3
+ module Win32
4
+
5
+ # The HtmlClipboard class is a subclass of Clipboard that explicitly
6
+ # handles text in HTML format.
7
+ #
8
+ class HtmlClipboard < Clipboard
9
+
10
+ private
11
+
12
+ # Marker block output
13
+ #--
14
+ # Version: Version of the clipboard.
15
+ #
16
+ # StartHTML: bytecount from the beginning of the clipboard to the
17
+ # start of the context, or -1 if no context.
18
+ #
19
+ # EndHTML: bytecount from the beginning of the clipboard to the end
20
+ # of the context, or -1 if no context.
21
+ #
22
+ # StartFragment: bytecount from the beginning of the clipboard to
23
+ # the start of the fragment.
24
+ #
25
+ # EndFragment: bytecount from the beginning of the clipboard to the
26
+ # end of the fragment.
27
+ #
28
+ # StartSelection: bytecount from the beginning of the clipboard to
29
+ # the start of the selection.
30
+ #
31
+ # EndSelection: bytecount from the beginning of the clipboard to the
32
+ # end of the selection.
33
+ #
34
+ MARKER_BLOCK_OUTPUT =
35
+ "Version:1.0\r\n" \
36
+ "StartHTML:%09d\r\n" \
37
+ "EndHTML:%09d\r\n" \
38
+ "StartFragment:%09d\r\n" \
39
+ "EndFragment:%09d\r\n" \
40
+ "StartSelection:%09d\r\n" \
41
+ "EndSelection:%09d\r\n" \
42
+ "SourceURL:%s\r\n"
43
+
44
+ # Extended marker block
45
+ MARKER_BLOCK_EX =
46
+ 'Version:(\S+)\s+' \
47
+ 'StartHTML:(\d+)\s+' \
48
+ 'EndHTML:(\d+)\s+' \
49
+ 'StartFragment:(\d+)\s+' \
50
+ 'EndFragment:(\d+)\s+' \
51
+ 'StartSelection:(\d+)\s+' \
52
+ 'EndSelection:(\d+)\s+' \
53
+ 'SourceURL:(\S+)'
54
+
55
+ # Regular expression for extended marker block
56
+ MARKER_BLOCK_EX_RE = Regexp.new(MARKER_BLOCK_EX, Regexp::MULTILINE) # :nodoc:
57
+
58
+ # Standard marker block
59
+ MARKER_BLOCK =
60
+ 'Version:(\S+)\s+' \
61
+ 'StartHTML:(\d+)\s+' \
62
+ 'EndHTML:(\d+)\s+' \
63
+ 'StartFragment:(\d+)\s+' \
64
+ 'EndFragment:(\d+)\s+' \
65
+ 'SourceURL:(\S+)'
66
+
67
+ # Regular expression for the standard marker block
68
+ MARKER_BLOCK_RE = Regexp.new(MARKER_BLOCK, Regexp::MULTILINE)
69
+
70
+ # Default HTML body
71
+ DEFAULT_HTML_BODY =
72
+ "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\r\n" \
73
+ "<HTML><BODY><!--StartFragment-->%s<!--EndFragment--></BODY></HTML>"
74
+
75
+ public
76
+
77
+ # Clipboard format value
78
+ CF_HTML = RegisterClipboardFormat("HTML Format")
79
+
80
+ def initialize # :nodoc:
81
+ @html = nil
82
+ @fragment = nil
83
+ @selection = nil
84
+ @source = nil
85
+ @version = nil
86
+ end
87
+
88
+ # Returns a boolean indicating whether or not the clipboard contains
89
+ # data in HTML format.
90
+ #
91
+ def self.html_format?
92
+ format_available?(CF_HTML)
93
+ end
94
+
95
+ # This method is nearly identical to the Clipboard.data method, but
96
+ # it decodes the data to preserve the HTML formatting.
97
+ #
98
+ def self.data
99
+ begin
100
+ self.open
101
+ if IsClipboardFormatAvailable(CF_HTML)
102
+ handle = GetClipboardData(CF_HTML)
103
+ size = GlobalSize(handle)
104
+ ptr = FFI::Pointer.new(:char, handle)
105
+
106
+ clip_data = decode_data(ptr.read_bytes(size))
107
+ else
108
+ clip_data = ''
109
+ end
110
+ ensure
111
+ self.close
112
+ end
113
+ clip_data
114
+ end
115
+
116
+ # Returns the block marker information for the HTML, or an empty
117
+ # string if there is no clipboard data.
118
+ #
119
+ def self.data_details
120
+ clip_data = data
121
+ string = ""
122
+ unless clip_data.empty?
123
+ string << "prefix=>>>#{@prefix}<<<END"
124
+ string << "version=>>>#{@version}<<<END"
125
+ string << "selection=>>>#{@selection}<<<END"
126
+ string << "fragment=>>>#{@fragment}<<<END"
127
+ string << "html=>>>#{@html}<<<END"
128
+ string << "source=>>>#{@source}<<<END"
129
+ end
130
+ string
131
+ end
132
+
133
+ # Put a well-formed fragment of HTML on the clipboard.
134
+ #
135
+ # The +selection+, if provided, must be a literal string within a
136
+ # fragment.
137
+ #
138
+ # The +html+ value, if provided, must be a well formed HTML document
139
+ # that textually contains a fragment and its required markers.
140
+ #
141
+ # The +source+, if provided, should include a scheme (file, http, or
142
+ # https) plus a file name. The default is file:// + __FILE__.
143
+ #
144
+ def self.set_data(fragment, selection=nil, html=nil, source=nil)
145
+ selection ||= fragment
146
+ html ||= DEFAULT_HTML_BODY % fragment
147
+ source ||= 'file://' + __FILE__
148
+
149
+ fragment_start = html.index(fragment)
150
+ fragment_end = fragment_start + fragment.length
151
+ selection_start = html.index(selection)
152
+ selection_end = selection_start + selection.length
153
+
154
+ clip_data = encode_data(
155
+ html,
156
+ fragment_start,
157
+ fragment_end,
158
+ selection_start,
159
+ selection_end,
160
+ source
161
+ )
162
+
163
+ self.open
164
+ EmptyClipboard()
165
+
166
+ # Global Allocate a movable piece of memory.
167
+ hmem = GlobalAlloc(GHND, clip_data.length + 4)
168
+ mem = GlobalLock(hmem)
169
+ mem.write_bytes(clip_data, 0, clip_data.size)
170
+
171
+ clip_data2 = fragment.gsub(/<[^>]+?>/,'')
172
+ hmem2 = GlobalAlloc(GHND, clip_data2.length + 4)
173
+ mem2 = GlobalLock(hmem2)
174
+ mem2.write_bytes(clip_data2, 0, clip_data2.size)
175
+
176
+ # Set the new data
177
+ begin
178
+ if SetClipboardData(CF_HTML, hmem) == 0
179
+ raise SystemCallError.new('SetClipboardData', FFI.errno)
180
+ end
181
+
182
+ if SetClipboardData(CF_TEXT, hmem2) == 0
183
+ raise SystemCallError.new('SetClipboardData', FFI.errno)
184
+ end
185
+ ensure
186
+ GlobalFree(hmem)
187
+ GlobalFree(hmem2)
188
+ self.close
189
+ end
190
+ self
191
+ end
192
+
193
+ private
194
+
195
+ # Encode the data markers into the HTML data
196
+ def self.encode_data(html,frag_start,frag_end,select_start,select_end,src)
197
+ dummy_prefix = MARKER_BLOCK_OUTPUT % [0,0,0,0,0,0,src]
198
+ len_prefix = dummy_prefix.length
199
+ prefix = MARKER_BLOCK_OUTPUT % [len_prefix, html.length + len_prefix,
200
+ frag_start + len_prefix, frag_end + len_prefix,
201
+ select_start + len_prefix, select_end + len_prefix, src]
202
+ prefix + html
203
+ end
204
+
205
+ # Decode the given string to figure out the details of the HTML
206
+ # that's on the string.
207
+ #--
208
+ # Try the extended format first, which has an explicit selection.
209
+ # If that fails, try the version without a selection.
210
+ #
211
+ def self.decode_data(src)
212
+ if (matches = MARKER_BLOCK_EX_RE.match(src))
213
+ @prefix = matches[0]
214
+ @version = matches[1]
215
+ @html = src[matches[2].to_i ... matches[3].to_i]
216
+ @fragment = src[matches[4].to_i ... matches[5].to_i]
217
+ @selection = src[matches[6].to_i ... matches[7].to_i]
218
+ @source = matches[8]
219
+ elsif (matches = MARKER_BLOCK_RE.match(src))
220
+ @prefix = matches[0]
221
+ @version = matches[1]
222
+ @html = src[matches[2].to_i ... matches[3].to_i]
223
+ @fragment = src[matches[4].to_i ... matches[5].to_i]
224
+ @source = matches[6]
225
+ @selection = @fragment
226
+ else
227
+ raise 'failed to match block markers'
228
+ end
229
+ @fragment
230
+ end
231
+ end
232
+ end
@@ -0,0 +1,10 @@
1
+ module Windows
2
+ module Constants
3
+ GHND = 0x0042
4
+ WM_DRAWCLIPBOARD = 0x0308
5
+ WM_CHANGECBCHAIN = 0x030D
6
+ GWL_USERDATA = -21
7
+ GWL_WNDPROC = -4
8
+ CF_TEXT = 1
9
+ end
10
+ end
@@ -0,0 +1,56 @@
1
+ require 'ffi'
2
+
3
+ module Windows
4
+ module Functions
5
+ extend FFI::Library
6
+
7
+ typedef :uintptr_t, :hglobal
8
+ typedef :uintptr_t, :hwnd
9
+ typedef :uintptr_t, :handle
10
+ typedef :uintptr_t, :hmenu
11
+ typedef :uintptr_t, :hdrop
12
+ typedef :uintptr_t, :hinstance
13
+ typedef :ulong, :dword
14
+
15
+ callback :wnd_proc, [:hwnd, :uint, :long, :long], :long
16
+
17
+ ffi_lib :kernel32
18
+
19
+ attach_function :GlobalAlloc, [:uint, :size_t], :hglobal
20
+ attach_function :GlobalFree, [:hglobal], :hglobal
21
+ attach_function :GlobalLock, [:hglobal], :pointer
22
+ attach_function :GlobalSize, [:hglobal], :size_t
23
+ attach_function :GlobalUnlock, [:hglobal], :bool
24
+
25
+ ffi_lib :user32
26
+
27
+ attach_function :CloseClipboard, [], :bool
28
+ attach_function :CountClipboardFormats, [], :int
29
+ attach_function :CreateWindowEx, :CreateWindowExA, [:dword, :string, :string, :dword, :int, :int, :int, :int, :hwnd, :hmenu, :hinstance, :pointer], :hwnd
30
+ attach_function :DefWindowProc, :DefWindowProcA, [:hwnd, :uint, :uint, :uint], :long
31
+ attach_function :DispatchMessage, :DispatchMessageA, [:pointer], :uint
32
+ attach_function :EmptyClipboard, [], :bool
33
+ attach_function :EnumClipboardFormats, [:uint], :uint
34
+ attach_function :GetClipboardData, [:uint], :handle
35
+ attach_function :GetClipboardFormatName, :GetClipboardFormatNameA, [:uint, :pointer, :int], :int
36
+ attach_function :GetWindowLongPtr, :GetWindowLongPtrA, [:hwnd, :int], :long
37
+ attach_function :IsClipboardFormatAvailable, [:uint], :bool
38
+ attach_function :OpenClipboard, [:hwnd], :bool
39
+ attach_function :PeekMessage, :PeekMessageA, [:pointer, :hwnd, :uint, :uint, :uint], :bool
40
+ attach_function :PostMessage, :PostMessageA, [:hwnd, :uint, :uintptr_t, :uintptr_t], :bool
41
+ attach_function :RegisterClipboardFormat, :RegisterClipboardFormatA, [:string], :uint
42
+ attach_function :SetClipboardData, [:uint, :handle], :handle
43
+ attach_function :SetClipboardViewer, [:hwnd], :hwnd
44
+ attach_function :SetWindowLongPtr, :SetWindowLongPtrA, [:hwnd, :int, :uintptr_t], :long
45
+ attach_function :TranslateMessage, [:pointer], :bool
46
+
47
+ ffi_lib :shell32
48
+
49
+ attach_function :DragQueryFileA, [:hdrop, :uint, :pointer, :uint], :uint
50
+
51
+ ffi_lib :gdi32
52
+
53
+ attach_function :GetEnhMetaFileBits, [:handle, :uint, :pointer], :uint
54
+ end
55
+ end
56
+
@@ -0,0 +1,43 @@
1
+ require 'ffi'
2
+
3
+ module Windows
4
+ module Structs
5
+ extend FFI::Library
6
+
7
+ typedef :uchar, :byte
8
+ typedef :ulong, :dword
9
+ typedef :ushort, :word
10
+
11
+ class RGBQUAD < FFI::Struct
12
+ layout(
13
+ :rgbBlue, :byte,
14
+ :rgbGreen, :byte,
15
+ :rgbRed, :byte,
16
+ :rgbReserved, :byte,
17
+ )
18
+ end
19
+
20
+ class BITMAPINFOHEADER < FFI::Struct
21
+ layout(
22
+ :biSize, :dword,
23
+ :biWidth, :long,
24
+ :biHeight, :long,
25
+ :biPlanes, :word,
26
+ :biBitCount, :word,
27
+ :biCompression, :dword,
28
+ :biSizeImage, :dword,
29
+ :biXPelsPerMeter, :long,
30
+ :biYPelsPerMeter, :long,
31
+ :biClrUsed, :dword,
32
+ :biClrImportant, :dword
33
+ )
34
+ end
35
+
36
+ class BITMAPINFO < FFI::Struct
37
+ layout(
38
+ :bmiHeader, BITMAPINFOHEADER,
39
+ :bmiColor, [RGBQUAD, 1]
40
+ )
41
+ end
42
+ end
43
+ end
@@ -1,135 +1,155 @@
1
- ###########################################################################
2
- # test_clipboard.rb
3
- #
4
- # Test suite for the win32-clipboard library. This will copy and remove
5
- # data from your clipboard. If your current clipboard data is crucial to
6
- # you, please save it first.
7
- #
8
- # You should run this test case via the 'rake test' task.
9
- ###########################################################################
10
- require 'rubygems'
11
- gem 'test-unit'
12
-
13
- require 'win32/clipboard'
14
- require 'test/unit'
15
- include Win32
16
-
17
- class TC_Win32_ClipBoard < Test::Unit::TestCase
18
- def test_version
19
- assert_equal('0.5.2', Clipboard::VERSION)
20
- end
21
-
22
- def test_data
23
- assert_respond_to(Clipboard, :data)
24
- assert_nothing_raised{ Clipboard.data }
25
- assert_kind_of(String, Clipboard.data)
26
- end
27
-
28
- def test_data_expected_errors
29
- assert_raise(TypeError){ Clipboard.data('test') }
30
- assert_raise(NameError){ Clipboard.data(CF_FOO) }
31
- end
32
-
33
- def test_get_data_alias
34
- assert_respond_to(Clipboard, :get_data)
35
- assert_true(Clipboard.method(:data) == Clipboard.method(:get_data))
36
- end
37
-
38
- def test_set_data
39
- assert_respond_to(Clipboard, :set_data)
40
- assert_nothing_raised{ Clipboard.set_data("foo") }
41
- end
42
-
43
- def test_set_data_unicode
44
- assert_nothing_raised{
45
- Clipboard.set_data('Ηελλας', Clipboard::UNICODETEXT)
46
- }
47
- end
48
-
49
- def test_set_data_expected_errors
50
- assert_raise(ArgumentError){ Clipboard.set_data }
51
- assert_raise(NameError){ Clipboard.set_data('foo', CF_FOO) }
52
- end
53
-
54
- def test_set_and_get_ascii
55
- assert_nothing_raised{ Clipboard.set_data('foobar') }
56
- assert_equal('foobar', Clipboard.data)
57
- end
58
-
59
- def test_set_and_get_unicode
60
- assert_nothing_raised{
61
- Clipboard.set_data('Ηελλας', Clipboard::UNICODETEXT)
62
- }
63
- assert_equal('Ηελλας', Clipboard.data(Clipboard::UNICODETEXT))
64
- end
65
-
66
- def test_empty
67
- assert_respond_to(Clipboard, :empty)
68
- assert_nothing_raised{ Clipboard.empty }
69
- end
70
-
71
- def test_clear_alias
72
- assert_respond_to(Clipboard, :clear)
73
- assert_true(Clipboard.method(:clear) == Clipboard.method(:empty))
74
- end
75
-
76
- def test_num_formats
77
- assert_respond_to(Clipboard, :num_formats)
78
- assert_nothing_raised{ Clipboard.num_formats }
79
- assert_kind_of(Fixnum, Clipboard.num_formats)
80
- end
81
-
82
- def test_num_formats_expected_errors
83
- assert_raise(ArgumentError){ Clipboard.num_formats(true) }
84
- end
85
-
86
- def test_register_format
87
- assert_respond_to(Clipboard, :register_format)
88
- assert_nothing_raised{ Clipboard.register_format('Ruby') }
89
- assert_kind_of(Integer, Clipboard.register_format('Ruby'))
90
- end
91
-
92
- def test_register_format_expected_errors
93
- assert_raises(TypeError){ Clipboard.register_format(1) }
94
- end
95
-
96
- def test_formats
97
- assert_respond_to(Clipboard, :formats)
98
- assert_nothing_raised{ Clipboard.formats }
99
- assert_kind_of(Hash, Clipboard.formats)
100
- end
101
-
102
- def test_formats_expected_errors
103
- assert_raise(ArgumentError){ Clipboard.formats(true) }
104
- end
105
-
106
- def test_format_available
107
- assert_respond_to(Clipboard, :format_available?)
108
- assert_nothing_raised{ Clipboard.format_available?(1) }
109
- assert_boolean(Clipboard.format_available?(1))
110
- end
111
-
112
- def test_format_name
113
- assert_respond_to(Clipboard, :format_name)
114
- assert_nothing_raised{ Clipboard.format_name(1) }
115
- assert_nil(Clipboard.format_name(9999999))
116
- end
117
-
118
- def test_format_name_expected_errors
119
- assert_raise(TypeError){ Clipboard.format_name('foo') }
120
- end
121
-
122
- def test_notify_change
123
- assert_respond_to(Clipboard, :notify_change)
124
- end
125
-
126
- def test_constants
127
- assert_not_nil(Clipboard::TEXT)
128
- assert_not_nil(Clipboard::OEMTEXT)
129
- assert_not_nil(Clipboard::UNICODETEXT)
130
- assert_not_nil(Clipboard::BITMAP)
131
- assert_not_nil(Clipboard::DIB)
132
- assert_not_nil(Clipboard::HDROP)
133
- assert_not_nil(Clipboard::ENHMETAFILE)
134
- end
135
- end
1
+ # encoding: utf-8
2
+ ###########################################################################
3
+ # test_clipboard.rb
4
+ #
5
+ # Test suite for the win32-clipboard library. This will copy and remove
6
+ # data from your clipboard. If your current clipboard data is crucial to
7
+ # you, please save it first.
8
+ #
9
+ # You should run this test case via the 'rake test' task.
10
+ ###########################################################################
11
+ require 'test-unit'
12
+ require 'win32/clipboard'
13
+ include Win32
14
+
15
+ class TC_Win32_ClipBoard < Test::Unit::TestCase
16
+ test "version is set to expected value" do
17
+ assert_equal('0.6.0', Clipboard::VERSION)
18
+ end
19
+
20
+ test "data method basic functionality" do
21
+ assert_respond_to(Clipboard, :data)
22
+ assert_nothing_raised{ Clipboard.data }
23
+ assert_kind_of(String, Clipboard.data)
24
+ end
25
+
26
+ test "data method requires proper format" do
27
+ assert_raise(TypeError){ Clipboard.data('test') }
28
+ assert_raise(NameError){ Clipboard.data(CF_FOO) }
29
+ end
30
+
31
+ test "get_data is an alias for data" do
32
+ assert_respond_to(Clipboard, :get_data)
33
+ assert_alias_method(Clipboard, :data, :get_data)
34
+ end
35
+
36
+ test "set_data basic functionality" do
37
+ assert_respond_to(Clipboard, :set_data)
38
+ assert_nothing_raised{ Clipboard.set_data('foo') }
39
+ end
40
+
41
+ test "set_data works with unicode text" do
42
+ assert_nothing_raised{
43
+ Clipboard.set_data('Ηελλας', Clipboard::UNICODETEXT)
44
+ }
45
+ end
46
+
47
+ test "set_data requires at least one argument" do
48
+ assert_raise(ArgumentError){ Clipboard.set_data }
49
+ end
50
+
51
+ test "set_data requires a valid data format" do
52
+ assert_raise(NameError){ Clipboard.set_data('foo', CF_FOO) }
53
+ end
54
+
55
+ test "set and get ascii data as expected" do
56
+ assert_nothing_raised{ Clipboard.set_data('foobar') }
57
+ assert_equal('foobar', Clipboard.data)
58
+ end
59
+
60
+ test "set and get unicode data as expected" do
61
+ assert_nothing_raised{
62
+ Clipboard.set_data('Ηελλας', Clipboard::UNICODETEXT)
63
+ }
64
+ assert_equal('Ηελλας', Clipboard.data(Clipboard::UNICODETEXT))
65
+ end
66
+
67
+ test "empty method basic functionality" do
68
+ assert_respond_to(Clipboard, :empty)
69
+ assert_nothing_raised{ Clipboard.empty }
70
+ end
71
+
72
+ test "clear is an alias for empty" do
73
+ assert_respond_to(Clipboard, :clear)
74
+ assert_alias_method(Clipboard, :clear, :empty)
75
+ end
76
+
77
+ test "num_formats basic functionality" do
78
+ assert_respond_to(Clipboard, :num_formats)
79
+ assert_nothing_raised{ Clipboard.num_formats }
80
+ assert_kind_of(Fixnum, Clipboard.num_formats)
81
+ end
82
+
83
+ test "num_formats returns an expected value" do
84
+ assert_true(Clipboard.num_formats >= 0)
85
+ assert_true(Clipboard.num_formats < 1000)
86
+ end
87
+
88
+ test "num_formats does not accept any arguments" do
89
+ assert_raise(ArgumentError){ Clipboard.num_formats(true) }
90
+ end
91
+
92
+ test "register_format basic functionality" do
93
+ assert_respond_to(Clipboard, :register_format)
94
+ assert_nothing_raised{ Clipboard.register_format('Ruby') }
95
+ assert_kind_of(Integer, Clipboard.register_format('Ruby'))
96
+ end
97
+
98
+ test "register_format requires a string argument" do
99
+ assert_raises(TypeError){ Clipboard.register_format(1) }
100
+ end
101
+
102
+ test "formats method basic functionality" do
103
+ assert_respond_to(Clipboard, :formats)
104
+ assert_nothing_raised{ Clipboard.formats }
105
+ assert_kind_of(Hash, Clipboard.formats)
106
+ end
107
+
108
+ # TODO: Why do these fail?
109
+ #test "formats result contains expected values" do
110
+ # assert_true(Clipboard.formats.size > 0)
111
+ # assert_true(Clipboard.formats.include?(1))
112
+ #end
113
+
114
+ test "formats method does not accept any arguments" do
115
+ assert_raise(ArgumentError){ Clipboard.formats(true) }
116
+ end
117
+
118
+ test "format_available basic functionality" do
119
+ assert_respond_to(Clipboard, :format_available?)
120
+ assert_nothing_raised{ Clipboard.format_available?(1) }
121
+ end
122
+
123
+ test "format_available returns a boolean value" do
124
+ assert_boolean(Clipboard.format_available?(1))
125
+ end
126
+
127
+ test "format_name basic functionality" do
128
+ assert_respond_to(Clipboard, :format_name)
129
+ assert_nothing_raised{ Clipboard.format_name(1) }
130
+ end
131
+
132
+ test "format_name returns expected value" do
133
+ format = Clipboard.register_format('HTML Format')
134
+ assert_equal('HTML Format', Clipboard.format_name(format))
135
+ assert_nil(Clipboard.format_name(9999999))
136
+ end
137
+
138
+ test "format_name requires a numeric argument" do
139
+ assert_raise(TypeError){ Clipboard.format_name('foo') }
140
+ end
141
+
142
+ test "notify_change basic functionality" do
143
+ assert_respond_to(Clipboard, :notify_change)
144
+ end
145
+
146
+ test "expected constants are defined" do
147
+ assert_not_nil(Clipboard::TEXT)
148
+ assert_not_nil(Clipboard::OEMTEXT)
149
+ assert_not_nil(Clipboard::UNICODETEXT)
150
+ assert_not_nil(Clipboard::BITMAP)
151
+ assert_not_nil(Clipboard::DIB)
152
+ assert_not_nil(Clipboard::HDROP)
153
+ assert_not_nil(Clipboard::ENHMETAFILE)
154
+ end
155
+ end