PopupMenu 想要弹出菜单的窗体的 ScaleMode 中的 X 和 Y 坐标。在这种情况下,这可能意味着用户控制。
但这实际上取决于您在哪里处理 MouseDown 事件。(您不会通过 Click 事件获得坐标。)如果您的事件处理程序位于用户控件本身中,那么使用提供的坐标应该不会有任何问题。但是,您发布的代码缺少Flags参数(应该是vbPopupMenuLeftAlign),这可以解释为什么您的坐标数学不起作用。另外,您必须将菜单定义为用户控件本身的属性。
另一方面,如果您从用户控件中引发 MouseDown 事件,并在包含表单中处理它,则弹出菜单必须是包含表单的属性。在这种情况下,您可以忽略 X 和 Y 参数,但您必须自己进行坐标计算。按钮的左边缘,相对于主窗体,将是用户控件的左边缘和控件内按钮的偏移量之和。类似的数学将用于计算按钮的底部边缘。换句话说:
Private Sub UserControl1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
PopupMenu mnuPopup, vbPopupMenuLeftAlign, _
UserControl1.Left + UserControl1.Button.Left, _
UserControl1.Top + UserControl1.Button.Top + UserControl1.Button.Height
End Sub
请注意,这将要求您还将按钮 (Button) 作为用户控件的属性公开,以便您可以访问其 Left、Top 和 Height 属性。这很容易:
Public Property Get Button() As CommandButton
Set Button = Command1
End Property
发起事件也很简单;就放
Public Event MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
在用户控件的顶部,然后使用:
RaiseEvent MouseDown(Button, Shift, X, Y)
在用户控件中的按钮的 MouseDown 事件中。
最后,要在主窗体中连接事件处理程序,请使用代码编辑窗口顶部的两个下拉菜单。从左侧选择用户控件,然后从右侧选择 MouseDown 事件。这将插入事件处理程序,您使用上面的代码填充它。
至于哪种方式更好,处理用户控件本身内部的菜单,并在选择一个时引发有意义的事件,使事情分开。用户控件处理 UI 工作,让主应用程序处理响应用户选择所需的任何操作,而无需担心菜单的位置。
因此,您实际上不会引发 MouseDown 事件;而是引发像 OptionOneSelected、OptionTwoSelected 或 OptionThreeSelected 这样的事件。(当然,更有意义的名称会更好。)
无论如何,我希望这对您有所帮助还为时不晚...