Delphi Alexandria 11.3中TouchKeyboard是否存在Bug?
TouchKeyboard 修饰键重复触发异常的解决办法
问题复现
- 拖放
TouchKeyboard到窗体运行,操作流程:左Shift点击(按下松开)→右Shift点击,状态正常;但第三次点击右Shift后,输入字母始终小写(肉眼可见瞬间大写又回落,疑似一次点击触发两次状态切换) - 通用异常场景:先点击一侧修饰键(Shift/Ctrl/Alt)激活,再点击另一侧同类型修饰键关闭,后续再点击同类型任意修饰键,都会出现状态异常
问题原因
这是TouchKeyboard组件的成对修饰键状态同步逻辑bug——当通过对侧修饰键关闭激活状态时,组件内部的状态标记没有正确重置,导致后续点击时触发了重复的状态翻转(相当于一次点击同时执行了按下和松开操作)。
修复方案
1. 自定义修饰键状态管理,绕过组件默认逻辑
给TouchKeyboard绑定自定义的按键点击事件,自己维护修饰键的激活状态:
// 示例:维护自定义的Shift状态 private bool _isShiftActive = false; private void TouchKeyboard_KeyClicked(object sender, KeyClickedEventArgs e) { if (e.Key == Keys.ShiftKey || e.Key == Keys.RShiftKey) { _isShiftActive = !_isShiftActive; // 手动模拟系统按键状态 keybd_event((byte)Keys.ShiftKey, 0, _isShiftActive ? 0 : 2, 0); // 阻止组件默认处理逻辑 e.Handled = true; } }
完全脱离组件内部的状态管理,直接控制系统的按键状态,避免同步bug。
2. 强制重置组件内部状态(如果可访问)
如果能找到TouchKeyboard内部存储修饰键状态的字段(比如_shiftPressed之类的私有字段),可以在关闭修饰键后强制重置:
// 示例:通过反射重置Shift状态 var shiftField = typeof(TouchKeyboard).GetField("_shiftPressed", BindingFlags.NonPublic | BindingFlags.Instance); if (shiftField != null) { shiftField.SetValue(touchKeyboard1, false); }
注意:这种方法依赖组件内部实现,后续组件更新可能失效。
3. 替换第三方虚拟键盘组件
如果上述方法都不稳定,建议更换成熟的第三方虚拟键盘组件,或者自己实现轻量的虚拟键盘逻辑,避免依赖有bug的内置组件。
内容的提问来源于stack exchange,提问作者Branko Sretenovic
相关产品推荐
相关产品推荐

