Активируйте ContextMenuStrip, когда форма не имеет фокуса - PullRequest
0 голосов
/ 22 декабря 2018
  1. Я могу успешно отображать ContextMenuScript (CMS) вне формы Windows.
  2. Я могу выбирать / выбирать элементы с помощью указателя мыши.
  3. Однако клавиатура не нравитсяуправление (стрелка вверх / вниз, выход), когда форма не сфокусирована.
  4. Если форма сфокусирована и отображается CMS, то клавиатура может контролировать ее, но не когда она не сфокусирована: (.
  5. Iнужна помощь с кодом, который поможет достичь этого без сосредоточенности на форме.

С уважением

   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 Ответ

0 голосов
/ 23 декабря 2018

Вариант 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
...