基于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
相关产品推荐
相关产品推荐

