VisualBasicのDeclareを使ってWindowsAPIを呼び出す

|

Visual Basic.NET が登場してから早20年。.NETが提供する豊富な機能を利用する事で、Windows API を使用しなくても機能を実装することが出来るようになった、と登場時に言われてから久しいので今更ですが、VBからWin32APIを呼び出してみる事に。

Windows API は、WindowsOSの一部機能であるDLL(ダイナミック・リンク・ライブラリ)ですが、アンマネージド関数であるため、慎重さが必要です。

マイクロソフトのドキュメントによれば、

Windows API を使用する利点は、既に記述され、使用されるのを待っている便利な関数が多数含まれているため、開発時間を節約できる事です。欠点として、Windows API は処理が容易でなく、問題が発生した時に困難な状況に陥る事があります。

Windows API にマネージド・コードは使用されておらず、組み込みのタイプ・ライブラリはありません。また、使用するデータ型は Visual Studio で使用するものとは異なります。Windows API および .NET Framework との相互運用性は、プラットフォーム呼び出し(PInvoke)を使用して実現されます。Visual Basic で PInvoke を使用するには、Declare ステートメントを使用するか、DllImport 属性を「空のプロシージャ」に適用します。

Windows API 呼び出しは、過去においては Visual Basic プログラミングの重要な部分でしたが、Visual Basic .NET ではほとんど必要ありません。可能な限り、Windows API 呼び出しではなく .NET Framework のマネージド関数を使用してタスクを実行するようにして下さい。

の様です。

取り敢えず、Declare ステートメントを使用して MessageBox を呼び出すだけのサンプルを作ってみました。

文字セット修飾子が Auto の場合、関数名に自動的にWを補ってくれるようです。Ansi や Unicode の場合は、関数名にAまたはWが付加されている事を要求します。

Ansi 修飾子は全ての文字列を ANSI 値に、Unicode 修飾子は全ての文字列を UNICODE 値に、自動的にマーシャリングが行われます。

指定した文字型と関数のエントリポイントに不一致などがあると、メッセージボックス内で文字化けが起きたり、例外が発生したりします。


<注意点>

・Declare 宣言の文字セット修飾子の規定値(デフォルト)は、ANSI です。

・Declare 宣言時に Shared 修飾子は使用できませんが、暗黙的に Shared になります。

・Visual Basic のデフォルトの文字セットは、UNICODE です。


お試し環境
  WindowsXP 32bit Edition、Windows7 64bit Edition
  Visual Basic 2008


/*-------------------------------- お試し結果 ------------------------------*/

・Declare Auto Function MBox1 Lib "user32.dll" Alias "MessageBox" (arg1, ...) As Integer の場合

auto-1メッセージボックス表示


・Declare Ansi Function MBox2 Lib "user32.dll" Alias "MessageBox" (arg1, ...) As Integer の場合

ansi-1例外エラー表示


・Declare Unicode Function MBox3 Lib "user32.dll" Alias "MessageBox" (arg1, ...) As Integer の場合

unicode-1例外エラー表示


・Declare Auto Function MBox1 Lib "user32.dll" Alias "MessageBoxA" (arg1, ...) As Integer の場合

auto-2メッセージボックス文字化け表示


・Declare Ansi Function MBox2 Lib "user32.dll" Alias "MessageBoxW" (arg1, ...) As Integer の場合

ansi-2メッセージボックス文字化け表示


・Declare Unicode Function MBox3 Lib "user32.dll" Alias "MessageBoxA" (arg1, ...) As Integer の場合

unicode-2メッセージボックス文字化け表示


・Declare Auto Function MBox1 Lib "user32.dll" Alias "MessageBoxW" (arg1, ...) As Integer の場合

auto-3メッセージボックス表示


・Declare Ansi Function MBox2 Lib "user32.dll" Alias "MessageBoxA" (arg1, ...) As Integer の場合

ansi-3メッセージボックス表示


・Declare Unicode Function MBox3 Lib "user32.dll" Alias "MessageBoxW" (arg1, ...) As Integer の場合

unicode-3メッセージボックス表示


/*----------------------------------------------------------------------------*/


/*-------------------------------- お試しソース ----------------------------*/

Public Class Form1

    Const MB_ICONQUESTION As Integer = &H20
    Const MB_YESNO As Integer = &H4
    Const ID_YES As Integer = 6
    Const ID_NO As Integer = 7

    Declare Auto Function MBox1 Lib "user32.dll" Alias "MessageBox" (ByVal hWnd As Integer, ByVal text As String, ByVal caption As String, ByVal type As Integer) As Integer
    Declare Ansi Function MBox2 Lib "user32.dll" Alias "MessageBoxA" (ByVal hWnd As Integer, ByVal text As String, ByVal caption As String, ByVal type As Integer) As Integer
    Declare Unicode Function MBox3 Lib "user32.dll" Alias "MessageBoxW" (ByVal hWnd As Integer, ByVal text As String, ByVal caption As String, ByVal type As Integer) As Integer

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        ' Stores the return value.
        Dim RetVal As Integer

        RetVal = MBox1(0, "Declare-charsetmodifier & unmanaged Windows API Test", "MBox1 charset auto", MB_ICONQUESTION Or MB_YESNO)

        ' Check the return value.
        If RetVal = ID_YES Then
            MsgBox("choice Yes", , "MBox1")
        Else
            MsgBox("choice No", , "MBox1")
        End If

        Try
            RetVal = MBox2(0, "Declare-charsetmodifier & unmanaged Windows API Test", "MBox2 charset ansi", MB_ICONQUESTION Or MB_YESNO)

            ' Check the return value.
            If RetVal = ID_YES Then
                MsgBox("choice Yes", , "MBox2")
            Else
                MsgBox("choice No", , "MBox2")
            End If

        Catch ex As EntryPointNotFoundException
            MessageBox.Show(ex.Message, "MBox2の例外エラーを捕捉しました")
        Catch ex As Exception
            MessageBox.Show(ex.Message, "その他の例外エラーを捕捉しました")
        End Try

        Try
            RetVal = MBox3(0, "Declare-charsetmodifier & unmanaged Windows API Test", "MBox3 charset unicode", MB_ICONQUESTION Or MB_YESNO)

            ' Check the return value.
            If RetVal = ID_YES Then
                MsgBox("choice Yes", , "MBox3")
            Else
                MsgBox("choice No", , "MBox3")
            End If

        Catch ex As EntryPointNotFoundException
            MessageBox.Show(Err.Description(), "MBox3の例外エラーを捕捉しました")
        Catch ex As Exception
            MessageBox.Show(Err.Description(), "その他の例外エラーを捕捉しました")
        End Try

    End Sub
End Class

/*----------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------*/
/*============================================================================*/

このブログ記事について

このページは、微禄が2021年7月 1日 06:48に書いたブログ記事です。

ひとつ前のブログ記事は「BIGLOBEのメールリニューアルでは見捨てられたけど、WindowsLiveメールを現役続行させる為の設定?」です。

次のブログ記事は「VisualBasicのDllImportを使ってWindowsAPIを呼び出す」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

ウェブページ

NOP法人 アジアチャイルドサポート 最も大切なボランティアは、自分自身が一生懸命に生きること