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

求修复:按住Ctrl时持续模拟上箭头按键的Delphi代码

修复后的Delphi低级别键盘钩子代码

原代码存在语法错误、按键判断逻辑颠倒、未过滤自注入消息导致循环、输入数组未初始化等问题,最终引发按键卡住等异常。以下是修复后的完整代码:

unit HookUnit;

interface

uses
  Windows, Messages, SysUtils, Classes;

var
  kHook: HHOOK;

implementation

function LowLevelKeybdHookProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
var
  pKeyInfo: PKeybdLLHookStruct;
  InputArray: array[0..1] of TInput;
  bCtrlPressed: Boolean;
begin
  // 仅处理符合规范的钩子消息
  if nCode >= 0 then
  begin
    pKeyInfo := PKeybdLLHookStruct(lParam);
    
    // 过滤钩子自身注入的消息,避免无限循环触发
    if (pKeyInfo.flags and LLKHF_INJECTED) <> 0 then
    begin
      Result := CallNextHookEx(kHook, nCode, wParam, lParam);
      Exit;
    end;

    // 判断Ctrl键是否处于按住状态(GetKeyState高位为1表示按下)
    bCtrlPressed := (GetKeyState(VK_CONTROL) < 0);

    case wParam of
      WM_KEYDOWN, WM_SYSKEYDOWN:
        begin
          // 当Ctrl按住且当前按下的不是上箭头时,模拟Ctrl+上箭头按下
          if bCtrlPressed and (pKeyInfo.vkCode <> VK_UP) then
          begin
            // 清空输入数组,避免垃圾数据引发异常操作
            ZeroMemory(@InputArray, SizeOf(InputArray));
            
            // 发送Ctrl按下(确保状态同步)
            InputArray[0].Itype := INPUT_KEYBOARD;
            InputArray[0].ki.wVk := VK_CONTROL;
            
            // 发送上箭头按下
            InputArray[1].Itype := INPUT_KEYBOARD;
            InputArray[1].ki.wVk := VK_UP;

            SendInput(2, InputArray[0], SizeOf(TInput));
          end;
        end;

      WM_KEYUP, WM_SYSKEYUP:
        begin
          // 当Ctrl松开时,同步抬起上箭头和Ctrl键
          if (pKeyInfo.vkCode = VK_CONTROL) then
          begin
            ZeroMemory(@InputArray, SizeOf(InputArray));
            
            // 发送上箭头抬起
            InputArray[0].Itype := INPUT_KEYBOARD;
            InputArray[0].ki.wVk := VK_UP;
            InputArray[0].ki.dwFlags := KEYEVENTF_KEYUP;
            
            // 发送Ctrl抬起
            InputArray[1].Itype := INPUT_KEYBOARD;
            InputArray[1].ki.wVk := VK_CONTROL;
            InputArray[1].ki.dwFlags := KEYEVENTF_KEYUP;

            SendInput(2, InputArray[0], SizeOf(TInput));
          end;
        end;
    end;
  end;

  // 传递消息给下一个钩子
  Result := CallNextHookEx(kHook, nCode, wParam, lParam);
end;

// 安装钩子
function InstallKeyHook: Boolean;
begin
  kHook := SetWindowsHookEx(WH_KEYBOARD_LL, @LowLevelKeybdHookProc, HInstance, 0);
  Result := kHook <> 0;
end;

// 卸载钩子
procedure UninstallKeyHook;
begin
  if kHook <> 0 then
  begin
    UnhookWindowsHookEx(kHook);
    kHook := 0;
  end;
end;

initialization
  InstallKeyHook;

finalization
  UninstallKeyHook;

end.

核心修复说明

  • 语法修正:补全原代码缺失的语法结构,改用指针访问避免潜在问题
  • 按键状态判断:使用GetKeyState(VK_CONTROL) < 0正确判断Ctrl是否按住
  • 自注入消息过滤:通过LLKHF_INJECTED标志避免钩子捕获自身发送的模拟按键,防止无限循环
  • 输入数组初始化:用ZeroMemory清空数组,避免内存垃圾触发意外的鼠标/键盘事件
  • 逻辑优化:仅在Ctrl按住且未触发上箭头时模拟组合键,Ctrl松开时同步抬起所有按键,彻底解决按键卡住问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 00:10:26