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

📄 kbsend.pas

📁 Windows屏幕键盘.rar Windows屏幕键盘.rar Windows屏幕键盘.rar
💻 PAS
字号:
unit KbSend;

interface

uses Windows;

var
  nDownShift: Integer = -1; // 之前按下的Shift
  nDownMenu: Integer = -1;  // 之前按下的Menu
  nDownCtrl: Integer = -1;  // 之前按下的Ctrl

procedure SendKey(nIndex: Integer; PtTip: PPoint);

implementation

uses Messages, MainWindow, KeyWindow, TipWindow, KbFunc, KbUsEx, Setting, ResDef;

//
// ** 前置声明 **
//
procedure SendKey_Extra(nIndex: Integer); forward;
procedure SendKey_NumPad(ScanCode: UInt); forward;
procedure SendKey_Extend(VirtualKey, ScanCode: UInt); forward;
procedure SendKey_Normal(VirtualKey, ScanCode: Word); forward;
procedure SendDown_Normal(VirtualKey, ScanCode: Word); forward;
procedure SendUp_Normal(VirtualKey, ScanCode: Word); forward;

//
// Send out the keystroke using SendInput
//
procedure SendKey(nIndex: Integer; PtTip: PPoint);
const {$J+}
  fTipShow: Bool = False; {$J-} // Tip显示中..
var
  fExtend: Bool;
  VirtualKey: UInt;
begin
  // 主窗口激活状态
  if (GetForegroundWindow() = g_hKbMainWnd) and (PtTip <> nil) then
  begin
    fTipShow := True;
    MoveTip(PtTip.x + 10, PtTip.y + 10);     // Tip位置
    ShowTip(1);                              // 显示Tip
    SetTimer(g_hKbMainWnd, 1014, 3000, nil); // 显示3秒
  end else
    if (fTipShow) then
    begin
      fTipShow := False;
      ShowTip(0);                            // 隐藏Tip
    end;

  // Make sure we are in the range(# of keys)
  if (nIndex < Low(KbKeyList)) or (nIndex > High(KbKeyList)) then Exit;

  // Extra Keys (Window Keys, App Key)
  if (lStrCmp(KbKeyList[nIndex].TextL, 'winlogoUp') = 0) or
     (lStrCmp(KbKeyList[nIndex].TextL, 'MenuKeyUp') = 0) then
  begin
    SendKey_Extra(nIndex);
    Exit;
  end;

  // extended key
  if (KbKeyList[nIndex].ScanCode[0] = $E0) then
  begin
    if (KbKeyList[nIndex].ScanCode[1] >= $47) and
       (KbKeyList[nIndex].ScanCode[1] <= $53) then
    begin
      // Incase of Arrow keys/ Home/ End keys do special procesing.
      case (KbKeyList[nIndex].ScanCode[1]) of
        $47: VirtualKey := VK_HOME;   // Home
        $48: VirtualKey := VK_UP;     // UP
        $49: VirtualKey := VK_PRIOR;  // PGUP
        $4B: VirtualKey := VK_LEFT;   // LEFT
        $4D: VirtualKey := VK_RIGHT;  // RIGHT
        $4F: VirtualKey := VK_END;    // END
        $50: VirtualKey := VK_DOWN;   // DOWN
        $51: VirtualKey := VK_NEXT;   // PGDOWN
        $52: VirtualKey := VK_INSERT; // INS
        $53: VirtualKey := VK_DELETE; // DEL
        else Exit;
      end;

      // Do the processing here itself
      SendKey_Extend(VirtualKey, KbKeyList[nIndex].ScanCode[1]);
      Exit;
    end;

    VirtualKey := MapVirtualKey(KbkeyList[nIndex].ScanCode[1], 1);
    fExtend := True;
  end else
    if (KbKeyList[nIndex].ScanCode[0] >= $47) and (KbKeyList[nIndex].ScanCode[0] <= $53) then // NumPad
    begin
      SendKey_NumPad(KbKeyList[nIndex].ScanCode[0]);
      Exit;
    end else // other keys
    begin
      VirtualKey := MapVirtualKey(KbKeyList[nIndex].ScanCode[0], 1);
      fExtend := False;
    end;

  case (KbKeyList[nIndex].Name) of
    KB_PSC:
    begin
      SendKey_Normal(VK_SNAPSHOT, 0);
    end;

    KB_LCTR, KB_RCTR:
    begin
      if (nDownCtrl = -1) then  // 按下
      begin
        SendDown_Normal(VK_CONTROL, KbKeyList[nIndex].ScanCode[0]);

        SetKeyLong(nIndex, 2);
        nDownCtrl := nIndex;
      end else                  // 抬起
      begin
        SendUp_Normal(VK_CONTROL, KbKeyList[nIndex].ScanCode[0]);

        SetKeyLong(nDownCtrl, 0);
        nDownCtrl := -1;
      end;
    end;

    KB_LSHIFT, KB_RSHIFT:
    begin
      if (nDownShift = -1) then // 按下
      begin
        SendDown_Normal(VK_SHIFT, KbKeyList[nIndex].ScanCode[0]);

        SetKeyLong(nIndex, 2);
        nDownShift := nIndex;
      end else                  // 抬起
      begin
        SendUp_Normal(VK_SHIFT, KbKeyList[nIndex].ScanCode[0]);

        SetKeyLong(nDownShift, 0);
        nDownShift := -1;
      end;
      RedrawKeys();
    end;

    KB_LALT, KB_RALT:
    begin
      if (nDownMenu = -1) then // 按下
      begin
        SendDown_Normal(VK_MENU, $38);

        SetKeyLong(nIndex, 2);
        nDownMenu := nIndex;
      end else
      begin                    // 抬起
        SendUp_Normal(VK_MENU, $38);

        SetKeyLong(nDownMenu, 0);
        nDownMenu := -1;
      end;
      RedrawKeys();
    end;

    KB_CAPLOCK:
    begin
      if (GetKeyState(VK_CAPITAL) and $0001 = 0) then SetKeyLong(nIndex, 2) else SetKeyLong(nIndex, 0);
      SendKey_Normal(VirtualKey, KbKeyList[nIndex].ScanCode[0]);
      RedrawKeys();
    end;

    KB_NUMLOCK:
    begin
      if (GetKeyState(VK_NUMLOCK) and $0001 = 0) then SetKeyLong(nIndex, 2) else SetKeyLong(nIndex, 0);
      SendKey_Normal(VK_NUMLOCK, $45);
      RedrawKeys();
    end;

    KB_SCROLL:
    begin
      if (GetKeyState(VK_SCROLL) and $0001 = 0) then SetKeyLong(nIndex, 2) else SetKeyLong(nIndex, 0);
      SendKey_Normal(VK_SCROLL, $46);
    end;

    else begin
      if (fExtend) then
        SendKey_Extend(VirtualKey, KbKeyList[nIndex].ScanCode[1])
      else
        // MapVirtualKey returns 0 for 'Break' key. Special case for 'Break'.
        if (VirtualKey = 0) and (KbKeyList[nIndex].ScanCode[0] = $E1) then
          if (GetAsyncKeyState(VK_CONTROL) and $8000 <> 0) then
            SendKey_Normal(03, KBkeyList[nIndex].ScanCode[2])
          else
            SendKey_Normal(19, KBkeyList[nIndex].ScanCode[0])
        else
          SendKey_Normal(VirtualKey, KbkeyList[nIndex].ScanCode[0]);
    end;
  end; // case (KbKey[nIndex].Name) of ..
