Вариант 1 - использование NotifyIcon
Самое простое исправление, которое вы можете использовать, - это использование невидимого компонента NotifyIcon
, поскольку он обрабатывает этот случай во внутреннем коде ,
Удалите экземпляр NotifyIcon
на вашей форме, а затем используйте его для отображения контекстного меню, назначьте полосу контекстного меню его свойству ContextMenuStrip
, а затем вызовите его ShowContextMenu
закрытый метод, используя отражение.
Пример
Private Sub ShowContextMenu(menu As ContextMenuStrip)
NotifyIcon1.Visible = False
NotifyIcon1.ContextMenuStrip = menu
Dim m = NotifyIcon1.GetType().GetMethod("ShowContextMenu",
Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Instance)
m.Invoke(NotifyIcon1, Nothing)
End Sub
Protected Overrides Sub WndProc(ByRef Window_Message As Message)
If Window_Message.Msg = Hot_Key Then
Dim id As IntPtr = Window_Message.WParam
Select Case (id.ToString)
Case "100"
ShowContextMenu(CMS_01)
End Select
End If
MyBase.WndProc(Window_Message)
End Sub
Вариант 2 - Использование собственного окна
А вот исправление без использования NotifyIcon
,используя NativeWindow
.Следующий фрагмент кода заботится об активном окне, и если текущая форма активна, он не использует собственное окно, в противном случае он создает и использует собственное окно.
Пример
Private window As NativeWindow
Private Sub ShowContextMenu(menu As ContextMenuStrip, p As Point)
If (Form.ActiveForm IsNot Me) Then
If (window Is Nothing) Then
window = New NativeWindow()
window.CreateHandle(New CreateParams())
End If
SetForegroundWindow(window.Handle)
End If
menu.Show(p)
End Sub
И показать меню:
ShowContextMenu(CMS_01, Cursor.Position)
Просто имейте в виду, чтобы при закрытии / утилизации формы освободить ручку окна:
If (window IsNot Nothing) Then
window.DestroyHandle()
window = Nothing
End If