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

如何在Windows上用Dart实现全局按键拦截与替换?

全局键盘拦截与替换实现方案(Dart/Windows)

一、可用Dart包推荐

目前pub.dev没有专门做全局键盘钩子的现成包,但可以用官方维护的win32包直接调用Windows原生API来实现——这个包封装了大部分Win32 API,完全能满足你的需求。

二、基于Win32 API的实现思路

要实现全局按键拦截+替换,核心要做的就是设置全局低级别键盘钩子,在系统处理按键前截获消息,然后拦截原按键、发送替代字符。

关键步骤:

  1. 安装win32包
    在项目的pubspec.yaml里添加依赖:

    dependencies:
      win32: ^5.0.0
    
  2. 注册全局键盘钩子
    用SetWindowsHookExW API注册WH_KEYBOARD_LL类型的钩子——这是低级别钩子,不需要注入到其他进程,实现起来更简单。

  3. 编写钩子回调函数
    在回调里判断按下的按键,如果是需要替换的:

    • 返回1,直接拦截原按键,不让它传递到其他程序;
    • 用SendInput API发送替代字符的模拟输入消息。

核心代码示例

下面是简化的实现框架,你可以根据自己的音译规则修改:

import 'dart:ffi';
import 'package:win32/win32.dart';

// 钩子回调函数
int KeyboardHookCallback(int nCode, int wParam, int lParam) {
  if (nCode >= HC_ACTION) {
    final keyInfo = PKBDLLHOOKSTRUCT(lParam);
    final vkCode = keyInfo.ref.vkCode;

    // 示例:拦截A键,替换为俄语字符Б
    if (wParam == WM_KEYDOWN && vkCode == 0x41) {
      // 发送替代字符
      final input = INPUT.allocate();
      input.ref.type = INPUT_KEYBOARD;
      input.ref.ki.wVk = 0; // 使用Unicode模式输入
      input.ref.ki.wScan = 0x0411; // Б的Unicode编码值
      input.ref.ki.dwFlags = KEYEVENTF_UNICODE;
      SendInput(1, input.addressOf, sizeOf<INPUT>());
      input.free();

      // 返回1表示已处理,拦截原按键
      return 1;
    }
  }
  // 非目标按键,交给系统后续处理
  return CallNextHookEx(NULL, nCode, wParam, lParam);
}

void main() {
  // 获取当前程序的模块句柄
  final hModule = GetModuleHandleW(nullptr);
  // 注册全局键盘钩子
  final hHook = SetWindowsHookExW(WH_KEYBOARD_LL, Pointer.fromFunction<KeyboardHookCallbackNative>(KeyboardHookCallback, 0), hModule, 0);

  // 保持消息循环,确保程序后台运行时仍能监听按键
  final msg = MSG.allocate();
  while (GetMessageW(msg.addressOf, NULL, 0, 0) != 0) {
    TranslateMessage(msg.addressOf);
    DispatchMessageW(msg.addressOf);
  }
  msg.free();

  // 退出前卸载钩子,避免内存泄漏
  UnhookWindowsHookEx(hHook);
}

// 回调函数的Native类型定义,需与Win32要求一致
typedef KeyboardHookCallbackNative = Int32 Function(Int32 nCode, Int32 wParam, IntPtr lParam);

注意事项

  • 消息循环不能中断:程序最小化后需保持运行,依赖消息循环接收钩子消息,不能随意退出。
  • Unicode输入更可靠:SendInput的KEYEVENTF_UNICODE标志可直接发送任意Unicode字符,无需依赖输入法状态,比模拟按键组合更稳定。
  • 权限匹配:如果目标程序以管理员权限运行,你的程序也需要以管理员权限启动才能生效。
  • 钩子卸载:程序退出前必须调用UnhookWindowsHookEx,避免钩子残留导致系统资源浪费。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 08:53:25