我正在尝试在我的应用的系统菜单中添加一个“关于”按钮,但我找到的代码却抛出错误 -
无法在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
答案 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