В разделе «Замечания» для документов MSDN на TrackPopupMenuEx указано:
Чтобы отобразить контекстное меню для значка уведомления, текущее окно
должно быть передним окном перед вызовами приложения
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();