end;

//
// Win键 & 菜单键
//
procedure SendKey_Extra(nIndex: Integer);
var
  ScanCode, VirtualKey: UInt;
begin
  if (lStrCmp(KbKeyList[nIndex].SkCap, 'App') = 0) then // App Key
  begin
    ScanCode := MapVirtualKey(VK_APPS, 0);
    VirtualKey := VK_APPS;
  end else
    if (lStrCmp(KbKeyList[nIndex].skCap, 'lwin') = 0) then // Left Window Key Down
    begin
      ScanCode := MapVirtualKey(VK_LWIN, 0);
      VirtualKey := VK_LWIN;
    end else
      if (lStrCmp(KbKeyList[nIndex].skCap, 'rwin') = 0) then // Right Window Key Down
      begin
        ScanCode := MapVirtualKey(VK_RWIN, 0);
        VirtualKey := VK_RWIN;
      end else
        Exit;

  SendKey_Extend(VirtualKey, ScanCode);
end;

//
// NumPad key down & up (数字小键盘)
//
procedure SendKey_NumPad(ScanCode: UInt);
var
  NumLock: Bool;
begin
  NumLock := (GetKeyState(VK_NUMLOCK) and $0001 = 1);

  case (ScanCode) of
    $47: if NumLock then SendKey_Normal(VK_NUMPAD7, ScanCode) else SendKey_Normal(VK_HOME, ScanCode);
    $48: if NumLock then SendKey_Normal(VK_NUMPAD8, ScanCode) else SendKey_Normal(VK_UP, ScanCode);
    $49: if NumLock then SendKey_Normal(VK_NUMPAD9, ScanCode) else SendKey_Normal(VK_PRIOR, ScanCode);
    $4A: SendKey_Normal(VK_SUBTRACT, ScanCode);
    $4B: if NumLock then SendKey_Normal(VK_NUMPAD4, ScanCode) else SendKey_Normal(VK_LEFT, ScanCode);
    $4C: if NumLock then SendKey_Normal(VK_NUMPAD5, ScanCode);
    $4D: if NumLock then SendKey_Normal(VK_NUMPAD6, ScanCode) else SendKey_Normal(VK_RIGHT, ScanCode);
    $4E: SendKey_Normal(VK_ADD, ScanCode);
    $4F: if NumLock then SendKey_Normal(VK_NUMPAD1, ScanCode) else SendKey_Normal(VK_END, ScanCode);
    $50: if NumLock then SendKey_Normal(VK_NUMPAD2, ScanCode) else SendKey_Normal(VK_DOWN, ScanCode);
    $51: if NumLock then SendKey_Normal(VK_NUMPAD3, ScanCode) else SendKey_Normal(VK_NEXT, ScanCode);
    $52: if NumLock then SendKey_Normal(VK_NUMPAD0, ScanCode) else SendKey_Normal(VK_INSERT, ScanCode);
    $53: if NumLock then SendKey_Normal(VK_DECIMAL, ScanCode) else SendKey_Normal(VK_DELETE, ScanCode);
  end;
