ruby 覚え書き

ダイアログボックス関連
メッセージボックスを出してみる
インプットボックスを出してみる
コモンダイアログを使ってみる
レジストリ値の読み込み
クリップボードの操作
ドラッグアンドドロップ
jwwファイルのメモを取り出す
エンコードとデコード
数字にカンマを付ける
Win32API関連
メッセージボックスの表示
電卓の移動
メモ帳に文字を送る
スクリーンセーバーの起動
現在開いてるウィンドウを調べる

ダイアログボックス関連

メッセージボックスを出してみる


#! ruby
require 'win32ole'
 
wsh = WIN32OLE.new('WScript.Shell')
wsh.Popup("こんにちは",0, "タイトル")

インプットボックスを出してみる


require'win32ole' 

sc=WIN32OLE.new("ScriptControl")
sc.language="VBScript"
a=sc.eval('InputBox("こんにちは"&vbcrlf&"入力してちょ","タイトル")')
sc.eval(%Q! MsgBox("#{a}",0,"タイトル") !)

コモンダイアログを使ってみる

簡単に済まそうと思うとこんな感じ。


#! ruby

require'win32ole' 
require 'vr/vruby' 

file=SWin::CommonDialog::
  openFilename(nil,[["BAT(*.bat)","*.bat"],
                 ["all(*.*)","*.*"]],0x1000)
wsh = WIN32OLE.new('WScript.Shell')
if file
  wsh.Popup(file,0, "選択されたファイルは")
else
  wsh.Popup("キャンセルされました",0, "error:")
end 

位置が左上ではヤダという場合はダミーのウィンドウを準備してみよう。


#! ruby 

require'win32ole' 
require 'vr/vruby' 

class MyForm < VRForm
  def construct
    col=SWin::CommonDialog::chooseColor(self)
    wsh = WIN32OLE.new('WScript.Shell')
    if col
      wsh.Popup(col,0, "選択された色は")
    else
      wsh.Popup("キャンセルされました",0, "error:")
    end 
    move 200,1200,0,0 # ダミーのウィンドウを隠す
  end
end

VRLocalScreen.showForm(MyForm,200,200,0,0)

win32ole を使う方法を覚えた。
こちらの方が便利かも。


#! ruby

require 'win32ole'

obj=WIN32OLE.new("MSComDlg.CommonDialog")
obj.MaxFileSize =255    
obj.Filter = "すべてのファイル (*.*)|*.*|"
obj.InitDir ="C:\\" 
obj.ShowOpen 
file=obj.FileName

wsh = WIN32OLE.new('WScript.Shell')
if file==""
  wsh.Popup("キャンセルされました",0, "error:")
else
  wsh.Popup(file,0, "選択されたファイルは")
end 

レジストリ値の読み込み

win32ole で RegRead を使う。


#! ruby -Ks

require 'win32ole'

wsh = WIN32OLE.new('WScript.Shell')
zfile='HKEY_CURRENT_USER\Software\Jw_cad\jw_win\Folder\ZFILE'
ztemp = wsh.RegRead zfile
p ztemp

Win32/Registry を利用すればもっと柔軟。


#! ruby -Ks

require 'Win32/Registry'

Win32::Registry::HKEY_CURRENT_USER.
  open('Software\Jw_cad\jw_win\Folder') do |reg|
  type, value = reg.read('ZFILE')
  p value
  reg.each_value{|name, type, data| puts("#{name}=#{data}")}
end

クリップボードの操作

Win32Utils を使うんだけど、いまのところテキストしか扱えないらしい。


#! ruby -Ks

require "win32/clipboard"
include Win32

p Clipboard.data
Clipboard.set_data("hoge")
p Clipboard.data

vruby の clipboard.rb で setText/getTextではなく、setData/getData を利
用するとテキスト以外にもいろんなデータに対応できるらしい。

ドラッグアンドドロップ

BATファイルにして ruby -x でスクリプトを呼べばドラッグアンドドロップで
ファイルを処理できる。


ruby -Ks -x %~f0 %1 %2 %3 %4 %5 %6 %7 %8 %9
exit

#! ruby

require 'win32ole'

wsh = WIN32OLE.new('WScript.Shell')
wsh.Popup(ARGV.join("\n"),0, $0)

jwwファイルのメモを取り出す

こんな感じのBATファイルはどうだろう。
jwwファイルをドラッグアンドドロップして使ってみる。


ruby -Ks -x %~f0 %1 %2 %3 %4 %5 %6 %7 %8 %9
exit

#! ruby
require 'win32ole'

wsh = WIN32OLE.new('WScript.Shell')

ARGV.sort.each{|argv|
if /\.jww$/i=~argv
  memo=open(argv).read(100)[13,80].
    scan(/(.*)\f/m).flatten[0]
  wsh.Popup(memo,0,argv)
else
  wsh.Popup("error:\njwwファイルではないようです",
            0, argv)
end}

エンコードとデコード

ファイルをエンコードするバッチファイル。


ruby -Ks -x %~f0 %1 %2 %3 %4 %5 %6 %7 %8 %9
exit

#! ruby 
ARGV.each{|argv|
open(argv+".txt","w"){|e|
e.print [open(argv,"rb").read].pack("m")}}

ファイルのデコードするバッチファイル。
エンコードされたテキスト(txt)を元に戻す。
同名のファイルには上書きしない。
一応、エラーのログをとる。


