SAKAI Masahiro - MeadowUnicodeClipboard Diff

  • Added parts are displayed like this.
  • Deleted parts are displayed like this.

= MeadowでUnicodeをクリップボードとやり取りする

安直な方法で実現してみた。

以下のスクリプトをwclip.rbとして保存。

  #!c:/cygwin/usr/local/bin/ruby
  #######################################################################
  
  require 'dl'
  require 'dl/import'
  
  module W
    extend DL::Importable
  
    # winuser.h
    CF_UNICODETEXT = 13
    dlload "user32"
    extern "BOOL OpenClipboard(HWND)"
    extern "BOOL CloseClipboard()"
    extern "HANDLE GetClipboardData(UINT)"
    extern "HANDLE SetClipboardData(UINT,HANDLE)"
    extern "BOOL EmptyClipboard()"
  
    # winbase.h
    GHND = 66
    dlload "kernel32"
    extern "HANDLE GlobalAlloc(UINT, DWORD)"
    extern "void* GlobalLock(HANDLE)"
    extern "BOOL GlobalUnlock(HANDLE)"
    extern "DWORD GlobalSize(HANDLE)"
  end
  
  def global_lock(h)
    ptr = W.globalLock(h)
    begin
      yield ptr
    ensure
      W.globalUnlock(h)
    end
  end
  
  def open_clipboard
    sleep(0.1) while not W.openClipboard(0)
    begin
      yield
    ensure
      W.closeClipboard
    end
  end
  
  #######################################################################
  
  require 'optparse'
  opt = OptionParser.new
  
  output = false
  opt.on('-o'){ output = true }
  opt.parse!(ARGV)
  
  if output
    open_clipboard{
      h = W.getClipboardData(W::CF_UNICODETEXT)
      raise RuntimeError if h == 0
      global_lock(h){|ptr|
        ary = ptr[0, W.globalSize(h)].unpack("S*")
        ary[ary.index(0)..(ary.length-1)] = nil
        s = ary.pack("S*")
        STDOUT.write(s)
      }
    }
  else
    s = ARGF.read
    s.concat("\0\0")
  
    h = W.globalAlloc(W::GHND, s.length)
    global_lock(h){|ptr| ptr[0, s.length] = s }
  
    open_clipboard{
      W.emptyClipboard
      W.setClipboardData(W::CF_UNICODETEXT, h)
    }
  end

以下のelispを.emacsにでも書く。

  (setq wclip-program "c:/cygwin/bin/wclip.rb")
  
  (defun copy-unicode (beg end)
    (interactive "r")
    (let ((coding-system-for-write 'utf-16-le-no-signature-dos))
      (call-process-region beg end wclip-program nil 0 nil)))
  
  (defun yank-unicode ()
    (interactive)
    (let ((coding-system-for-read 'utf-16-le-no-signature-dos))
      (call-process wclip-program nil t nil "-o")))

== 参考

* ((<URL:http://www.ysnb.net/meadow/meadow-users-jp/1999/msg01171.html>))