虚拟按键总结列表

在编程当中,我们会经常用到虚拟按键,然而具体的对应关系我们经常需要现查,下面将一些常用的虚拟按键总结如下:

符号常量   十六进制值  指定的鼠标或键盘按键
VK_LBUTTON   01   鼠标左键
VK_RBUTTON   02   鼠标右键
VK_CANCEL   03     Control-break 过程
VK_MBUTTON     04      鼠标中键
VK_BACK   08   BACKSPACE 键
VK_TAB    09   TAB 键
VK_CLEAR   0C   CLEAR 键
VK_RETURN   0D   ENTER 键
VK_SHIFT   10   SHIFT 键
VK_CONTROL   11   CTRL 键
VK_MENU   12   ALT 键
VK_PAUSE   13   PAUSE 键
VK_CAPITAL   14   CAPS LOCK 键
VK_ESCAPE   1B   ESC 键
VK_SPACE   20   SPACEBAR
VK_PRIOR   21   PAGE UP 键
VK_NEXT   22   PAGE DOWN 键
VK_END    23   END 键
VK_HOME   24   HOME 键
VK_LEFT   25   LEFT ARROW 键
VK_UP    26   UP ARROW 键
VK_RIGHT   27   RIGHT ARROW 键
VK_DOWN   28    DOWN ARROW 键
VK_SELECT   29   SELECT 键
VK_EXECUTE   2B   EXECUTE 键
VK_SNAPSHOT   2C  PRINT SCREEN键(用于Windows 3.0及以后版本)
VK_INSERT   2D   INS 键
VK_DELETE   2E   DEL 键
VK_HELP   2F   HELP键


/////////////////////
对于非小键盘上的数字键和字母键,直接在单引号中加入该键就行.
比如: a 键: 'A'
      1 键: '1'
/////////////////////////////////
VK_LWIN   5B   Left Windows 键 (Microsoft自然键盘)
VK_RWIN   5C   Right Windows 键 (Microsoft自然键盘)
VK_APPS   5D   Applications 键 (Microsoft自然键盘)
VK_NUMPAD0   60   数字小键盘上的 0 键
VK_NUMPAD1   61     数字小键盘上的 1 键
VK_NUMPAD2   62    数字小键盘上的 2 键
VK_NUMPAD3   63     数字小键盘上的 3 键
VK_NUMPAD4  64     数字小键盘上的 4 键
VK_NUMPAD5   65     数字小键盘上的 5 键
VK_NUMPAD6   66     数字小键盘上的 6 键
VK_NUMPAD7   67    数字小键盘上的 7 键
VK_NUMPAD8  68     数字小键盘上的 8 键
VK_NUMPAD9  69     数字小键盘上的 9 键
VK_MULTIPLY   6A     Multiply 键
VK_ADD    6B   Add键
VK_SEPARATOR   6C   Separator 键
VK_SUBTRACT   6D   Subtract 键
VK_DECIMAL   6E   Decimal 键
VK_DIVIDE   6F   Divide 键
VK_F1   70   F1 键
VK_F2   71  F2 键
VK_F3   72   F3 键
VK_F4   73   F4 键
VK_F5   74    F5 键
VK_F6    75     F6 键
VK_F7    76     F7 键
VK_F8    77     F8 键
VK_F9    78     F9 键
VK_F10    79     F10 键
VK_F11   7A     F11 键
VK_F12     7B     F12 键
VK_F13     7C     F13 键
VK_F14     7D     F14 键
VK_F15     7E     F15 键
VK_F16     7F     F16 键
VK_F17     80H     F17 键
VK_F18     81H     F18 键
VK_F19     82H     F19 键
VK_F20     83H     F20 键
VK_F21     84H     F21 键
VK_F22     85H     F22 键
VK_F23     86H     F23 键
VK_F24     87H     F24 键
VK_NUMLOCK   90     NUM LOCK 键
VK_SCROLL   91     SCROLL LOCK 键
VK_ATTN     F6     Attn 键
VK_CRSEL     F7     CrSel 键
VK_EXSEL     F8     ExSel 键
VK_EREOF   F9     Erase EOF 键
VK_PLAY   FA   Play 键
VK_ZOOM   FB     Zoom 键
VK_OEM_CLEAR   FE   Clear 键


举例说明这些键的用法:


(一)响应单独的按键:


    先添加PreTranslateMessage()(响应WM_CHAR)也是同样的效果,因为本例只捕捉键盘)
