Win32 API の利用について への返答

投稿で使用できる特殊コードの説明。(別タブで開きます。)
本名は入力しないようにしましょう。
投稿した後で削除するときに使うパスワードです。返答があった後は削除できません。
返答する人が目安にします。相手が小学生か社会人かで返答の仕方も変わります。
最初の投稿が質問の場合、質問者が解決時にチェックしてください。(以降も追加書き込み・返信は可能です。)
※「過去ログ」について書くときはその過去ログのURLも書いてください。

以下の返答は逆順(新しい順)に並んでいます。

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

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

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

投稿者 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/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


ざっくりとした質問になりますが、これで問題はないのでしょうか?