0

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

在 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
4

1 回答 1

5

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

您的旧式 Declare 语句正在使用 legacy 函数。您应该使用 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。使用 legacy 函数不是很漂亮,尽管将“About”转换为 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
于 2013-04-09T13:56:44.540 回答