当窗体没有焦点时激活 ContextMenuStrip
Activate ContextMenuStrip when the Form doesn't have focus
- 我能够在 windows 表单外成功显示 ContextMenuScript (CMS)。
- 我可以使用鼠标指针 Select/Click 个项目。
- 但是,当窗体未获得焦点时,它不喜欢键盘控制(箭头 up/down,转义)。
- 如果表单获得焦点并显示 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 - 使用 NotifyIcon
您可以使用的最简单的修复方法是使用不可见的 NotifyIcon
component as it handles this case in its internal code。
将 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 - 使用本机 Window
这里是不使用 NotifyIcon
, using NativeWindow
的修复方法。下面的一段代码关心活动的window,如果当前表单是活动的,它不使用原生的window,否则它创建并使用原生的window.
例子
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)
请记住在 closing/disposing 形式时释放 window 句柄:
If (window IsNot Nothing) Then
window.DestroyHandle()
window = Nothing
End If
- 我能够在 windows 表单外成功显示 ContextMenuScript (CMS)。
- 我可以使用鼠标指针 Select/Click 个项目。
- 但是,当窗体未获得焦点时,它不喜欢键盘控制(箭头 up/down,转义)。
- 如果表单获得焦点并显示 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 - 使用 NotifyIcon
您可以使用的最简单的修复方法是使用不可见的 NotifyIcon
component as it handles this case in its internal code。
将 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 - 使用本机 Window
这里是不使用 NotifyIcon
, using NativeWindow
的修复方法。下面的一段代码关心活动的window,如果当前表单是活动的,它不使用原生的window,否则它创建并使用原生的window.
例子
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)
请记住在 closing/disposing 形式时释放 window 句柄:
If (window IsNot Nothing) Then
window.DestroyHandle()
window = Nothing
End If