投稿者 魔界の仮面弁士  (社会人) 投稿日時 2010/7/8 17:59:19
> Alias "OpenPrinterA"
VB6 当時とは異なり、VB.NET の場合、ANSI 系 API を固定的に呼び出すメリットはほぼありません。
通常は Auto 指定にするか、Unicode 版の API を利用するようにしましょう。
Declare Auto Function OpenPrinter Lib "winspool.drv" (ByVal ~~

以下、Auto 指定の宣言がされた場合という前提で回答します。


> Declare Function OpenPrinter
第 3 引数は、「PRINTER_DEFAULTS への参照」が求められています。
今回は、第 3 引数を ByVal にしているのですから、PRINTER_DEFAULTS を Structure で
宣言するのは誤りです。PRINTER_DEFAULTS を Class に変更してください。

なお、戻り値は As Boolean で構いませんが、この場合の推奨表現は
「As <MarshalAs(UnmanagedType.Bool)> Boolean」となります。
http://msdn.microsoft.com/ja-jp/library/ms182206.aspx


> Declare Function GetPrinter
第 3 引数は、「PRINTER_INFO_2 への参照」です。こちらは、OpenPrinter のような
間違いは無いようですね(ByRef + Structure または ByVal + Class であれば OK)。


> Alias "RtlMoveMemory"
Marshal.StructureToPtr メソッド / Marshal.PtrToStructure メソッドと RtlMoveMemory を
併用されているのは何故でしょうか。Marshal クラスだけで充分な気がします。


> Public Declare Sub CopyMemory1 Lib "KERNEL32" Alias "RtlMoveMemory"
> Public Declare Sub CopyMemory2 Lib "KERNEL32" Alias "RtlMoveMemory"
VB.NET ではオーバーロードが可能なため、それぞれに別名をつける必要はありません。


> Public Structure PRINTER_DEFAULTS
メンバーの型宣言が間違っています。32bit OS で動かす場合は、As Long にはなりません。
<MarshalAs(UnmanagedType.LPTStr)>String, IntPtr, Integer にするか、あるいは
IntPtr, IntPtr, Integer などにしておきましょう。
http://dobon.net/cgi-bin/vbbbs/cbbs.cgi?mode=all&namber=26997&space=0&type=0&no=0


> Public Structure PRINTER_INFO_2
PRINTER_INFO_2 は文字列の受け渡しを伴うため、クラス(もしくは構造体)に
以下の属性を付与して、CharSet を明示しましょう。PRINTER_DEFAULTS も同様です。
 <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)>


> Public Const CCHFORMNAME = 32
> Public Const CCHDEVICENAME = 32
Const にも As を宣言しましょう。


> Public Structure DEVMODE
こちらも StructLayout をつけておいた方が良いでしょう。今回は共用体(union)を
使わないので、LayoutKind.Sequential で良さそうですね。


>    <VBFixedString(CCHDEVICENAME)> Public dmDeviceName As String
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=CCHDEVICENAME)> を付与しましょう。
これは、dmFormname メンバーについても言える事です。

VBFixedString 属性は、Declare で呼び出すアンマネージ API に対しては役に立ちません。
この属性が意味を持つのは、一部のマネージ API に対してだけです(FilePut など)。