我试图调用TrackPopupMenu
函数在运行时从托管VB.NET代码显示菜单。
以下是我得到的错误:
检测到PInvokeStackImbalance消息:调用PInvoke函数 'UeWIPopupX!UeWIPopupX.mDeclares :: TrackPopupMenu '不平衡 堆栈。这很可能是因为托管PInvoke签名 不匹配非托管目标签名。检查是否正在通话 PInvoke签名的约定和参数与目标匹配 非托管签名。
以下是我用于TrackPopupMenu函数的声明:
<DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True, CallingConvention:=CallingConvention.StdCall)> _
Friend Function TrackPopupMenu(ByVal hMenu As Long, ByVal wFlags As Integer, ByVal x As Integer, ByVal y As Integer, ByVal nReserved As Integer, ByVal hWnd As IntPtr, ByVal lprc As RECT) As Integer
End Function
以下是调用TrackPopupMenu
函数的代码:
dim lpRc as RECT
Dim tP As POINTAPI
Dim lR as Integer
Dim lUn as Integer
lUn = TPM_RIGHTBUTTON Or TPM_TOPALIGN Or TPM_LEFTALIGN Or TPM_RETURNCMD
tP.x = 50
tP.y = 100
'Here I am getting the error
lR = TrackPopupMenu(m_ppMenu.Tools(1).hMenu, lUn, tP.x, tP.y, 0, m_hWndOwner, lpRC)
以下是矩形RECT
的声明:
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _
Structure RECT
Dim Left As Integer
Dim Top As Integer
Dim Right As Integer
Dim Bottom As Integer
End Structure
在调用TrackPopupMenu期间的所有参数都有一些值。 我尝试了不同的callConvention但仍然收到错误。
我无法解决这个问题。有谁知道如何解决这个问题?
答案 0 :(得分:1)
您的声明是错误的。第一个参数是菜单的句柄,因此必须是IntPtr。最后一个参数是RECT的指针。 VB.NET中的ByRef。由于它实际上并未使用,因此最好将其声明为ByVal IntPtr,这样您就不需要RECT声明了。在您的通话中传递IntPtr.Zero。返回值是布尔值,而不是整数。如果得到False返回,则抛出Win32Exception。修正:
<DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
Friend Function TrackPopupMenu(ByVal hMenu As IntPtr, ByVal wFlags As Integer, _
ByVal x As Integer, ByVal y As Integer, ByVal nReserved As Integer, _
ByVal hWnd As IntPtr, ByVal ignored As IntPtr) As Boolean
End Function
有一些提示你没有正确的菜单,很难想象你如何提出Long作为参数类型。请注意,此功能已经巧妙地包装在.NET中,不得不对它进行pinvoke它应该是非常罕见的。 TrackPopupMenu已由.NET ContextMenu类调用。 ContextMenuStrip类为其提供了更现代的版本,并提供了更好的渲染选项。