如何正确地将“关于”按钮添加到系统菜单?

时间:2013-04-09 13:02:13

标签: vb.net button systemmenu

我正在尝试在我的应用的系统菜单中添加一个“关于”按钮,但我找到的代码却抛出错误 -

  

无法在DLL'user32'中找到名为'AppendMenu'的入口点。

我想知道是否有人可以请一看代码,并就如何解决问题提出建议?感谢。

Private Declare Function GetSystemMenu Lib "user32" (ByVal hWnd As IntPtr, ByVal bRevert As Boolean) As IntPtr
Private Declare Function AppendMenu Lib "user32" (ByVal hMenu As IntPtr, ByVal uFlags As Int32, ByVal uIDNewItem As IntPtr, ByVal lpNewItem As String) As Boolean

Private Const MF_STRING As Integer = &H0
Private Const MF_SEPARATOR As Integer = &H800

Private Sub AddSysMenuItems()

    'Get the System Menus Handle.
    Dim hSysMenu As IntPtr = GetSystemMenu(Me.Handle, False)

    'Add a standard Separator Item.
    AppendMenu(hSysMenu, MF_SEPARATOR, 1000, Nothing)
    'Add an About Menu Item.
    AppendMenu(hSysMenu, MF_STRING, 1001, "About")


End Sub

1 个答案:

答案 0 :(得分:5)

嗯,消息准确无误,user32.dll中没有名为“AppendMenu”的入口点。它实际上有两个版本。一个名为AppendMenuA,A代表Ansi。使用8位编码字符串的旧版本,通常用于旧C程序。而AppendMenuW,W意味着宽广。它需要一个Unicode字符串,就像所有winapi函数在现代Windows版本上一样。

您的旧式Declare语句正在使用旧版功能。您应该使用Alias关键字来提供正确的入口点名称:

Private Declare Function AppendMenu Lib "user32.dll" Alias "AppendMenuA" (ByVal hMenu As IntPtr, ByVal uFlags As Int32, ByVal uIDNewItem As IntPtr, ByVal lpNewItem As String) As Boolean

或者只是简单地称它为AppendMenuA。使用遗留功能并不是很漂亮,尽管将“关于”转换为Unicode不会有问题。但是赞成使用现代方式声明pinvoke函数,它除了自动映射到A或W版本之外还有许多优点:

Imports System.Runtime.InteropServices
Imports System.ComponentModel
...
    <DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
    Private Shared Function AppendMenu(ByVal hMenu As IntPtr, ByVal uFlags As Int32, ByVal uIDNewItem As IntPtr, ByVal lpNewItem As String) As Boolean
    End Function
...
        If Not AppendMenu(hSysMenu, MF_STRING, IntPtr.Zero, "About") Then
            Throw New Win32Exception()
        End If