ruby -Ks -x %~f0 %1 %2 %3 %4 %5 %6 %7 %8 %9
exit

#! ruby 
$stderr=open(File.dirname(ARGV[0])+'\error.log',"w")
ARGV.each{|argv|
unless FileTest.file?(argv.sub(/\.te?xt$/i,""))
open(argv.sub(/\.te?xt$/i,""),"wb"){|e| 
e.print open(argv).read.unpack("m")}
end}

数字にカンマを付ける

jcode には reverse がないんだけど、
each_char.reverse.join で代用すればOK。


#! ruby -Ks

require 'jcode'

class String
  def add_comma
    return self.gsub(/([\-\+−+]?)     # $1=>符号
      ([0-90-9]+)                     # $2=>整数部
      ((?:[\..][0-90-9]*)?)/x){|f|   # $3=>小数部
      a,b,c=$1,$2,$3
      b=b.each_char.reverse.join.
        gsub(/([0-90-9]{3})/,'\1,').
        each_char.reverse.join.gsub(/^,/,"")
      (a+b+c).gsub(/([0-9])\,/,'\1,')}
  end
end

p "1234567.8901".add_comma # => "1,234,567.8901"
p "−12345".add_comma # => "−12,345"

Win32API関連

メッセージボックスの表示


#! ruby

require 'dl/win32'

mb = Win32API.new("user32","MessageBoxA",'LPPL',"L")
mb.call(0, "hoge", "title", 0)

電卓の移動

電卓を起動してサイズやタイトルの変更。


#! ruby

require 'dl/win32'

Thread.start{system("calc")}
sleep 0.5
fw = Win32API.new('user32', 'FindWindow', 'LP', 'L')
hw = fw.call(0,'電卓')
mw = Win32API.new('user32', 'MoveWindow', ['L']*6, 'L')
mw.call(hw, 200, 200, 400, 300, 1)
swt=Win32API.new('user32', 'SetWindowText', 'LP', 'L')
swt.call(hw,"でんたく")

メモ帳に文字を送る

メモ帳を起動して「Hello World!」を入力してヘルプ起動。
文字はASCII文字コード表を参考に。


#! ruby

require 'dl/win32'

Thread.start{system("notepad")}

sleep 0.5
fw=Win32API.new('user32','FindWindow','PP','L')
fe=Win32API.new('user32','FindWindowEx','LLPP','L')

hw=fw.call(0,"無題 - メモ帳")
hw=fe.call(hw,0,"Edit",0)
sm= Win32API.new("user32", "SendMessage",['L']*4,'L')
[72,101,108,108,111,32,87,111,114,108,100,33,13].each{|e|
  sm.call(hw,0x102,e,0)} #0x102:WM_CHAR
ke = Win32API.new('user32','keybd_event','IILL','V')
ke.call(0x12,0,0,0) #0x12:VK_MENU
ke.call(0x48,0,0,0) #0x48:VK_H
ke.call(0x12,0,2,0) #0x12:VK_MENU
ke.call(0x48,0,0,0) #0x48:VK_H

スクリーンセーバーの起動

頭の「0x」は16進数を表す。
274 :WM_SYSCOMMAND
0xf140:SC_SCREENSAVE に相当。


#! ruby

require 'dl/win32'

getDesktopWindow = Win32API.new("user32", "GetDesktopWindow", [], 'L')
sendMessage = Win32API.new("user32", "SendMessage", ['L'] * 4, 'L')
sendMessage.Call getDesktopWindow.Call, 274, 0xf140, 0

現在開いてるウィンドウを調べる

ウィンドウのハンドルとクラス名、ウィンドウタイトルを列挙
out.log に書き出す


#! ruby 

$stderr=open("error.log","w")
$stdout=open("out.log","w")

require 'dl/win32'

User32 = DL.dlopen("user32")

def get_window_text(hwnd)
  buf = "\0" * 500
  gWT = Win32API.new('user32','GetWindowTextA','LPI','I')
  gWT.call(hwnd,buf, buf.size)
  return buf.unpack("A*")[0]
end

def get_class_name(hwnd)
  buf = "\0" * 500
  gCN= Win32API.new('user32','GetClassName','LPI','I')
  gCN.Call(hwnd,buf, buf.size)
  return buf.unpack("A*")[0]
end

def puts_handle(hwnd)
  puts hwnd.to_s+";"+get_class_name(hwnd)+
    ";"+get_window_text(hwnd)
end

# puts "===== EnumWindows ====="*2
# ew= User32['EnumWindows', '0PL']
# enum_windows_proc = DL.callback('IL'){|hwnd2|
#   puts_handle(hwnd2);  -1}
# ew.call(enum_windows_proc, 0)
# puts "=== EnumChildWindows ==="*2
hw=Win32API.new("user32","GetDesktopWindow",[],"L").call
ec= User32['EnumChildWindows', '0LPL']
enum_child_proc = DL.callback('IL'){|hwnd2|
  puts_handle(hwnd2);  -1}
ec.call(hw,enum_child_proc, 0)

更新履歴

2007/09/30 :第5版改訂
2007/09/21 :第4版改訂
2007/09/15 :第3版改訂
2007/09/09 :第2版改訂
2007/09/05 :初版


戻る