Проверка видимости ContextMenu при связывании с NotifyIcon - PullRequest
0 голосов
/ 07 ноября 2011

Согласно этому ответу на другой вопрос, событие Collapsed ContextMenu вызывается, только если оно связано с элементом управления перед вызовом Show().

Поскольку NotifyIcon не считается элементом управления, я не могу подключиться к событию Collapsed, чтобы определить, скрыто ли связанное с ним меню.

Есть ли обходные пути?

1 Ответ

0 голосов
/ 07 ноября 2011

В разделе «Замечания» для документов 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();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...