Chapter 117 · 输入系统

文本输入与 IME

使用有序输入事件统一处理普通文本、输入法组合态和提交态;示例以可重复的事件回放验证 UTF-8 与 IME 流程。

117

本章目标

完成后,你可以在一个文本控件中消费 xgeInputEventGet 的顺序事件,区分已提交文本与 IME 预编辑文本,并理解为什么一个控件不能同时消费有序事件和旧式 xgeTextGet / xgeImeEventGet。

输入模型

事件写入位置说明
XGE_EVENT_TEXT文档已转换的 Unicode 码点;示例编码为 UTF-8 后追加。
XGE_EVENT_IME_UPDATE组合态覆盖层正在候选的文本,不应直接写入文档。
XGE_EVENT_IME_COMMIT文档确认的 UTF-8 字节序列;提交后清除组合态。
XGE_EVENT_IME_END组合态覆盖层取消或完成组合;始终清除临时显示。

构建、运行与自动验证

gcc -O2 -Wall -Wextra -DXGE_DLL -DXGE_DEBUGMODE=0 -I. -o build\ch117_main1.exe examples\tutorial_capture\ch117_main1.c build\xge.lib -lm -lws2_32 -liphlpapi -lgdi32 -luser32 -lshell32 -lopengl32 -lole32 -lwinmm -lavrt

# 断言事件顺序,并在两个无人工交互的帧后退出
build\ch117_main1.exe --frames 2

# 由同一个可执行文件生成本页截图
build\ch117_main1.exe --capture tutorial\img\ch117_1.png

可观察的结果

程序首帧回放五个合成事件:TEXT('A')、IME_START、IME_UPDATE("ni")、IME_COMMIT("你好")、IME_END。它按真实输入相同的公开队列接口消费事件,只有当事件数为 5、最终文档为 A你好、组合态为空时才以成功退出。

XGE 有序输入和 IME 合成回放通过,已提交文本为 A你好,组合态已清空
图:真实运行的第 117 章示例。绿色 PASS 表示五个事件顺序消费且 UTF-8 提交结果正确;黄色区域展示提交后已清空的组合态。

核心代码:只选择一种消费模型

xge_input_event_t event;
while (xgeInputEventGet(&event) > 0) {
    switch (event.iType) {
    case XGE_EVENT_TEXT:
        append_codepoint(committed, sizeof(committed), event.iCodepoint);
        break;
    case XGE_EVENT_IME_UPDATE:
        // sText 只在下一次 xgeInputEventGet 前有效,立即复制。
        copy_utf8(composing, sizeof(composing), event.sText, event.iTextSize);
        break;
    case XGE_EVENT_IME_COMMIT:
        append_utf8(committed, event.sText, event.iTextSize);
        composing[0] = '\0';
        break;
    case XGE_EVENT_IME_END:
        composing[0] = '\0';
        break;
    }
}

完整代码

权威、可构建的完整代码位于 examples/tutorial_capture/ch117_main1.c。它包含 UTF-8 码点编码、事件回放、断言、字体加载、离屏渲染和截图;上方片段只保留输入控件最关键的消费逻辑。

代码讲解

  • 焦点管理:文本控件获得焦点时调用 xgeImeSetEnabled(1);失焦时关闭,避免无焦点控件接管系统 IME。
  • 指针生命周期:xgeInputEventGet 返回的 sText 在下一次读取事件后失效,因此不能把它直接保存为控件状态。
  • 顺序保证:有序事件 API 保留平台到达顺序。旧式 xgeTextGet 与 xgeImeEventGet 是兼容视图;同一控件只能选一种模型。
  • 自动化边界:合成回放验证引擎的队列与控件逻辑;真实系统候选窗仍需要在目标平台上进行人工 IME 冒烟测试。

练习

  1. 给 committed 文本实现 UTF-8 字素簇删除,而不是按单字节删除。
  2. 将组合态绘制在光标位置,并依据 iCursor、iSelectStart 和 iSelectEnd 显示选择范围。
  3. 为控件加入真实焦点切换,并分别验证中文、日文和韩文输入法的取消与提交。