根据另一个问题的this answer,只有在调用Show()
之前将ContextMenu的事件与控件相关联,才会引发ContextMenu的Collapsed
事件。在与NotifyIcon关联时检查ContextMenu的可见性
如果一个NotifyIcon
不算作控件,我无法挂接到Collapsed
事件来检测与其中一个菜单相关的菜单是否隐藏。
是否有任何解决方法?
根据另一个问题的this answer,只有在调用Show()
之前将ContextMenu的事件与控件相关联,才会引发ContextMenu的Collapsed
事件。在与NotifyIcon关联时检查ContextMenu的可见性
如果一个NotifyIcon
不算作控件,我无法挂接到Collapsed
事件来检测与其中一个菜单相关的菜单是否隐藏。
是否有任何解决方法?
对TrackPopupMenuEx MSDN文档“备注”部分下,它说:
要显示通知图标上下文菜单,当前窗口 必须在前台窗口中应用程序调用 前TrackPopupMenu或TrackPopupMenuEx。否则,当用户单击菜单外部或 创建菜单(如果它是可见的)的窗口时,菜单不会 消失。如果当前窗口是子窗口 ,则必须将(顶层)父窗口设置为前景 窗口。
所以这可能意味着,当ContextMenu
是可见的,在NotifyIcon
窗口将在前台窗口。您可以通过查看NotifyIcon.ShowContextMenu()
看到它确实是这样的:
private void ShowContextMenu()
{
if (this.contextMenu != null || this.contextMenuStrip != null)
{
NativeMethods.POINT pOINT = new NativeMethods.POINT();
UnsafeNativeMethods.GetCursorPos(pOINT);
UnsafeNativeMethods.SetForegroundWindow(new HandleRef(this.window, this.window.Handle));
if (this.contextMenu != null)
{
this.contextMenu.OnPopup(EventArgs.Empty);
SafeNativeMethods.TrackPopupMenuEx(new HandleRef(this.contextMenu, this.contextMenu.Handle), 72, pOINT.x, pOINT.y, new HandleRef(this.window, this.window.Handle), null);
UnsafeNativeMethods.PostMessage(new HandleRef(this.window, this.window.Handle), 0, IntPtr.Zero, IntPtr.Zero);
return;
}
if (this.contextMenuStrip != null)
{
this.contextMenuStrip.ShowInTaskbar(pOINT.x, pOINT.y);
}
}
}
使用ILSpy后来我发现NotifyIcon
有一个私有成员window
,这是指私人类基本类型NativeWindow
。因此,你可以检查这样的:
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr GetForegroundWindow();
...
FieldInfo notifyIconNativeWindowInfo = typeof(NotifyIcon).GetField("window", BindingFlags.NonPublic | BindingFlags.Instance);
NativeWindow notifyIconNativeWindow = (NativeWindow)notifyIconNativeWindowInfo.GetValue(notifyIcon1);
bool visible = notifyIcon1.Handle == GetForegroundWindow();
的[调用的NotifyIcon的上下文菜单(http://stackoverflow.com/questions/2208690/invoke-notifyicons-context-menu) –
问题是问如何可能重复检查ContextMenu的可见性,而不是如何显示它。 – unrelativity