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

基于VSTO-C#实现Word中用户输入WPM检测的技术咨询

VSTO Word插件实现按键输入WPM统计方案

一、核心事件捕获

Word对象模型提供了两个关键事件来满足需求,需在插件启动时注册:

private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
    Application.WindowBeforeKeyPress += Application_WindowBeforeKeyPress;
    Application.WindowSelectionChange += Application_WindowSelectionChange;
    // 若需区分鼠标/键盘选中文本,额外注册鼠标事件
    Application.WindowMouseUp += Application_WindowMouseUp;
}

二、排除鼠标选中文本场景

方案1:排除所有选中文本场景

维护状态变量记录当前是否存在选中文本,仅当处于插入点状态时统计输入:

private bool _hasSelectedText;

private void Application_WindowSelectionChange(Selection Sel)
{
    // wdSelectionIP表示无选中文本,仅显示插入点
    _hasSelectedText = Sel.Type != WdSelectionType.wdSelectionIP;
}

方案2:仅排除鼠标选中文本场景

若允许键盘选中(如Shift+方向键)时的输入统计,需通过鼠标事件区分选中来源:

private bool _isMouseSelectedText;

private void Application_WindowMouseUp(Selection Sel, int Button, int Shift, int X, int Y)
{
    // 鼠标松开后若存在选中文本,标记为鼠标选中
    _isMouseSelectedText = Sel.Type != WdSelectionType.wdSelectionIP;
}

private void Application_WindowSelectionChange(Selection Sel)
{
    // 键盘选中时重置鼠标选中标记
    if (Sel.Type != WdSelectionType.wdSelectionIP && !_isMouseSelectedText)
    {
        _isMouseSelectedText = false;
    }
}

三、WPM统计逻辑

核心变量定义

private int _validInputCount = 0; // 累计有效输入字符数(含空格)
private DateTime? _sessionStartTime = null;
private const int CHARS_PER_WORD = 5; // 行业通用单词字符数标准,可按需调整

按键事件处理

过滤控制键(退格、回车等),仅统计可打印字符和空格,计算WPM:

private void Application_WindowBeforeKeyPress(string Key, ref bool Cancel)
{
    // 仅处理非控制键,且满足选中文本排除条件
    if (!char.IsControl(Key[0]) && !_hasSelectedText) // 若用方案2则替换为!_isMouseSelectedText
    {
        // 初始化计时起点
        if (_sessionStartTime == null)
        {
            _sessionStartTime = DateTime.Now;
        }

        _validInputCount++;
        TimeSpan elapsed = DateTime.Now - _sessionStartTime.Value;

        // 每分钟计算一次WPM(可调整统计频率)
        if (elapsed.TotalMinutes >= 1)
        {
            double wpm = (_validInputCount / (double)CHARS_PER_WORD) / elapsed.TotalMinutes;
            // 输出或存储WPM结果,示例:写入日志/显示到插件面板
            System.Diagnostics.Debug.WriteLine($"当前WPM: {Math.Round(wpm, 2)}");
            
            // 重置计时与计数,开启新统计周期
            _sessionStartTime = DateTime.Now;
            _validInputCount = 0;
        }
    }
}

四、额外优化点

  • 跨文档处理:注册WindowActivate事件,切换文档时重置统计变量,避免跨文档累计
  • 性能优化:避免在事件处理中执行IO等耗时操作,可将统计结果异步写入存储
  • 边界处理:处理用户暂停输入超过阈值的场景(如5分钟无输入),自动重置统计会话

内容的提问来源于stack exchange,提问作者gumuruh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 06:00:08