红宝石与小提琴复制到剪贴板 [英] Ruby copy to clipboard with Fiddle
问题描述
我正在尝试使用Fiddle模块将字符串复制到剪贴板,但是此代码失败.
I am trying to copy a string to the clipboard with the Fiddle module,but this code fails.
require'fiddle';
user32 = Fiddle.dlopen 'USER32.dll';
$openClipboard = Fiddle::Function.new(user32['OpenClipboard'],[Fiddle::TYPE_INT],Fiddle::TYPE_INT);
$closeClipboard = Fiddle::Function.new(user32['CloseClipboard'],[],Fiddle::TYPE_INT);
$emptyClipboard = Fiddle::Function.new(user32['EmptyClipboard'],[],Fiddle::TYPE_INT);
$setClipboardData = Fiddle::Function.new(user32['SetClipboardData'],[Fiddle::TYPE_INT,Fiddle::TYPE_VOIDP],Fiddle::TYPE_VOIDP);
class Clipboard
def initialize
@closed = false;
puts "openClipboard : #{$openClipboard.call(0)}";
puts "emptyClipboard : #{$emptyClipboard.call}";
end
def data=(d)
return 'Cannot write to closed clipboard' if @closed;
puts "setClipboardData : #{$setClipboardData.call(1,d)}"; # 1 is CF_TEXT
end
def close
return 'Already closed' if @closed;
@closed = true;
puts "closeClipboard : #{$closeClipboard.call}";
end
end
c = Clipboard.new
puts 'going to write';
gets;
c.data = 'red'; # Should write 'red' to the clipboard
p 'after writing to the clipboard';
gets;
c.close;
p 'closed';
gets
但是#data =方法失败.(这只是尝试翻译 http://www.codeproject.com/Articles/2242/Using-the-Clipboard-Part-I-Transferring-Simple-Tex ).有没有在不使用外部gem/library的情况下如何做的想法?
But it's failing in the #data= method. (This is just an attempt to translate the code at http://www.codeproject.com/Articles/2242/Using-the-Clipboard-Part-I-Transferring-Simple-Tex). Any idea on how to do it without using an external gem/library?
推荐答案
由于Ruby 1.9.3不支持dlopen方法,因此无法为您提供帮助.在我的脚本库中,我找到了这个工作示例.在 https://github.com/janlelis/clipboard/下找到它blob/master/lib/clipboard/windows.rb
Can't help you with fiddle because Ruby 1.9.3 doesn't support the dlopen method. In my library of scripts I found this working example. Found it at https://github.com/janlelis/clipboard/blob/master/lib/clipboard/windows.rb
在我的gem列表中找不到open3,因此我认为它是标准库的一部分.无论如何,要与操作系统进行这种级别的交互,您都需要某种宝石(无论是否集成),小提琴也是一颗宝石.
Can't find open3 in my list of gems so I suppose it is part of the standard library. In any way, to interact at such level with the OS you will need some kind of gem, incorporated or not, fiddle is also a gem.
require 'open3'
module Clipboard; end
module Clipboard::Windows
extend self
CF_TEXT = 1
CF_UNICODETEXT = 13
GMEM_MOVEABLE = 2
# get ffi function handlers
begin
require 'ffi'
rescue LoadError
raise LoadError, 'Could not load the required ffi gem, install it with: gem install ffi'
end
module User32
extend FFI::Library
ffi_lib "user32"
ffi_convention :stdcall
attach_function :open, :OpenClipboard, [ :long ], :long
attach_function :close, :CloseClipboard, [ ], :long
attach_function :empty, :EmptyClipboard, [ ], :long
attach_function :get, :GetClipboardData, [ :long ], :long
attach_function :set, :SetClipboardData, [ :long, :long ], :long
end
module Kernel32
extend FFI::Library
ffi_lib 'kernel32'
ffi_convention :stdcall
attach_function :lock, :GlobalLock, [ :long ], :pointer
attach_function :unlock, :GlobalUnlock, [ :long ], :long
attach_function :size, :GlobalSize, [ :long ], :long
attach_function :alloc, :GlobalAlloc, [ :long, :long ], :long
end
# see http://www.codeproject.com/KB/clipboard/archerclipboard1.aspx
def paste(_ = nil)
ret = ""
if 0 != User32.open( 0 )
hclip = User32.get( CF_UNICODETEXT )
if hclip && 0 != hclip
pointer_to_data = Kernel32.lock( hclip )
data = ""
# Windows Unicode is ended by to null bytes, so get the whole string
size = Kernel32.size( hclip )
data << pointer_to_data.get_bytes( 0, size - 2 )
if RUBY_VERSION >= '1.9'
ret = data.force_encoding("UTF-16LE").encode(Encoding.default_external) # TODO catch bad encodings
else # 1.8: fallback to simple CP850 encoding
require 'iconv'
utf8 = Iconv.iconv( "UTF-8", "UTF-16LE", data)[0]
ret = Iconv.iconv( "CP850", "UTF-8", utf8)[0]
end
if data && 0 != data
Kernel32.unlock( hclip )
end
end
User32.close( )
end
ret || ""
end
def clear
if 0 != User32.open( 0 )
User32.empty( )
User32.close( )
end
paste
end
def copy(data_to_copy)
if ( RUBY_VERSION >= '1.9' ) && 0 != User32.open( 0 )
User32.empty( )
data = data_to_copy.encode("UTF-16LE") # TODO catch bad encodings
data << 0
handler = Kernel32.alloc( GMEM_MOVEABLE, data.bytesize )
pointer_to_data = Kernel32.lock( handler )
pointer_to_data.put_bytes( 0, data, 0, data.bytesize )
Kernel32.unlock( handler )
User32.set( CF_UNICODETEXT, handler )
User32.close( )
else # don't touch anything
Open3.popen3( 'clip' ){ |input,_,_| input << data_to_copy } # depends on clip (available by default since Vista)
end
paste
end
end
Clipboard::Windows.copy("test")
puts Clipboard::Windows.paste
如果您不介意安装gem,这是一个更简单的解决方案,可在Windows7 64位Ruby 1.9.3上运行.
If you don't mind to install a gem, here is a much simpler solution, works on windows7 64 bit, Ruby 1.9.3.
#gem install clipboard
require 'clipboard'
Clipboard.copy("This is a sentence that has been copied to your clipboard")
puts Clipboard.paste
这篇关于红宝石与小提琴复制到剪贴板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!