BOOL CMydilog::PreTranslateMessage(MSG* pMsg)
{
if (pMsg->message == WM_KEYDOWN)
{
         if(pMsg->wParam=='M')//直接用上面的虚码代替就可以响应所指键
MessageBox("hello");//如果按下M键弹出消息.
     }
return CDialog::PreTranslateMessage(pMsg);
}
(二)组合键的用法:(本例响应Ctrl+X键)
BOOL CMydilog::PreTranslateMessage(MSG* pMsg)
{
if (pMsg->message == WM_KEYDOWN)
{
switch (pMsg->wParam)
{
case VK_ESCAPE:
SetFocus ();
return TRUE;
case 'X':
if(::GetKeyState(VK_CONTROL) < 0
MessageBox("hello");
return TRUE;
}
}
return CDialog::PreTranslateMessage(pMsg);
}

<think>我们正在详细解析Android虚拟按键事件的分发流程。根据引用[2]和引用[4],虚拟按键是通过SystemUI中的NavigationBarFragment实现的,每个虚拟按键都对应一个keyCode,点击时模拟发送该keyCode。事件分发流程涉及系统层、框架层和应用层。以下为详细流程:###一、事件触发阶段(SystemUI层) 1. **虚拟按键布局定义**在`res/layout/navigation_bar.xml`中定义按键,通过`systemui:keyCode`属性绑定键值:```xml<com.android.systemui.navigationbar.buttons.KeyButtonViewandroid:id="@+id/back"systemui:keyCode="KEYCODE_BACK"/> <!--实际值为4 -->```2.**按键点击事件处理**在`KeyButtonView.java`中,触屏事件被转化为按键事件:```javapublicboolean onTouchEvent(MotionEvent ev) {if(ev.getAction() ==MotionEvent.ACTION_DOWN) {injectKeyEvent(KeyEvent.ACTION_DOWN);//注入按下事件}else if(ev.getAction() ==MotionEvent.ACTION_UP) {injectKeyEvent(KeyEvent.ACTION_UP);//注入抬起事件}returntrue;}private voidinjectKeyEvent(intaction){KeyEventevent =new KeyEvent(action, mKeyCode);InputManager.getInstance().injectInputEvent(event,...);}```此处通过`InputManager.injectInputEvent()`注入事件[^2][^4]。 ###二、系统服务处理阶段(InputManagerService层) 3. **权限验证与事件注入**`InputManagerService`验证`INJECT_EVENTS`权限后,将事件传递到Native层:```java// InputManagerService.javapublicboolean injectInputEvent(InputEvent event, intmode){verifyInjectionPermission(); //检查android.permission.INJECT_EVENTSreturn mNative.injectInputEvent(event, mode); //JNI调用}``` 4. **Native层事件标记**在Native层标记事件来源为虚拟设备:```cpp// com_android_server_input_InputManagerService.cppvoidNativeInputManager::injectInputEvent(...){event->initialize(...,InputDevice::VIRTUAL_KEYBOARD_ID); //deviceId=-1}```###三、输入事件分发阶段(InputDispatcher层) 5. **跳过焦点检查**InputDispatcher识别虚拟设备ID后跳过焦点窗口检查:```cpp// InputDispatcher.cppvoid InputDispatcher::dispatchKeyLocked(...){if (entry.deviceId== VIRTUAL_KEYBOARD_ID) {target= getSystemGestureTarget();//直接选择系统目标}}```6.**策略层拦截**事件优先传递到`WindowManagerPolicy`拦截系统按键:```java//PhoneWindowManager.javapublic longinterceptKeyBeforeDispatching(...){if (keyCode== KeyEvent.KEYCODE_BACK) {//处理返回键逻辑return-1; //拦截事件}return0;//继续分发}``` ###四、应用层处理阶段(View系统层)7.**DecorView首轮处理**事件到达Activity的根视图`DecorView`,尝试作为快捷键处理:```java// DecorView.javapublic booleandispatchKeyEvent(KeyEventevent){if (event.isCtrlPressed() &&...){if (super.dispatchKeyShortcutEvent(event)) returntrue;}returnsuper.dispatchKeyEvent(event);}```8.**View层级分发**事件沿View树向下传递:```java//ViewGroup.javapublicboolean dispatchKeyEvent(KeyEvent event) {if(mFocused!=null &&mFocused.dispatchKeyEvent(event)) {returntrue;//焦点View消费事件}return super.dispatchKeyEvent(event);}```###五、事件传递机制对比|**特性**|实体按键事件|虚拟按键事件| |------------------|----------------------|---------------------| |**事件来源**|物理设备驱动上报|SystemUI注入| |**设备ID**|真实设备ID(>=0)|VIRTUAL_KEYBOARD_ID(-1)| |**焦点检查**|需要|跳过| |**分发延迟**[^2] |5ms以内|20-100ms| ###六、关键设计约束1. **性能权衡**[^2]虚拟按键通过触屏事件转化实现,节省了物理按键的硬件成本,但带来额外延迟:$$\text{总延迟} =T_{touch} +T_{inject} +T_{dispatch}$$其中$T_{inject}$占主要开销(约15ms)。2.**系统级优先处理**虚拟按键事件被标记为`FLAG_FROM_SYSTEM`,确保系统策略层优先拦截:```java//KeyEvent.javaevent.setSource(InputDevice.SOURCE_KEYBOARD| FLAG_FROM_SYSTEM);``` >**流程总结**:虚拟按键事件从SystemUI触发,经特权注入绕过焦点检查,由系统策略层优先拦截,最终通过View层级分发至应用。整个流程通过设备ID标记和异步注入模式确保系统控制权[^1][^3]。§§相关问题§§1.虚拟按键事件如何避免被非焦点窗口拦截? 2.系统策略层拦截按键事件的逻辑是怎样的? 3.为什么虚拟按键比实体按键延迟更高?</think>### Android 虚拟按键事件分发流程详解 #### 一、事件生成阶段(SystemUI层) 1. **虚拟按键布局定义** 在`res/layout/navigation_bar.xml`中定义按键,通过`systemui:keyCode`属性绑定键值: ```xml <com.android.systemui.navigationbar.buttons.KeyButtonView android:id="@+id/back" systemui:keyCode="KEYCODE_BACK" /> <!-- 实际值为4 --> ``` 每个虚拟按键对应特定键值(如BACK=4,HOME=3)[^4]。 2. **触屏事件转化** 点击事件触发`KeyButtonView.onTouchEvent()`: ```java // KeyButtonView.java public boolean onTouchEvent(MotionEvent ev) { if (ev.getAction() == MotionEvent.ACTION_DOWN) { sendEvent(KeyEvent.ACTION_DOWN); // 注入按下事件 } else if (ev.getAction() == MotionEvent.ACTION_UP) { sendEvent(KeyEvent.ACTION_UP); // 注入抬起事件 } return true; } ``` 触屏事件在此转化为按键事件[^2]。 #### 二、系统服务注入阶段(InputManagerService层) 3. **特权事件注入** 通过`InputManager.injectInputEvent()`注入系统级事件: ```java // KeyButtonView.java private void sendEvent(int action) { KeyEvent event = new KeyEvent(action, mKeyCode); event.setSource(InputDevice.SOURCE_KEYBOARD); InputManager.getInstance().injectInputEvent(event, ...); } ``` 事件标记为`SOURCE_KEYBOARD`来源[^1]。 4. **Native层处理** JNI调用`NativeInputManager::injectInputEvent()`: ```cpp // com_android_server_input_InputManagerService.cpp status_t NativeInputManager::injectInputEvent(...) { event->initialize(..., InputDevice::VIRTUAL_KEYBOARD_ID); // deviceId=-1 mInputManager->getDispatcher()->injectInputEvent(...); } ``` 关键标识:`deviceId = -1`(虚拟设备)[^1]。 #### 三、输入事件分发阶段(InputDispatcher层) 5. **跳过焦点检查** InputDispatcher识别虚拟设备ID后跳过焦点窗口检查: ```cpp // InputDispatcher.cpp void InputDispatcher::dispatchKeyLocked(...) { if (entry.deviceId == VIRTUAL_KEYBOARD_ID) { target = getSystemGestureTarget(); // 直接选择系统目标 } } ``` 6. **策略层优先拦截** 事件首先传递到`WindowManagerPolicy`: ```java // PhoneWindowManager.java public long interceptKeyBeforeDispatching(...) { if (keyCode == KeyEvent.KEYCODE_HOME) { launchHome(); // HOME键直接处理 return -1; // 拦截事件 } return 0; // 允许继续分发 } ``` 系统按键(HOME/BACK等)在此被拦截[^3]。 #### 四、应用层处理阶段(View系统层) 7. **DecorView首轮处理** 事件到达Activity的根视图`DecorView`: ```java // DecorView.java public boolean dispatchKeyEvent(KeyEvent event) { // 系统快捷键优先处理 if (event.isCtrlPressed() && ...) { if (super.dispatchKeyShortcutEvent(event)) return true; } return super.dispatchKeyEvent(event); } ``` 此处处理系统级快捷键[^3]。 8. **View层级分发** 事件沿View树向下传递: ```java // ViewGroup.java public boolean dispatchKeyEvent(KeyEvent event) { if (mFocused != null && mFocused.dispatchKeyEvent(event)) { return true; // 焦点View消费事件 } return super.dispatchKeyEvent(event); } ``` #### 五、事件传递机制对比 | **特性** | 实体按键事件 | 虚拟按键事件 | |------------------|----------------------|---------------------| | **事件来源** | 物理设备驱动上报 | SystemUI注入 | | **设备ID** | 真实设备ID(>=0) | VIRTUAL_KEYBOARD_ID(-1) | | **焦点检查** | 需要 | 跳过 | | **分发延迟**[^2] | 5ms以内 | 20-100ms | | **系统拦截** | 部分按键 | 全部系统按键 | #### 六、关键设计约束 1. **性能权衡**[^2] 虚拟按键通过触屏事件转化实现,节省物理按键成本,但带来额外延迟: $$ \text{总延迟} = T_{touch} + T_{inject} + T_{dispatch} $$ 其中$T_{inject}$占主要开销(约15ms)。 2. **系统级优先处理** 虚拟按键事件被标记为`FLAG_FROM_SYSTEM`,确保: - 策略层优先拦截系统按键 - 绕过焦点窗口检查 - 防止应用层恶意拦截 > **流程本质**:虚拟按键通过`设备ID=-1`和`FLAG_FROM_SYSTEM`标识,在分发链中建立特权通道,确保系统级控制权始终优先于应用层[^1][^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值