You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 13:52:47