投稿者 魔界の仮面弁士  (社会人) 投稿日時 2010/7/30 10:42:13
> VB6のLongは2008ではIntegerになるのをうっかりしていました。
とは限りません。Long → Integer への単純置換で済むと言うのは、
32bit専用アプリしか作れなかった VB2002/2003 当時の話です。

たとえば API 側が DWORD 型であった場合は、(VB6)Long→(VB2008)Integer/UInteger へ
置きかえるだけで OK です。しかし、今回の場合はそうではありません。

元の型がハンドル(型名が h や H で始まるもの)や、ポインタ(型名が LP で始まるもの)で
あった場合、VB6 の Long/OLE_HANDLE 型は、VB.NET では Integer 型に置き換えるのではなく、
IntPtr 型とするべきです。(64bit専用アプリならLong、32bit専用アプリならIntegerでも可)


> 調べたサンプルをそのまま張り付けてしまったのがバレバレですが
(Windows 的には 張り付け → 貼り付け ですね)

サンプルコードを利用する場合には、「ByRef As 構造体」と「ByVal As クラス」の
いずれで宣言されているかにも注意しておいてください。

たとえば、もとの資料が .NET 用に書かれた API コードであったとしても、

--------------
Declare Function CreateBrushIndirect Lib "…" (ByRef x As LOGBRUSH) As …
Structure LOGBRUSH
 :
End Structure
--------------
Declare Function CreateBrushIndirect Lib "…" (ByVal x As LOGBRUSH) As …
Class LOGBRUSH
 :
End Class
--------------

のように、同じ API が資料によって異なる宣言で紹介される事があります。

複数の資料を利用した場合などに、これらを混ぜこぜにして、「ByRef As クラス」で
宣言してしまい、正常に動作しなくなった事例を見たことがあります。蛇足までに。


>> Private Declare Function CreateBrushIndirect Lib "gdi32" _
>>       (ByVal lpLogBrush As LOGBRUSH) As <MarshalAs(UnmanagedType.Bool)> Boolean
> ただしくは、「ByRef lpLogBrush As LOGBRUSH」ですね。
戻り値の指定も間違っているようです。

この API の戻り値は、成否を表す BOOL 型ではなく、論理ブラシを表す HBRUSH 型です。
HBRUSH はハンドル型ですから、この場合には IntPtr で受ける必要があります。
http://msdn.microsoft.com/ja-jp/library/cc428326.aspx

そもそも、Boolean 型の戻り値を持つ関数であるならば、
> Dim NewBrush As LOGBRUSH
> Dim hNewBrush As Integer
> hNewBrush = CreateBrushIndirect(NewBrush) 'ここでエラー 
のように、それを Integer で受けているのは、API で無くとも不自然ですよね。