WIN32OLE で使える VARIANT_NAME

常識的なタイプライブラリを使っていると必要ないが、設計のよろしくないタイプライブラリを使うと引数の型をいちいち指定してやらないと関数を呼べないことがある。

optional な引数を飛ばして次の引数を指定する場合など。

require 'win32ole'
include WIN32OLE::VARIANT

app = WIN32OLE.new 'Foobar.Application'
at_exit{app.Quit}

m = app.ole_method('foo')
app._invoke(m.dispid, [1, nil, 3], [VT_I4, VT_I4, VT_I4])

第 2 引数の Array が foo に渡したい引数で、第 3 引数の Array が引数の型。
VT_VARIANT|VT_ARRAY みたいな指定もできる。


この VT_* が覚えられないのでメモ。

require 'win32ole'
include WIN32OLE::VARIANT

vt = {
 VT_ARRAY:VT_ARRAY,
 VT_BOOL:VT_BOOL,
 VT_BSTR:VT_BSTR,
 VT_BYREF:VT_BYREF,
 VT_CY:VT_CY,
 VT_DATE:VT_DATE,
 VT_DISPATCH:VT_DISPATCH,
 VT_EMPTY:VT_EMPTY,
 VT_ERROR:VT_ERROR,
 VT_I1:VT_I1,
 VT_I2:VT_I2,
 VT_I4:VT_I4,
 VT_I8:VT_I8,
 VT_INT:VT_INT,
 VT_NULL:VT_NULL,
 VT_PTR:VT_PTR,
 VT_R4:VT_R4,
 VT_R8:VT_R8,
 VT_UI1:VT_UI1,
 VT_UI2:VT_UI2,
 VT_UI4:VT_UI4,
 VT_UI8:VT_UI8,
 VT_UINT:VT_UINT,
 VT_UNKNOWN:VT_UNKNOWN,
 VT_USERDEFINED:VT_USERDEFINED,
 VT_VARIANT:VT_VARIANT,
}

vt.sort_by{|key, val| val}.each do |key, val|
  puts "%16b %5d %s" % [val, val, key]
end
# >>                0     0 VT_EMPTY
# >>                1     1 VT_NULL
# >>               10     2 VT_I2
# >>               11     3 VT_I4
# >>              100     4 VT_R4
# >>              101     5 VT_R8
# >>              110     6 VT_CY
# >>              111     7 VT_DATE
# >>             1000     8 VT_BSTR
# >>             1001     9 VT_DISPATCH
# >>             1010    10 VT_ERROR
# >>             1011    11 VT_BOOL
# >>             1100    12 VT_VARIANT
# >>             1101    13 VT_UNKNOWN
# >>            10000    16 VT_I1
# >>            10001    17 VT_UI1
# >>            10010    18 VT_UI2
# >>            10011    19 VT_UI4
# >>            10100    20 VT_I8
# >>            10101    21 VT_UI8
# >>            10110    22 VT_INT
# >>            10111    23 VT_UINT
# >>            11010    26 VT_PTR
# >>            11101    29 VT_USERDEFINED
# >>   10000000000000  8192 VT_ARRAY
# >>  100000000000000 16384 VT_BYREF

Hash vt は rcodetools で補完して出てきたものをちょろっと加工。*1

ビット 1 が立ってるから VT_NULL かと思うのは早計で、VT_I4 なんかもビット 1 が立っている。*2

たぶん 0 〜 29 までは同時に満すことはなくて、組み合わせに使えるのは VT_ARRAY と VT_BYREF だけなんだろうなぁ。

*1:補完できるなら覚える必要ない?

*2:たぶん Windows やる人には常識なんだろうけど。