⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sendkey.pas

📁 这一系列是我平时收集的pascal深入核心编程
💻 PAS
📖 第 1 页 / 共 2 页
字号:
         // 此键值将会导致向hwndQueueSyncTarget'回放'WM_QUEUESYNC消息
          if (g_SKD.nMaxVirtKeys = High(g_SKD.asVirtKeys) + 1) then
          begin
            Result := SKERR_STRINGTOOLONG;
            Exit;
          end else
          begin
            g_SKD.asVirtKeys[g_SKD.nMaxVirtKeys] := Byte(VK_QUEUESYNC);
            Inc(g_SKD.nMaxVirtKeys);
          end;
        end else
          goto Other;
      end;

    else // 普通按键
      begin
       // 并非由上一分支跳入
Other:  if (cChar <> '{') then
        begin
          sVirtKey := VkKeyScan(cChar);
        end;

       // 按下Shift
        if (HiByte(sVirtKey) and 1) <> 0 then
        begin
          if (g_SKD.nMaxVirtKeys = High(g_SKD.asVirtKeys) + 1) then
          begin
            Result := SKERR_STRINGTOOLONG;
            Exit;
          end else
          begin
            g_SKD.asVirtKeys[g_SKD.nMaxVirtKeys] := Byte(VK_SHIFT);
            Inc(g_SKD.nMaxVirtKeys);
          end;
        end;

       // 添加按键
        while (nCount > 0) do
        begin
          Dec(nCount);

          if (g_SKD.nMaxVirtKeys = High(g_SKD.asVirtKeys) + 1) then
          begin
            Result := SKERR_STRINGTOOLONG;
            Exit;
          end else
          begin
            g_SKD.asVirtKeys[g_SKD.nMaxVirtKeys] := Byte(LOBYTE(sVirtKey));
            Inc(g_SKD.nMaxVirtKeys);
          end;
        end;

       // 放开Shift
        if (HiByte(sVirtKey) and 1) <> 0 then
        begin
          if (g_SKD.nMaxVirtKeys = High(g_SKD.asVirtKeys) + 1) then
          begin
            Result := SKERR_STRINGTOOLONG;
            Exit;
          end else
          begin
            g_SKD.asVirtKeys[g_SKD.nMaxVirtKeys] := Byte(LOBYTE(VK_SHIFT));
            Inc(g_SKD.nMaxVirtKeys);
          end;
        end;
      end;
  end; // END: case (cChar) of 
end;

 // 字符串 -> 虚拟键值表
