SDL中文论坛

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 4189|回复: 2
打印 上一主题 下一主题

[Discuss] 处理键盘(keyboard)

[复制链接]

149

主题

331

帖子

2445

积分

版主

Rank: 7Rank: 7Rank: 7

积分
2445
跳转到指定楼层
楼主
发表于 2017-9-29 20:25:48 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
一楼:键盘事件:SDL_KeyboardEvent
二楼:Rose处理键盘事件
回复

使用道具 举报

149

主题

331

帖子

2445

积分

版主

Rank: 7Rank: 7Rank: 7

积分
2445
沙发
 楼主| 发表于 2017-9-29 20:26:08 | 只看该作者

键盘事件:SDL_KeyboardEvent

本帖最后由 ancientcc 于 2017-9-29 20:27 编辑

字段名C类型说明
typeUint32键盘事件类型SDL_KEYDOWN, SDL_KEYUP
windowIDUint32键盘挂接到焦点窗口焦点窗口,0
stateUint8按键状态SDL_PRESSED,SDL_RELEASED
repeatUint8此次是否是重复触发(注1)SDL_PRESSED时,或是1或是0  SDL_RELEASED时肯定是0
keysym.scancode 此次事件涉及到的控制符
keysym.mod 此次消息之后的控制符状态(注2)
keysym.sym oem码转换来的SDL自定按键码值(注3)
keysym.unicode



1:按下一个按键时系统会触发两个消息,一个DOWN一个UP,具体到Windows是WM_KEYDOWN、WM_KEYUP。通常情况下WM_KEYDOWN、WM_KEYUP是成对出现的,但有时会出现同一个键多个WM_KEYDOWN,这时第二后或之后的WM_KEYDOWN中的repeat就会被置为1。对于如何判断repeat是什么值,有些系统有API支持,像Window上的lParam的bit30,但SDL判断repeat没使用系统API,而是借用SDL_Keyboard::keystate字段。以下是大概逻辑。
按键按下时(state = SDL_PRESSED)
  1. repeat = (state && keyboard->keystate[scancode]);
  2. keyboard->keystate[scancode] = state; // 置标志
复制代码
按键松开时(state = SDL_RELEASED)
  1. keyboard->keystate[scancode] = state; // 清标志
复制代码
2:支持的控制符
名称SDL_Keymod(mod字段)SDL自定义码(scancode字段)
数字控制键KMOD_NUMSDL_SCANCODE_NUMLOCKCLEAR
CAPSKMOD_CAPSSDL_SCANCODE_CAPS
左侧CTRLKMOD_LCTRLSDL_SCANCODE_LCTRL
右侧CTRLKMOD_RCTRLSDL_SCANCODE_RCTRL
左侧SHIFTKMOD_LSHIFTSDL_SCANCODE_LSHIFT
右侧SHIFTKMOD_RSHIFTSDL_SCANCODE_RSHIFT
左侧ALTKMOD_LALTSDL_SCANCODE_LALT
右侧ALTKMOD_RALTSDL_SCANCODE_RALT
左侧GUIKMOD_LGUISDL_SCANCODE_LGUI
右侧GUIKMOD_RGUISDL_SCANCODE_RGUI
MODEKMOD_MODESDL_SCANCODE_MODE

scancode和mod关系。scancode来自系统API,mod则根据scancode和当前控制键状态计算出的一个值。scancode、mod使用时候。
  • scancode表示“此次事件涉及到的控制符”,当希望判断此次按下/弹开涉及到哪些控制任,使用这个字段。
  • mod表示“此次消息之后的控制符状态”,当希望判断此次按下/弹开后控制符是什么状态,使用这个字段。


3:oem码如何转换到SDL自定码
说是SDL自定码,但它其实并不是SDL自定义的,它摘自http://www.usb.org/developers/devclass_docs/Hut1_12.pdf

转换操作就是通过一个数组:windows_scancode_table。组数索引就是oem码,像常见就是ascii,组就是SDL自定义码。
回复 支持 反对

使用道具 举报

149

主题

331

帖子

2445

积分

版主

Rank: 7Rank: 7Rank: 7

积分
2445
板凳
 楼主| 发表于 2017-9-29 20:26:52 | 只看该作者

Rose处理键盘事件

本帖最后由 ancientcc 于 2017-9-29 20:34 编辑

keyboard_focus_:获得键盘输入焦点的控件。

一次输入最多只能被一个控件处理。

处理键盘输入的候选控件按优级排列是1)twindow::keyboard_capture设置的控件。2)键盘链中控件。键盘链中控件没有父子关系,它的处理方法类似栈,栈底总是窗口(窗口为什么要处理键盘?收到tab键后让链盘焦点在各编辑框切换),后面的则由add_to_keyboard_chain加入(总是压向栈顶),remove_from_keyboard_chain移除。在处理按键时,先调用顶部控件,如果该控件宣称不处理该次键盘输入,那就往下传给下一个控件,否则结束此次输入处理。

原生模型中和键盘输入相关的两种事件:SDL_KEYDOWN、SDL_TEXTINPUT。为什么要分两种?SDL_KEYDOWN不仅表示键盘输入字母(注意:字母!),还包括同时接下接下控制键,像shift、ctrl、alt。SDL_TEXTINPUT则只有输入的字符/字符串信息。——这里存在个问题,输入的是字母时,是SDL_KEYDOWN还是SDL_TEXTINPUT?(看SDL 2.0.6是如何处理)。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|丽谷软件|libsdl.cn

GMT+8, 2025-5-2 04:03 , Processed in 0.045521 second(s), 22 queries .

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表