向VFP窗口快速输入整串字符串替代逐字符输入的实现方案
向VFP窗口快速输入字符串的优化方案
最小改动:现有代码优化
现有代码的性能损耗主要来自两个可优化点:
- 循环内重复实例化
KeysConverter,每次字符转换都产生不必要的开销 - 每个字符强制等待10ms,是耗时占比最高的部分
优化后代码如下,仅需调整少量逻辑就能提升3~10倍的处理速度:
IntPtr hw = win32.FindWindow(null, deffensterTitel); // 转换器实例移到循环外,仅初始化一次 var keyConverter = new System.Windows.Forms.KeysConverter(); foreach (char c in stringToBeSent.ToCharArray()) { System.Windows.Forms.Keys key = (System.Windows.Forms.Keys)keyConverter.ConvertFromString(c.ToString()); // 仅当目标窗口响应速度极慢时保留短等待,可根据实际场景调整到1~2ms,或直接删除 // System.Threading.Thread.Sleep(1); win32.SendKey(key, hw, false); }
性能最优:直接发送WM_SETTEXT消息
不需要模拟按键,直接把字符串赋值给目标输入框,整体耗时几乎可以忽略,是首选的替换方案:
注意:需要先获取目标输入框的子窗口句柄,而非主窗口句柄,可通过
FindWindowEx、EnumChildWindows枚举主窗口的子控件定位,也可借助Spy++工具先确认目标输入框的类名、控件ID等属性。如果不方便获取类名,可先通过模拟点击或者发送WM_SETFOCUS消息把焦点切到目标输入框,再调用GetFocus()获取当前焦点的句柄作为输入框句柄。
代码示例:
// 首先定义Win32 API常量和函数 private const uint WM_SETTEXT = 0x000C; [DllImport("user32.dll", CharSet = CharSet.Unicode)] private static extern IntPtr SendMessageW(IntPtr hWnd, uint Msg, IntPtr wParam, string lParam); [DllImport("user32.dll", CharSet = CharSet.Unicode)] private static extern IntPtr FindWindowEx(IntPtr hWndParent, IntPtr hWndChildAfter, string lpszClass, string lpszWindow); [DllImport("user32.dll")] private static extern IntPtr GetFocus(); // 调用逻辑 IntPtr mainHwnd = win32.FindWindow(null, deffensterTitel); // 先把焦点切到目标输入框(此处可替换为你自己的聚焦逻辑) SetForegroundWindow(mainHwnd); // 模拟Tab切到输入框/或者模拟点击输入框区域,之后获取当前焦点句柄 IntPtr editHwnd = GetFocus(); // 直接发送完整文本 SendMessageW(editHwnd, WM_SETTEXT, IntPtr.Zero, stringToBeSent);
特殊场景适配:如果目标VFP输入框绑定了输入校验、TextChanged等事件,WM_SETTEXT默认不会触发这些事件,可在发送完文本后补发一个
WM_KEYDOWN+WM_KEYUP的普通按键消息,即可触发对应事件。
高兼容方案:批量SendInput模拟输入
如果目标是VFP的表格单元格、自定义控件等不好定位输入框句柄的场景,可使用SendInput批量提交按键事件,比逐个调用SendKey快5倍以上,且不需要每个字符加等待。该方案完全模拟真实键盘输入,会触发所有绑定的输入事件,兼容性最好,不需要额外适配事件逻辑。
内容的提问来源于stack exchange,提问作者Zelforacle
相关产品推荐
相关产品推荐