function SendKeys_InitPreprocessKeys(pszPassedKeys: PChar): TSKErr; stdcall;
begin
  g_SKD.nMaxVirtKeys := 0;
  g_SKD.nVirtKeyNum := 0;
  g_SKD.pszKeys := pszPassedKeys;
  Result := SKERR_NOERROR;

 // 转入虚拟键值表
  while (g_SKD.pszKeys^ <> #0) do
  begin
    Result := SendKeys_PreprocessKeys();
    if (Result <> SKERR_NOERROR) then Break;
  end;
end;

 // 取下一个要回放的按键
function SendKeys_GetToken(psVirtKey: PSmallint; pfPressDown, pfSysKey: PBOOL): BOOL;
const
{$J+}
  sVirtKey: SHORT = 0;
  fKeyIsDown: BOOL = FALSE;
  fKeyPressWhileAltDown: BOOL = FALSE;
  fShiftDown: BOOL = FALSE;
  fControlDown: BOOL = FALSE;
  fAltDown: BOOL = FALSE;
{$J-}
begin
 // 初始化
  if (psVirtKey = nil) then
  begin
    sVirtKey := 0;
    fKeyIsDown := FALSE;
    fShiftDown := FALSE;
    fControlDown := FALSE;
    fAltDown := FALSE;
    g_SKD.nVirtKeyNum := 0;

    Result := TRUE;
    Exit;
  end;

 // 确定不是功能键
  if (sVirtKey <> VK_SHIFT) and (sVirtKey <> VK_CONTROL) and (sVirtKey <> VK_MENU) then
  begin
   // 如果上次重放的键是按下, 现在则抬起
    if (sVirtKey <> 0) and (fKeyIsDown) then
    begin
      psVirtKey^ := sVirtKey; // 键值相同
      sVirtKey := 0;
      pfPressDown^ := FALSE; // 释放按键
      pfSysKey^ := fAltDown and not fControlDown; // Is it a SYS key?
      fKeyPressWhileAltDown := TRUE;

      Result := TRUE;
      Exit;
    end;
  end;

 // 回放完毕
  if (g_SKD.nVirtKeyNum = g_SKD.nMaxVirtKeys) then
  begin
    Result := FALSE;
    Exit;
  end;

 // 当前按键
  psVirtKey^ := g_SKD.asVirtKeys[g_SKD.nVirtKeyNum];
  Inc(g_SKD.nVirtKeyNum);
  sVirtKey := psVirtKey^;

  case (sVirtKey) of
    VK_SHIFT:
      begin
        fShiftDown := not fShiftDown;
        pfPressDown^ := fShiftDown;
      end;

    VK_CONTROL:
      begin
        fControlDown := not fControlDown;
        pfPressDown^ := fControlDown;
      end;

    VK_MENU:
      begin
        fAltDown := not fAltDown;
        pfPressDown^ := fAltDown;

        if (fAltDown) then
          fKeyPressWhileAltDown := FALSE;
      end;

    VK_QUEUESYNC:
      begin
        sVirtKey := 0;
      end;

    else
      begin
        pfPressDown^ := TRUE;
        fKeyIsDown := TRUE;
        fKeyPressWhileAltDown := TRUE;
      end;
  end;

 // 是否系统按键
  if (sVirtKey = VK_MENU) and (not fAltDown) then
    pfSysKey^ := not fKeyPressWhileAltDown and not fControlDown
  else
    pfSysKey^ := fAltDown and not fControlDown;

  Result := TRUE;
end;

 // 回放钩子回调函数
function SendKeys_JrnlPlayBackHook(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
const
{$J+}
  sVirtKey: SHORT = 0;
  fKeyDown: BOOL = FALSE;
  fSysKey: BOOL = FALSE;
{$J-}
var
  pEvent: PEventMsg;
begin
 // 安装钩子后首次调用
  if (g_SKD.fNoTokensRetrievedYet) then
  begin
    SendKeys_GetToken(@sVirtKey, @fKeyDown, @fSysKey);
    g_SKD.fNoTokensRetrievedYet := FALSE;
  end;

  case (nCode) of
    HC_SKIP:
      begin
       // 取出下一个按键准备回放
        if (SendKeys_GetToken(@sVirtKey, @fKeyDown, @fSysKey) = FALSE) then
        begin
         // 播放完毕则卸载钩子
          UnhookWindowsHookEx(g_SKD.hhook);
          g_SKD.hhook := 0;
        end;
      end;

    HC_GETNEXT:
      begin
       // 拷贝按键消息至PEventMsg处
        pEvent := PEventMsg(lParam);
        pEvent.time := GetTickCount();
        if (sVirtKey = VK_QUEUESYNC) then
        begin
          PostMessage(g_SKD.hwndQueueSyncTarget, WM_QUEUESYNC, 0, 0);
          pEvent.hwnd := g_SKD.hwndQueueSyncTarget;
          pEvent.message := WM_QUEUESYNC;
          pEvent.paramL := 0;
          pEvent.paramH := 0;
        end else
        begin
          if (fSysKey = FALSE) then
          begin
            if fKeyDown then
              pEvent.message := WM_KEYDOWN
            else
              pEvent.message := WM_KEYUP;
          end else
          begin
            if fKeyDown then
              pEvent.message := WM_SYSKEYDOWN
            else
              pEvent.message := WM_SYSKEYUP;
          end;
         // 虚拟键
          pEvent.paramL := sVirtKey;
         // 扫描码
          pEvent.paramH := MapVirtualKey(sVirtKey, 0);
        end;
      end;
  end;

 // 立刻处理
  Result := 0;
end;

  // 发送一系列按键
function SendKeys(hWndQueueSyncTarget: HWND; pszKeys: PChar): TSKErr; stdcall;
var
  abKeyState: TKeyboardState;
begin
 // 转成虚拟键列表
  Result := SendKeys_InitPreprocessKeys(pszKeys);
  if (Result <> SKERR_NOERROR) then Exit;

 // 初始化
  SendKeys_GetToken(nil, nil, nil);
  g_SKD.fNoTokensRetrievedYet := TRUE;
  g_SKD.hwndQueueSyncTarget := hwndQueueSyncTarget;

 // 安装钩子
  g_SKD.hhook := SetWindowsHookEx(WH_JOURNALPLAYBACK, @SendKeys_JrnlPlayBackHook, HInstance, 0);
  if (g_SKD.hhook = 0) then
  begin
    Result := SKERR_CANTINSTALLHOOK;
    Exit;
  end;

 // 抬起按键
  GetKeyboardState(abKeyState);
  abKeyState[VK_CONTROL] := abKeyState[VK_CONTROL] and $7f;
  abKeyState[VK_MENU] := abKeyState[VK_MENU] and $7f;
  abKeyState[VK_SHIFT] := abKeyState[VK_SHIFT] and $7f;
  abKeyState[VK_CAPITAL] := abKeyState[VK_CAPITAL] and $7e;
  abKeyState[VK_NUMLOCK] := abKeyState[VK_NUMLOCK] and $7e;
  SetKeyboardState(abKeyState);

 // 返回成功 
  Result := SKERR_NOERROR;
end;

end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -