红宝石与小提琴复制到剪贴板 [英] Ruby copy to clipboard with Fiddle

查看:73
本文介绍了红宝石与小提琴复制到剪贴板的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用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 =方法失败.(这只是尝试翻译

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