end;

//
// Extend key down & up
//
procedure SendKey_Extend(VirtualKey, ScanCode: UInt);
var
  rgInput: array[0..1] of TInput;
begin
  // extend key down
  rgInput[0].iType := INPUT_KEYBOARD;
  rgInput[0].ki.time := 0;
  rgInput[0].ki.dwFlags := KEYEVENTF_EXTENDEDKEY;
  rgInput[0].ki.dwExtraInfo := 66;
  rgInput[0].ki.wVk := VirtualKey;
  rgInput[0].ki.wScan := ScanCode;

  // extend key up
  rgInput[1].iType := INPUT_KEYBOARD;
  rgInput[1].ki.time := 0;
  rgInput[1].ki.dwFlags := KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP;
  rgInput[1].ki.dwExtraInfo := 66;
  rgInput[1].ki.wVk := VirtualKey;
  rgInput[1].ki.wScan := ScanCode;

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

//
// Normal key down & up
//
procedure SendKey_Normal(VirtualKey, ScanCode: Word);
var
  rgInput: array[0..1] of TInput;
begin
  // Normal key down
  rgInput[0].iType := INPUT_KEYBOARD;
  rgInput[0].ki.time := 0;
  rgInput[0].ki.dwFlags := 0;
  rgInput[0].ki.dwExtraInfo := 66;
  rgInput[0].ki.wVk := VirtualKey;
  rgInput[0].ki.wScan := ScanCode;

  // Normal key up
  rgInput[1].iType := INPUT_KEYBOARD;
  rgInput[1].ki.time := 0;
  rgInput[1].ki.dwFlags := KEYEVENTF_KEYUP;
  rgInput[1].ki.dwExtraInfo := 66;
  rgInput[1].ki.wVk := VirtualKey;
  rgInput[1].ki.wScan := ScanCode;

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

//
// Normal key down
//
procedure SendDown_Normal(VirtualKey, ScanCode: Word);
var
  rgInput: TInput;
begin
  rgInput.iType := INPUT_KEYBOARD;
  rgInput.ki.time := 0;
  rgInput.ki.dwFlags := 0;
  rgInput.ki.dwExtraInfo := 66;
  rgInput.ki.wVk := VirtualKey;
  rgInput.ki.wScan := ScanCode;

  SendInput(1, rgInput, SizeOf(TInput));
end;

//
// Normal key down
//
procedure SendUp_Normal(VirtualKey, ScanCode: Word);
var
  rgInput: TInput;
begin
  rgInput.iType := INPUT_KEYBOARD;
  rgInput.ki.time := 0;
  rgInput.ki.dwFlags := KEYEVENTF_KEYUP;
  rgInput.ki.dwExtraInfo := 66;
  rgInput.ki.wVk := VirtualKey;
  rgInput.ki.wScan := ScanCode;

  SendInput(1, rgInput, SizeOf(TInput));
end;

end.

⌨️ 快捷键说明

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