Class: Win32::Clipboard

Inherits:
Object
  • Object
show all
Extended by:
Windows::Clipboard, Windows::Error, Windows::GDI::MetaFile, Windows::Library, Windows::MSVCRT::Buffer, Windows::Memory, Windows::Shell, Windows::Window, Windows::Window::Classes, Windows::Window::Message
Includes:
Windows::Clipboard, Windows::Error, Windows::Memory
Defined in:
lib/win32/clipboard.rb

Overview

The Clipboard class encapsulates functions that relate to the MS Windows clipboard.

Defined Under Namespace

Classes: Error

Constant Summary collapse

VERSION =

The version of this library

'0.5.1'
TEXT =

Text

CF_TEXT
OEMTEXT =
CF_OEMTEXT
UNICODETEXT =
CF_UNICODETEXT
DIB =

Images

CF_DIB
BITMAP =
CF_BITMAP
ENHMETAFILE =

Metafiles

CF_ENHMETAFILE
HDROP =

Files

CF_HDROP

Class Method Summary collapse

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)
}


112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/win32/clipboard.rb', line 112

def self.data(format = TEXT)
   begin
      self.open
      if IsClipboardFormatAvailable(format)
         handle = GetClipboardData(format)
         case format
            when TEXT, OEMTEXT, UNICODETEXT
               clip_data = 0.chr * GlobalSize(handle)
               memcpy(clip_data, handle, clip_data.size)
               clip_data = clip_data[ /^[^\0]*/ ]
            when HDROP
               clip_data = get_file_list(handle)
            when ENHMETAFILE
               clip_data = get_metafile_data(handle)
            when DIB, BITMAP
               clip_data = get_image_data(handle)
            else
               raise Error, 'format not supported'
         end
      else
         clip_data = ''
      end
   ensure
      self.close
   end

   clip_data
end

.emptyObject Also known as: clear

Empties the contents of the clipboard.



143
144
145
146
147
148
149
150
151
152
# File 'lib/win32/clipboard.rb', line 143

def self.empty
   begin
      self.open
      EmptyClipboard()
   ensure
      self.close
   end

   self
end

.format_available?(format) ⇒ Boolean

Returns whether or not format (an int) is currently available.

Returns:

  • (Boolean)


179
180
181
# File 'lib/win32/clipboard.rb', line 179

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.



187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
# File 'lib/win32/clipboard.rb', line 187

def self.format_name(format_num)
   val = nil
   buf = 0.chr * 80

   begin
      self.open
      if GetClipboardFormatName(format_num, buf, buf.length) != 0
         val = buf
      end
   ensure
      self.close
   end

   val.split(0.chr).first rescue nil
end

.formatsObject

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.

Example:

Win32::Clipboard.formats # => {1 => nil, 49335 => "HTML Format"}


210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
# File 'lib/win32/clipboard.rb', line 210

def self.formats
   formats = {}
   format = 0
   
   begin
      self.open
      while 0 != (format = EnumClipboardFormats(format))
         buf = 0.chr * 80
         GetClipboardFormatName(format, buf, buf.length)
         formats[format] = buf.split(0.chr).first
      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.



266
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
# File 'lib/win32/clipboard.rb', line 266

def self.notify_change(&block)
   name   = 'ruby-clipboard-' + Time.now.to_s
   handle = CreateWindow('static', name, 0, 0, 0, 0, 0, 0, 0, 0, 0)
   
   @first_notify = true

   wnd_proc = Win32::API::Callback.new('LLLL', 'L') 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

   old_wnd_proc = SetWindowLongPtr(handle, GWL_WNDPROC, wnd_proc.address)
   next_viewer  = SetClipboardViewer(handle)

   SetWindowLongPtr(handle, GWL_USERDATA, next_viewer)

   msg = 0.chr * 100

   while true
      while PeekMessage(msg, handle, 0, 0, 1)
         TranslateMessage(msg)
         DispatchMessage(msg)
      end
      sleep 0.1
   end
end

.num_formatsObject

Returns the number of different data formats currently on the clipboard.



164
165
166
167
168
169
170
171
172
173
174
175
# File 'lib/win32/clipboard.rb', line 164

def self.num_formats
   count = 0

   begin
      self.open
      count = CountClipboardFormats()
   ensure
      self.close
   end

   count
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.

Raises:

  • (TypeError)


241
242
243
244
245
246
247
248
249
250
251
252
# File 'lib/win32/clipboard.rb', line 241

def self.register_format(format)
   raise TypeError unless format.is_a?(String)
   
   format_value = RegisterClipboardFormat(format)
   
   if format_value == 0
      error = "RegisterClipboardFormat() call failed: " + get_last_error
      raise Error, error
   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')


64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/win32/clipboard.rb', line 64

def self.set_data(clip_data, format = TEXT)
   self.open
   EmptyClipboard()

   # NULL terminate text
   case format
      when TEXT, OEMTEXT, UNICODETEXT				
         clip_data << "\0"
   end

   # Global Allocate a movable piece of memory.
   hmem = GlobalAlloc(GHND, clip_data.length + 4)
   mem  = GlobalLock(hmem)
   memcpy(mem, clip_data, clip_data.length)

   # Set the new data
   begin
      if SetClipboardData(format, hmem) == 0
         raise Error, "SetClipboardData() failed: " + get_last_error
      end
   ensure
      GlobalFree(hmem)
      self.close
   end

   self
end