Ruby


クリップボードを操作

今回は、クリップボードを操作します。具体的には、クリップボードとデータの授受を行うってことです。 前回はクリップボードからの文字列の取得を行いましたが、今回は文字列をセットするので、結構関数が多いですががんばってください。 ゲットする場合は大抵よきにはからえですが、セットするときはフォーマットを整えたりするのがちょっと面倒なのです。
では、実際のコードを以下に示しましょう。

001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 023 024 025 026 027 028 029 030 031 032 033 034 035 036 037 038 039 040 041 042 043 044 045 046 047 048 049 050 051 052 053 054 055 056 057 058 059 060 061 062 063

#!ruby -Ks #2009/11/1 Shirao #クリップボードを操作するプログラム require "Win32API" #クリップボード操作モジュール module Clipboard #クリップボード操作関数群 $OpenClipboard = Win32API.new("user32", "OpenClipboard", ["I"], "I"); $CloseClipboard = Win32API.new("user32", "CloseClipboard", [], "I"); $GetClipboardData = Win32API.new("user32", "GetClipboardData", ["I"], "I"); $SetClipboardData = Win32API.new("user32", "SetClipboardData", ["I", "I"], "I"); #メモリ操作関数群 $GlobalAlloc = Win32API.new("kernel32", "GlobalAlloc", ["I","I"], "I"); $GlobalLock = Win32API.new("kernel32", "GlobalLock", ["I"], "P"); #get $GlobalLockI = Win32API.new("kernel32", "GlobalLock", ["I"], "I"); #set $GlobalUnlock = Win32API.new("kernel32", "GlobalUnlock", ["I"], "I"); $GlobalSize = Win32API.new("kernel32", "GlobalSize", ["I"], "I"); $GlobalFree = Win32API.new("kernel32", "GlobalFree", ["I"], "I"); #文字列(ポインタ)操作関数群 $lstrcpy = Win32API.new("kernel32", "lstrcpyA", ["P", "P"], "P"); $lstrlen = Win32API.new("kernel32", "lstrlenA", ["P"], "I"); CF_TEXT = 1 #他にもいろいろ GHND = 0x0042; #これも他にもいろいろある #テキスト取得メソッド def self.getText clpdata = "" while $OpenClipboard.Call(0) == 0 #開くまで座して待て sleep 1 end begin if(h = $GetClipboardData.Call(CF_TEXT))!=0 #ある? if p = $GlobalLock.Call(h) #ロックして取り出すべし clpdata = p; $GlobalUnlock.Call(h); end end ensure $CloseClipboard.Call end return clpdata; end #テキスト設定メソッド def self.setText(str) if $OpenClipboard.Call(0) != 0 #開かなかったら残念賞 len = $lstrlen.Call(str) hmem = $GlobalAlloc.Call(GHND, len+1); pmem = $GlobalLockI.Call(hmem); $lstrcpy.Call(pmem, str); $SetClipboardData.Call(CF_TEXT, hmem); $GlobalUnlock.Call(hmem); $CloseClipboard.Call end end end Clipboard.setText("『"+Clipboard.getText.to_s+"』") puts Clipboard.getText.to_s

ポイント

setText

今回追加されたのがsetTextメソッドです。 クリップボードにデータをセットするための手順を書いておきます。
まず、OpenClipboardで開いて、
セットする文字列の長さをlstrlen関数で取得し(lengthやsizeといったRubyのメソッドではない)、
GlobalAllocとGlobalLockI(戻り値がint)でメモリ領域をロックする。
そして、lstrcpyでそのメモリ領域に文字列をコピーして、
そのメモリ領域をSetClipboardDataでクリップボードにセットする。
あとは領域のロックをはずして(GlobalUnlock)、クリップボードをクローズしましょう。 このような手順で行えばできるというわけです。
このようにセットする場合はWinAPIを多用します。 これは、言語の対象とするドメインが違うことに起因するのですが、 手間をかければ結構下位までいじることができるというのはいいことだとおもいます。

付録

応用

さて、今回はクリップボードに文字列をセットする方法を紹介しました。 これで、あなたはクリップボードをプログラムのインタフェースとして使えるようになったわけです(たぶん)。 これを使うと、ファイルよりも手間をかけずに、コマンドライン入力よりも柔軟に、 フォームよりも簡単に文字列データをやり取りできるようになります(モジュールさえコピペしておけば)。 多くの場面に応用が利くので、ぜひ面白いプログラムに仕上げてみてください。
さらに調べると、別の形式のデータの操作についてもマスターできるはずです。 そうすればさらに幅が広がります。ただし、ほどほどにしておくのが吉かもしれません。 餅は餅屋ってことですね。

ソース・入力ファイル

今回のRubyソースコードをおいておきます。


プログラムに戻る