Class: Win32::Clipboard
- Inherits:
-
Object
- Object
- Win32::Clipboard
- Extended by:
- Windows::Functions, Windows::Structs
- Includes:
- Windows::Constants, Windows::Functions, Windows::Structs
- Defined in:
- lib/win32/clipboard.rb
Overview
The Clipboard class encapsulates functions that relate to the MS Windows clipboard.
Direct Known Subclasses
Constant Summary collapse
- VERSION =
The version of this library
'0.6.1'- TEXT =
Text
1- OEMTEXT =
7- UNICODETEXT =
13- DIB =
Images
8- BITMAP =
2- ENHMETAFILE =
Metafiles
14- HDROP =
Files
15
Constants included from Windows::Constants
Windows::Constants::CF_TEXT, Windows::Constants::GHND, Windows::Constants::GWL_USERDATA, Windows::Constants::GWL_WNDPROC, Windows::Constants::WM_CHANGECBCHAIN, Windows::Constants::WM_DRAWCLIPBOARD
Class Method Summary collapse
-
.data(format = TEXT) ⇒ Object
(also: get_data)
Returns the data currently in the clipboard.
-
.empty ⇒ Object
(also: clear)
Empties the contents of the clipboard.
-
.format_available?(format) ⇒ Boolean
Returns whether or not
format(an integer) is currently available. -
.format_name(format_num) ⇒ Object
Returns the corresponding name for the given
format_num, or nil if it does not exist. -
.formats ⇒ Object
Returns a hash of all the current formats, with the format number as the key and the format name as the value for that key.
-
.notify_change(&block) ⇒ Object
Sets up a notification loop that will call the provided block whenever there’s a change to the clipboard.
-
.num_formats ⇒ Object
Returns the number of different data formats currently on the clipboard.
-
.register_format(format) ⇒ Object
Registers the given
format(a String) as a clipboard format, which can then be used as a valid clipboard format. -
.set_data(clip_data, format = TEXT) ⇒ Object
Sets the clipboard contents to the data that you specify.
Class Method Details
.data(format = TEXT) ⇒ Object Also known as: get_data
Returns the data currently in the clipboard. If format is specified, it will attempt to retrieve the data in that format. The default is Clipboard::TEXT.
If there is no data in the clipboard, or data is available but the format doesn’t match the data, then an empty string is returned.
Examples:
# Get some plain text
Win32::Clipboard.data # => e.g. 'hello'
# Get a list of files copied from the Windows Explorer window
Win32::Clipboard.data(Clipboard::HDROP) # => ['foo.rb', 'bar.rb']
# Get a bitmap and write it to another file
File.open('bitmap_copy', 'wb'){ |fh|
fh.write Win32::Clipboard.data(Clipboard::DIB)
}
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/win32/clipboard.rb', line 91 def self.data(format = TEXT) begin open if IsClipboardFormatAvailable(format) handle = GetClipboardData(format) case format when UNICODETEXT size = GlobalSize(handle) ptr = GlobalLock(handle) clip_data = ptr.read_bytes(size).force_encoding('UTF-16LE').encode('UTF-8').strip when TEXT, OEMTEXT size = GlobalSize(handle) ptr = GlobalLock(handle) clip_data = ptr.read_bytes(size).strip unless clip_data.ascii_only? clip_data.force_encoding('BINARY') end when HDROP clip_data = get_file_list(handle) when ENHMETAFILE clip_data = (handle) when DIB, BITMAP clip_data = get_image_data(handle) else raise "format '#{format}' not supported" end else clip_data = '' end ensure close end clip_data end |
.empty ⇒ Object Also known as: clear
Empties the contents of the clipboard.
44 45 46 47 48 49 50 51 52 53 |
# File 'lib/win32/clipboard.rb', line 44 def self.empty begin open unless EmptyClipboard() raise SystemCallError.new('EmptyClipboard', FFI.errno) end ensure close end end |
.format_available?(format) ⇒ Boolean
Returns whether or not format (an integer) is currently available.
67 68 69 |
# File 'lib/win32/clipboard.rb', line 67 def self.format_available?(format) IsClipboardFormatAvailable(format) end |
.format_name(format_num) ⇒ Object
Returns the corresponding name for the given format_num, or nil if it does not exist. You cannot specify any of the predefined clipboard formats (or nil is returned), only registered formats.
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 |
# File 'lib/win32/clipboard.rb', line 215 def self.format_name(format_num) val = nil buf = FFI::MemoryPointer.new(:char, 80) begin open if GetClipboardFormatName(format_num, buf, buf.size) != 0 val = buf.read_string end ensure close end val end |
.formats ⇒ Object
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'lib/win32/clipboard.rb', line 192 def self.formats formats = {} format = 0 begin self.open while 0 != (format = EnumClipboardFormats(format)) buf = FFI::MemoryPointer.new(:char, 80) GetClipboardFormatName(format, buf, buf.size) string = buf.read_string formats[format] = string.empty? ? nil : string end ensure self.close end formats end |
.notify_change(&block) ⇒ Object
Sets up a notification loop that will call the provided block whenever there’s a change to the clipboard.
Example:
Win32::Clipboard.notify_change{
puts "There's been a change in the clipboard contents!"
}
– We skip the first notification because the very act of attaching the new window causes it to trigger once.
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 |
# File 'lib/win32/clipboard.rb', line 267 def self.notify_change(&block) name = 'ruby-clipboard-' + Time.now.to_s handle = CreateWindowEx(0, 'static', name, 0, 0, 0, 0, 0, 0, 0, 0, nil) @first_notify = true wnd_proc = FFI::Function.new(:uintptr_t, [:uintptr_t, :uint, :uintptr_t, :uintptr_t]) do |hwnd, umsg, wparam, lparam| case umsg when WM_DRAWCLIPBOARD yield unless @first_notify next_viewer = GetWindowLongPtr(hwnd, GWL_USERDATA) if next_viewer != 0 PostMessage(next_viewer, umsg, wparam, lparam) end rv = 0 when WM_CHANGECBCHAIN yield unless @first_notify next_viewer = lparam if next_viewer == wparam if next_viewer != 0 PostMessage(next_viewer, umsg, wparam, lparam) end rv = 0 else rv = DefWindowProc(hwnd, umsg, wparam, lparam) end @first_notify = false rv end if SetWindowLongPtr(handle, GWL_WNDPROC, wnd_proc.address) == 0 raise SystemCallError.new('SetWindowLongPtr', FFI.errno) end next_viewer = SetClipboardViewer(handle) if next_viewer.nil? raise SystemCallError.new('SetClipboardViewer', FFI.errno) end SetWindowLongPtr(handle, GWL_USERDATA, next_viewer) msg = FFI::MemoryPointer.new(:char, 100) while true while PeekMessage(msg, handle, 0, 0, 1) TranslateMessage(msg) DispatchMessage(msg) end sleep 0.1 end end |
.num_formats ⇒ Object
Returns the number of different data formats currently on the clipboard.
61 62 63 |
# File 'lib/win32/clipboard.rb', line 61 def self.num_formats CountClipboardFormats() || 0 end |
.register_format(format) ⇒ Object
Registers the given format (a String) as a clipboard format, which can then be used as a valid clipboard format. Returns the integer value of the registered format.
If a registered format with the specified name already exists, a new format is not registered and the return value identifies the existing format. This enables more than one application to copy and paste data using the same registered clipboard format. Note that the format name comparison is case-insensitive.
Registered clipboard formats are identified by values in the range 0xC000 through 0xFFFF.
245 246 247 248 249 250 251 252 253 |
# File 'lib/win32/clipboard.rb', line 245 def self.register_format(format) format_value = RegisterClipboardFormat(format) if format_value == 0 raise SystemCallError.new('RegisterClipboardFormat', FFI.errno) end format_value end |
.set_data(clip_data, format = TEXT) ⇒ Object
Sets the clipboard contents to the data that you specify. You may optionally specify a clipboard format. The default is Clipboard::TEXT.
Example:
# Put the string 'hello' on the clipboard
Win32::Clipboard.set_data('hello')
# Put the image test.bmp on the clipboard
f = File.open("test.bmp", "rb")
str = f.read
Clipboard.set_data(str, Win32::Clipboard::DIB)
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 |
# File 'lib/win32/clipboard.rb', line 148 def self.set_data(clip_data, format = TEXT) begin clear open # NULL terminate text or strip header of bitmap file case format when UNICODETEXT clip_data.encode!('UTF-16LE') clip_data << "\0".encode('UTF-16LE') buf = clip_data extra = 4 when TEXT, OEMTEXT clip_data << "\0" buf = clip_data extra = 4 when BITMAP, DIB buf = clip_data[14..clip_data.length] # sizeof(BITMAPFILEHEADER) = 14 extra = 0 end # Global Allocate a movable piece of memory. hmem = GlobalAlloc(GHND, buf.bytesize + extra) mptr = GlobalLock(hmem) mptr.write_bytes(buf, 0, buf.bytesize) # Set the new data if SetClipboardData(format, hmem) == 0 raise SystemCallError.new('SetClipboardData', FFI.errno) end ensure GlobalFree(hmem) close end end |