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

Dav*_*ard 0 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
Run Code Online (Sandbox Code Playgroud)

Han*_*ant 5

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

您的旧式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
Run Code Online (Sandbox Code Playgroud)

或者只是称它为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
Run Code Online (Sandbox Code Playgroud)