我找不到与为此使用 P/Invoke 不同的解决方案。
如果它不适合该方案,则可能有另一种简单的方法。
第一个问题:拦截一个 KeyDown 事件。
KeyDown 事件处理程序在这种情况下不是很有用,因此您必须“下”并获取 WindowProc 消息。
第二个问题:让 Container 控件知道必须处理 KeyDown 事件。除了使用 PostMessage 之外找不到任何好的解决方案。
声明 dll 导入:
Imports System.Runtime.InteropServices
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function PostMessage(ByVal hWnd As IntPtr, ByVal Msg As UInteger, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Boolean
End Function
然后重写UserControl的ProcessCmdKey:
Protected Overrides Function ProcessCmdKey(ByRef msg As Message, ByVal keyData As Keys) As Boolean
'If ALT has been pressed...
If (keyData And Keys.Alt) > 0 Then
'... if another key is pressed aswell...
If (keyData Xor Keys.Alt) > 64 Then
'...pass the information to the container to see if it is interested
PostMessage(Me.ParentForm.Handle, CType(msg.Msg, UInt32), msg.WParam, msg.LParam)
Return True
End If
End If
'Not a key we are interested in
Return MyBase.ProcessCmdKey(msg, keyData)
End Function
如果您不能/不会 P/Invoke,您可能会获得类似的效果,将焦点设置为父容器中的随机控件。
因此,将 PostMessage 替换为:
Me.ParentForm.Controls(0).Focus()
但这当然会移动任何 ALT/键组合的焦点。