HOME  >  スポンサー広告 >  Ruby >  Windows 上の Ruby でクリップボードを活用する方法 その1

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
--/--/-- | カテゴリ:スポンサー広告 | トラックバック(-) | コメント(-)

Windows 上の Ruby でクリップボードを活用する方法 その1

Ruby でクリップボードを使用する方法について。
2014/1/19 追記
2014/1/12 に win32-clipboard が更新(0.5.2->0.6.0)されて、
日本語も使えるようになっています。
ですので、この記事はもはや*無意味*です。
むむむ、なんというタイミングなんだろう……。(win32-clipboard の更新は約 4 年半ぶり)
バージョンアップした win32-clipboard の使用方法の記事も書きました。
Windows 上の Ruby でクリップボードを活用する方法 その2をご覧ください。
追記ここまで
# 今回、問題を応急処置的に対応します。
# なので、文字コードは Shift_JIS のみの対応とします。

対象:
  • Windows 上で Ruby 1.9 系以降
  • マルチバイト文字(とりあえず今回は Shift_JIS 限定)を使用している方向け
  • win32-clipboard version.0.5.2 <-2014/1/19 追記
win32-clipboard という gem を利用します。
gem install win32-clipboard
こいつ使えると便利(画像も扱えるし、クリップボード監視とかもできる)そうなんですが、
いろいろ問題があります。
問題:
  1. 画像情報を扱うとエラーが発生する場合がある
  2. 日本語を扱うと、エラーが発生する
  3. 上記エラー解決しても、日本語を扱う場合、文字が途中で途切れる
1. 3. はともかく、2. の日本語対応のためには、かなーり面倒な修正が必要になるので、
こちらの方が別の方法 (AutoITX を使う方法) を紹介しています。
Rubyからクリップボードを操作する方法
ただし AutoITX では、文字列しか扱えないっぽいので、お好きな方をお選びください。

以降では、以下のファイルを編集していきます。
{ ruby のインストール先 }\lib\ruby\gems\2.0.0\gems\win32-clipboard-0.5.2\lib\win32\clipboard.rb

1. 画像情報を扱うとエラーが発生する場合がある

実際動かしてみると、エンコードの異なる 2 つの変数を結合しようとしてエラーが発生します。
C:/ruby/lib/ruby/gems/2.0.0/gems/win32-clipboard-0.5.2/lib/win32/clipboard.rb:388:in `get_image_data': incompatible character encodings: ASCII-8BIT and US-ASCII
 (Encoding::CompatibilityError)
        from C:/ruby/lib/ruby/gems/2.0.0/gems/win32-clipboard-0.5.2/lib/win32/clipboard.rb:129:in `data'
        from C:/Applications/ruby/screenshot/printscreen.rb:23:in `write'
        from clipimagetest.rb:4:in `
'

1. 修正方法

極めて単純。
US-ASCII として Ruby に認識されちゃっている変数を、
ASCII-8BIT(BINARY) として認識させるだけです。
buf = "\x42\x4D" + [size_image].pack('L') + 0.chr * 4 + [offset].pack('L') + buf
buf = "\x42\x4D" + [size_image].pack('L') + 0.chr * 4 + [offset].pack('L') + buf.b
※ 1.9 系の場合、String#b が無いはずなので、以下のようにしてください。
buf = "\x42\x4D" + [size_image].pack('L') + 0.chr * 4 + [offset].pack('L') + buf.force_encoding('ASCII-8BIT')
やってることは、画像情報なので、buf の中身はバイナリとして扱ってねと教えてあげてるだけです。
以上で、クリップボード上の画像情報を Ruby で扱えるようになります。
require 'win32/clipboard'

if Win32::Clipboard.format_available?(Win32::Clipboard::DIB)
  File.open('image.png', 'wb'){ |f|
    f.write Win32::Clipboard.data(Win32::Clipboard::DIB)
  }
end

2. 日本語を扱おうとすると、エラー発生して使用できない

クリップボード上にある文字列を取得した際、その文字列が US-ASCII として認識されているのが原因。
C:/ruby/lib/ruby/gems/2.0.0/gems/win32-clipboard-0.5.2/lib/win32/clipboard.rb:123:in `[]': invalid byte sequence in US-ASCII (ArgumentError)
        from C:/ruby/lib/ruby/gems/2.0.0/gems/win32-clipboard-0.5.2/lib/win32/clipboard.rb:123:in `data'
        from cliptest.rb:8:in `
'

2. 修正方法(暫定)

注意:この対応は応急処置的な対応で、とりあえず Shift_JIS だけ使えるようにします。
clip_data = clip_data[ /^[^\0]*/ ]
while clip_data[clip_data.bytesize - 1] == "\0"
  clip_data.chop!
end
ただし Ruby(win32-clipboard) でコピーした文字列を
メモ帳などのエディタにペーストすると文字化けすると思います。
その場合は、以下のように String#tosjis を使ってあげると大丈夫です。
require 'win32/clipboard'
require 'kconv'

# shift_jis でクリップボードにセット
Win32::Clipboard.set_data("クリップボードにデータを設定".tosjis)
# クリップボードのデータを取得
puts Win32::Clipboard.data.tosjis
# UTF-8 でやった方が……というツッコミもあると思います。
# おっしゃるとおりだと思います。
# ただ、現状の win32-clipboard を結構改造しないと UTF-8 は扱えないのです……。
# なので、今回は見送ります。

3. 上記エラー解決しても、日本語を扱うと場合、文字が途中で途切れる

原因は、バイト数が必要になる箇所で、String#length および String#size を使用しているため。
参考:length, size (String) - Rubyリファレンス
一部を抜粋すると、
1.8 系では、文字の数はバイト数と同じになります。
1.9 系ではlengthメソッドは文字の数を返します。
バイト数を得たいときはbytesizeメソッドを使います。

3. 修正方法

String#size と String#length を String#bytesize に片っ端から修正します。
たとえば 77行目あたりを例にすると以下のように修正します。
hmem = GlobalAlloc(GHND, clip_data.length + 4)
mem  = GlobalLock(hmem)
memcpy(mem, clip_data, clip_data.length)
hmem = GlobalAlloc(GHND, clip_data.bytesize + 4)
mem  = GlobalLock(hmem)
memcpy(mem, clip_data, clip_data.bytesize)
以上で、Shift_JIS 限定ではありますが、Ruby でクリップボードが使えるようにはなります。

実は、他にも win32-clipboard にはマルチバイト文字を扱う上で妙な箇所があったりしますが、
エンコード周りは深入りしたくないので、スルー。
# たとえば bytesize + 4 の + 4 って何者!?とか。UTF-32 を考慮して + 4 してあるのかなぁ。
でも、UTF-8くらいは使えるようにしたいので、いつか、ある程度は対応したいです。
2014/01/13 | カテゴリ:Ruby | トラックバック(0) | コメント(0)
コメントの投稿












管理者にだけ表示を許可する
トラックバック
この記事のトラックバックURL
http://uisteven.blog.fc2.com/tb.php/42-70eeb79a

外部リンク

カンパのお願い
公開しているソフトウェアはフリーウェアなので無料でご利用いただけます。 気に入ってくださった方は、Amazon でお買い物をする際に下記のリンクを経由して頂ければ励みになります。

検索BOX・タグ一覧
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。