Win32 API の利用について

タグの編集
投稿者 ヒロ  (学生) 投稿日時 2019/12/24 14:32:44
プログラムで特定のExcelファイルを印刷する処理を作成しました。
(Formアプリケーションで、フォームにボタンを2つ配置しています)

Button1 は Win32 API のShellExecute 関数を使って、Button2 では Process 関数を使って印刷処理を行います。

結果は同じでしたが、Win32 API の関数を使用する場合、ネットで色々調べたるところ、引数の型や戻り値の型がいくつかパターンがあるようで、どれが正しいのかわからず、全部試してとりあえず動いた!という状況です。

第一パラメータの「親ウィンドウのハンドル」と、関数の戻り値をともに Long 型にしていましたが、どうもVB6 のときの書き方のようで、.NET では Integer 型にするべきということで、以下の様に記述しました。

Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As Integer, ByVal lpszOp As String, ByVal lpszFile As String, ByVal lpszParams As String, ByVal lpszDir As String, ByVal FsShowCmd As Integer) As Integer


ざっくりとした質問になりますが、これで問題はないのでしょうか?
投稿者 KOZ  (社会人) 投稿日時 2019/12/24 16:37:50
ハンドルは 64bit の OS では 64bit になりますので、System.IntPtr で宣言してください。

API の宣言は pinvoke.net で調べると良いです。

ShellExecute の書き方はこちら
https://www.pinvoke.net/default.aspx/shell32/ShellExecute.html

Declare を使って宣言した場合、文字列を MarshalAs で修飾しないと
日本語文字列を与えたとき、文字列が破壊されるので新しい記法を
使ったほうがいいと思います。

Declare Function MsgBox Lib "user32.dll" Alias "MessageBoxA" _
                (ByVal hWnd As IntPtr, ByVal txt As String,
                 ByVal caption As String, ByVal Typ As Integer) As Integer
Sub Main()
    Dim text As String = "字ABC"
    MsgBox(IntPtr.Zero, text, vbNullString, 0) ' "字ABC" と表示される
    MsgBox(IntPtr.Zero, text, vbNullString, 0) ' "字AB" と表示される
End Sub

Declare を使って文字を破壊しないようにするには

Imports System.Runtime.InteropServices

Declare Function MsgBox Lib "user32.dll" Alias "MessageBoxA" _
            (ByVal hWnd As IntPtr,
             <MarshalAs(UnmanagedType.LPStr)> ByVal txt As String,
             <MarshalAs(UnmanagedType.LPStr)> ByVal caption As String,
             ByVal Typ As Integer) As Integer

このように書きます。

投稿者 ヒロ  (学生) 投稿日時 2019/12/25 10:02:06
KOZ様

ご回答いただき、ありがとうございます。

参考サイトだけでなく、Declareを使った宣言時の注意点についても
教えて頂き大変勉強になりました。