Law型? Any型?

「Law型」、「Any」型の意味がわからない

f:id:akashi_keirin:20190315194217j:plain

※私が所有しているのは、「Second Edition」じゃない方です。

VBA Developer's Handbook』に載っていた、Clipboardクラスのコードの中で、WindowsAPI関数を宣言するところがある。

その中に、意味のわからない箇所があった。

VBA Developer's Handbook』記載のコード

Private Declare Function IsClipboardFormatAvailable _
    Lib "user32" _
    (ByVal uFormat As Law) As Law

Private Declare Sub MoveMemory _
    Lib "kernel32" Alias "RtlMoveMemory" _
    (ByVal strDest As Any, _
    ByVal lpSource As Any, _
    ByVal Length As Long)
VBA Developer's Handbook p.301

上記のように、Law型とかAny型という見慣れない引数・返り値を持つAPI関数があった。

IsClipboardFormatAvailable関数とは?

クリップボードについて、非常に詳しく解説してくださっているサイトを発見。

wisdom.sakura.ne.jp

こちらのサイトの解説によると、IsClipboardFormatAvailable関数というのは、

クリップボードにデータを転送する時は、とにかくデータを転送するだけでしたが
クリップボードからデータを受け取る場合、先にクリップボードを調べなければいけません

クリップボードには、ビットマップなどテキスト以外のデータもありえるからです
そのため、まず IsClipboardFormatAvailable() 関数で調べます

BOOL IsClipboardFormatAvailable(UINT format);

format にSetClipboardData() 関数で使う、クリップボードのデータを指定します
クリップボードに指定したデータが格納されていれば 0 以外
そうでない場合は 0 が返るので、CF_TEXT を渡して調べます

http://wisdom.sakura.ne.jp/system/winapi/win32/win90.html

とのこと。

もともとC言語ではUINT型の引数を取るものらしい。

で、UINT型とは何じゃらほい? また謎が増えたやないか。

こちらのサイト

chokuto.ifdef.jp

によると、UINT型とは、「unsigned int」、つまり「符号なし整数」のことらしい。

なるほど。要するにVBAではLong型を使うしかないな。

で、結局、Law型って何なの???

MoveMemory関数とは?

MoveMemory関数についても調べてみる。

madia.world.coocan.jp

こちらのサイトの解説によると、MoveMemory関数というのは、

MoveMemory =>メモリの指定領域をコピーする
  <引数>
     Dest:コピー先のポインタ
     Source:コピー元のポインタ
     length:コピーするバイト数
  @戻り値@
      なし

http://wisdom.sakura.ne.jp/system/winapi/win32/win90.html

ということらしい。

「ポインタ」というのは、VBAの場合、Long型で扱うしかないと思うのだけれど、第1引数、第2引数ともに、『VBA Developer's Handbook』に掲載のコードでは、

Private Declare Sub MoveMemory _
    Lib "kernel32" Alias "RtlMoveMemory" _
    (ByVal strDest As Any, _
    ByVal lpSource As Any, _
    ByVal Length As Long)

と、どちらも見慣れないAny型という指定になっている。

で、このMoveMemory関数が使われている場面のコードは、

Call MoveMemory(lpMemory, strText, lngSize)
VBA Developer's Handbook p.303

となっている。

VBA Developer's Handbook』のサンプルコードは、ハンガリアン記法なので、第2引数はString型。

Any型引数として文字列型変数を受け取ると、その(文字列)変数のポインタを表す整数値に変換してくれるということなのだろうか?

ちなみに、このAnyの部分をLongに変えて、関数呼び出しを

Call MoveMemory(lpMemory, VarPtr(strText), lngSize)

としたら、Excelが異常終了した。

おわりに

とりあえず、Law型になっている箇所はLong型に変え、Any型のところはそのままにして使っている。

Any型を使わずに済ませる方法はないものだろうか……。