Активируйте ContextMenuStrip, когда форма не имеет фокуса
- Я могу успешно отображать ContextMenuScript (CMS) вне формы Windows.
- Я могу выбрать / щелкнуть элементы, используя указатель мыши.
- Однако ему не нравится управление с клавиатуры (стрелка вверх / вниз, выход), когда форма не сфокусирована.
- Если форма сфокусирована и CMS показала, то клавиатура может управлять ею, но не тогда, когда она не сфокусирована:(.
- Мне нужна помощь с кодом, который поможет достичь этого без сосредоточенности формы.
С уважением
Public Const CTRL_Key As Integer = &H2
Public Const Hot_Key As Integer = &H312
Public Declare Function RegisterHotKey Lib "user32" (ByVal hwnd As IntPtr, ByVal id As Integer, ByVal fsModifiers As Integer, ByVal vk As Integer) As Integer
Public Declare Function UnregisterHotKey Lib "user32" (ByVal hwnd As IntPtr, ByVal id As Integer) As Integer
Private Sub Hot_Key_Register() Handles MyBase.Load
RegisterHotKey(Me.Handle, 100, CTRL_Key, Keys.NumPad1)
RegisterHotKey(Me.Handle, 200, CTRL_Key, Keys.NumPad2)
RegisterHotKey(Me.Handle, 300, CTRL_Key, Keys.NumPad3)
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"
CMS_01.Show(Cursor.Position.X, Cursor.Position.Y)
Case "200"
CMS_02.Show(Cursor.Position.X, Cursor.Position.Y)
Case "300"
CMS_03.Show(Cursor.Position.X, Cursor.Position.Y)
End Select
End If
MyBase.WndProc(Window_Message)
End Sub
1 ответ
Вариант 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