Determining System Button Captions

The .NET Framework does not expose the strings used as captions for buttons in message boxes and other windows. Some of these strings are located as Win32 resources in user32.dll. The SystemStrings class shown below loads the strings from this library and makes them available through shared properties:

Imports System.ComponentModel

Public NotInheritable Class SystemStrings
    Private Declare Auto Function LoadLibrary Lib "kernel32.dll" ( _
        ByVal lpLibFileName As String _
    ) As IntPtr

    Private Declare Function FreeLibrary Lib "kernel32.dll" ( _
        ByVal hLibModule As IntPtr _
    ) As Boolean

    Private Declare Auto Function LoadString Lib "user32.dll" ( _
        ByVal hInstance As IntPtr, _
        ByVal uID As Int32, _
        ByVal lpBuffer As String, _
        ByVal nBufferMax As Int32 _
   ) As Int32

    Private Enum SystemStringId
        OK = 800
        Cancel = 801
        Abort = 802
        Retry = 803
        Ignore = 804
        Yes = 805
        No = 806
        Close = 807
        Help = 808
        Repeat = 809    ' ?
        Continue = 810
    End Enum

    Private Shared m_hUser32 As IntPtr

    Private Sub New()
        '
    End Sub

    Shared Sub New()
        m_hUser32 = LoadLibrary("user32.dll")
        If m_hUser32.Equals(IntPtr.Zero) Then
            Throw New Win32Exception()
        End If
    End Sub

    Public Shared ReadOnly Property OK() As String
        Get
            Return LoadString(SystemStringId.OK)
        End Get
    End Property

    Public Shared ReadOnly Property Cancel() As String
        Get
            Return LoadString(SystemStringId.Cancel)
        End Get
    End Property

    Public Shared ReadOnly Property Abort() As String
        Get
            Return LoadString(SystemStringId.Abort)
        End Get
    End Property

    Public Shared ReadOnly Property Retry() As String
        Get
            Return LoadString(SystemStringId.Retry)
        End Get
    End Property

    Public Shared ReadOnly Property Ignore() As String
        Get
            Return LoadString(SystemStringId.Ignore)
        End Get
    End Property

    Public Shared ReadOnly Property Yes() As String
        Get
            Return LoadString(SystemStringId.Yes)
        End Get
    End Property

    Public Shared ReadOnly Property No() As String
        Get
            Return LoadString(SystemStringId.No)
        End Get
    End Property

    Public Shared ReadOnly Property Close() As String
        Get
            Return LoadString(SystemStringId.Close)
        End Get
    End Property

    Public Shared ReadOnly Property Help() As String
        Get
            Return LoadString(SystemStringId.Help)
        End Get
    End Property

    Public Shared ReadOnly Property Repeat() As String
        Get
            Return LoadString(SystemStringId.Repeat)
        End Get
    End Property

    Public Shared ReadOnly Property Continue() As String
        Get
            Return LoadString(SystemStringId.Continue)
        End Get
    End Property

    Private Shared Function LoadString(ByVal Id As SystemStringId) As String
        Dim Buffer As String = Space(100)
        Dim n As Int32 = LoadString(m_hUser32, Id, Buffer, Buffer.Length)
        If n = 0 Then
            Throw New Win32Exception()
        End If
        Return Strings.Left(Buffer, n)
    End Function

    Private Shared Finalizer As New SharedFinalizer

    Private Class SharedFinalizer
        Protected Overrides Sub Finalize()
            MyBase.Finalize()
            If Not m_hUser32.Equals(IntPtr.Zero) Then
                If Not FreeLibrary(m_hUser32) Then
                    Throw New Win32Exception()
                End If
            End If
        End Sub
    End Class
End Class

Usage:

Me.CancelButton.Text = SystemStrings.Cancel