![]() |
![]() ![]() ![]() ![]() ![]() |
![]() |
Эмуляция нажатия клавиши для любого активного приложенияDelphi , ОС и Железо , Клавиши
Автор: VID { **** UBPFD *********** by delphibase.endimus.com **** >> Эмуляция нажатия клавиши Функция SendKeys этого юнита, эмулиреут нажатие клавиши для лююого активного приложения Для активизации приложения ивпользуйте функцию AppActivate Зависимости: SysUtils, Windows, messages Автор: VID, vidsnap@mail.ru, ICQ:132234868, Махачкала Copyright: Автор неизвестен Дата: 19 июня 2002 г. ***************************************************** } unit SKUnit; interface uses SysUtils, Windows, messages; function SendKeys(SendKeysString: PChar; Wait: Boolean): Boolean; function AppActivate(WindowName: PChar): boolean; const WorkBufLen = 40; var WorkBuf: array[0..WorkBufLen] of Char; implementation type THKeys = array[0..pred(MaxLongInt)] of byte; var AllocationSize: integer; (* Converts a string of characters and key names to keyboard events and passes them to Windows. Example syntax: SendKeys('abc123{left}{left}{left}def{end}456{left 6}ghi{end}789', True); *) function SendKeys(SendKeysString: PChar; Wait: Boolean): Boolean; type WBytes = array[0..pred(SizeOf(Word))] of Byte; TSendKey = record Name: ShortString; VKey: Byte; end; const {Array of keys that SendKeys recognizes. If you add to this list, you must be sure to keep it sorted alphabetically by Name because a binary search routine is used to scan it.} MaxSendKeyRecs = 41; SendKeyRecs: array[1..MaxSendKeyRecs] of TSendKey = ( (Name: 'BKSP'; VKey: VK_BACK), (Name: 'BS'; VKey: VK_BACK), (Name: 'BACKSPACE'; VKey: VK_BACK), (Name: 'BREAK'; VKey: VK_CANCEL), (Name: 'CAPSLOCK'; VKey: VK_CAPITAL), (Name: 'CLEAR'; VKey: VK_CLEAR), (Name: 'DEL'; VKey: VK_DELETE), (Name: 'DELETE'; VKey: VK_DELETE), (Name: 'DOWN'; VKey: VK_DOWN), (Name: 'END'; VKey: VK_END), (Name: 'ENTER'; VKey: VK_RETURN), (Name: 'ESC'; VKey: VK_ESCAPE), (Name: 'ESCAPE'; VKey: VK_ESCAPE), (Name: 'F1'; VKey: VK_F1), (Name: 'F10'; VKey: VK_F10), (Name: 'F11'; VKey: VK_F11), (Name: 'F12'; VKey: VK_F12), (Name: 'F13'; VKey: VK_F13), (Name: 'F14'; VKey: VK_F14), (Name: 'F15'; VKey: VK_F15), (Name: 'F16'; VKey: VK_F16), (Name: 'F2'; VKey: VK_F2), (Name: 'F3'; VKey: VK_F3), (Name: 'F4'; VKey: VK_F4), (Name: 'F5'; VKey: VK_F5), (Name: 'F6'; VKey: VK_F6), (Name: 'F7'; VKey: VK_F7), (Name: 'F8'; VKey: VK_F8), (Name: 'F9'; VKey: VK_F9), (Name: 'HELP'; VKey: VK_HELP), (Name: 'HOME'; VKey: VK_HOME), (Name: 'INS'; VKey: VK_INSERT), (Name: 'LEFT'; VKey: VK_LEFT), (Name: 'NUMLOCK'; VKey: VK_NUMLOCK), (Name: 'PGDN'; VKey: VK_NEXT), (Name: 'PGUP'; VKey: VK_PRIOR), (Name: 'PRTSC'; VKey: VK_PRINT), (Name: 'RIGHT'; VKey: VK_RIGHT), (Name: 'SCROLLLOCK'; VKey: VK_SCROLL), (Name: 'TAB'; VKey: VK_TAB), (Name: 'UP'; VKey: VK_UP) ); {Extra VK constants missing from Delphi's Windows API interface} VK_NULL = 0; VK_SemiColon = 186; VK_Equal = 187; VK_Comma = 188; VK_Minus = 189; VK_Period = 190; VK_Slash = 191; VK_BackQuote = 192; VK_LeftBracket = 219; VK_BackSlash = 220; VK_RightBracket = 221; VK_Quote = 222; VK_Last = VK_Quote; ExtendedVKeys: set of byte = [VK_Up, VK_Down, VK_Left, VK_Right, VK_Home, VK_End, VK_Prior, {PgUp} VK_Next, {PgDn} VK_Insert, VK_Delete]; const INVALIDKEY = $FFFF {Unsigned -1}; VKKEYSCANSHIFTON = $01; VKKEYSCANCTRLON = $02; VKKEYSCANALTON = $04; UNITNAME = 'SendKeys'; var UsingParens, ShiftDown, ControlDown, AltDown, FoundClose: Boolean; PosSpace: Byte; I, L: Integer; NumTimes, MKey: Word; KeyString: string[20]; procedure DisplayMessage(Message: PChar); begin MessageBox(0, Message, UNITNAME, 0); end; function BitSet(BitTable, BitMask: Byte): Boolean; begin Result := ByteBool(BitTable and BitMask); end; procedure SetBit(var BitTable: Byte; BitMask: Byte); begin BitTable := BitTable or Bitmask; end; procedure KeyboardEvent(VKey, ScanCode: Byte; Flags: Longint); var KeyboardMsg: TMsg; begin keybd_event(VKey, ScanCode, Flags, 0); if (Wait) then while (PeekMessage(KeyboardMsg, 0, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE)) do begin TranslateMessage(KeyboardMsg); DispatchMessage(KeyboardMsg); end; end; procedure SendKeyDown(VKey: Byte; NumTimes: Word; GenUpMsg: Boolean); var Cnt: Word; ScanCode: Byte; NumState: Boolean; KeyBoardState: TKeyboardState; begin if (VKey = VK_NUMLOCK) then begin NumState := ByteBool(GetKeyState(VK_NUMLOCK) and 1); GetKeyBoardState(KeyBoardState); if NumState then KeyBoardState[VK_NUMLOCK] := (KeyBoardState[VK_NUMLOCK] and not 1) else KeyBoardState[VK_NUMLOCK] := (KeyBoardState[VK_NUMLOCK] or 1); SetKeyBoardState(KeyBoardState); exit; end; ScanCode := Lo(MapVirtualKey(VKey, 0)); for Cnt := 1 to NumTimes do if (VKey in ExtendedVKeys) then begin KeyboardEvent(VKey, ScanCode, KEYEVENTF_EXTENDEDKEY); if (GenUpMsg) then KeyboardEvent(VKey, ScanCode, KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP) end else begin KeyboardEvent(VKey, ScanCode, 0); if (GenUpMsg) then KeyboardEvent(VKey, ScanCode, KEYEVENTF_KEYUP); end; end; procedure SendKeyUp(VKey: Byte); var ScanCode: Byte; begin ScanCode := Lo(MapVirtualKey(VKey, 0)); if (VKey in ExtendedVKeys) then KeyboardEvent(VKey, ScanCode, KEYEVENTF_EXTENDEDKEY and KEYEVENTF_KEYUP) else KeyboardEvent(VKey, ScanCode, KEYEVENTF_KEYUP); end; procedure SendKey(MKey: Word; NumTimes: Word; GenDownMsg: Boolean); begin if (BitSet(Hi(MKey), VKKEYSCANSHIFTON)) then SendKeyDown(VK_SHIFT, 1, False); if (BitSet(Hi(MKey), VKKEYSCANCTRLON)) then SendKeyDown(VK_CONTROL, 1, False); if (BitSet(Hi(MKey), VKKEYSCANALTON)) then SendKeyDown(VK_MENU, 1, False); SendKeyDown(Lo(MKey), NumTimes, GenDownMsg); if (BitSet(Hi(MKey), VKKEYSCANSHIFTON)) then SendKeyUp(VK_SHIFT); if (BitSet(Hi(MKey), VKKEYSCANCTRLON)) then SendKeyUp(VK_CONTROL); if (BitSet(Hi(MKey), VKKEYSCANALTON)) then SendKeyUp(VK_MENU); end; {Implements a simple binary search to locate special key name strings} function StringToVKey(KeyString: ShortString): Word; var Found, Collided: Boolean; Bottom, Top, Middle: Byte; begin Result := INVALIDKEY; Bottom := 1; Top := MaxSendKeyRecs; Found := false; Middle := (Bottom + Top) div 2; repeat Collided := ((Bottom = Middle) or (Top = Middle)); if (KeyString = SendKeyRecs[Middle].Name) then begin Found := True; Result := SendKeyRecs[Middle].VKey; end else begin if (KeyString > SendKeyRecs[Middle].Name) then Bottom := Middle else Top := Middle; Middle := (Succ(Bottom + Top)) div 2; end; until (Found or Collided); if (Result = INVALIDKEY) then DisplayMessage('Invalid Key Name'); end; procedure PopUpShiftKeys; begin if (not UsingParens) then begin if ShiftDown then SendKeyUp(VK_SHIFT); if ControlDown then SendKeyUp(VK_CONTROL); if AltDown then SendKeyUp(VK_MENU); ShiftDown := false; ControlDown := false; AltDown := false; end; end; begin AllocationSize := MaxInt; Result := false; UsingParens := false; ShiftDown := false; ControlDown := false; AltDown := false; I := 0; L := StrLen(SendKeysString); if (L > AllocationSize) then L := AllocationSize; if (L = 0) then Exit; case SendKeysString[I] of '(': begin UsingParens := True; Inc(I); end; ')': begin UsingParens := False; PopUpShiftKeys; Inc(I); end; '%': begin AltDown := True; SendKeyDown(VK_MENU, 1, False); Inc(I); end; '+': begin ShiftDown := True; SendKeyDown(VK_SHIFT, 1, False); Inc(I); end; '^': begin ControlDown := True; SendKeyDown(VK_CONTROL, 1, False); Inc(I); end; '{': begin NumTimes := 1; if (SendKeysString[Succ(I)] = '{') then begin MKey := VK_LEFTBRACKET; SetBit(Wbytes(MKey)[1], VKKEYSCANSHIFTON); SendKey(MKey, 1, True); PopUpShiftKeys; Inc(I, 3); // Continue; end; KeyString := ''; FoundClose := False; while (I <= L) do begin Inc(I); if (SendKeysString[I] = '}') then begin FoundClose := True; Inc(I); Break; end; KeyString := KeyString + Upcase(SendKeysString[I]); end; if (not FoundClose) then begin DisplayMessage('No Close'); Exit; end; if (SendKeysString[I] = '}') then begin MKey := VK_RIGHTBRACKET; SetBit(Wbytes(MKey)[1], VKKEYSCANSHIFTON); SendKey(MKey, 1, True); PopUpShiftKeys; Inc(I); // Continue; end; PosSpace := Pos(' ', KeyString); if (PosSpace <> 0) then begin NumTimes := StrToInt(Copy(KeyString, Succ(PosSpace), Length(KeyString) - PosSpace)); KeyString := Copy(KeyString, 1, Pred(PosSpace)); end; if (Length(KeyString) = 1) then MKey := vkKeyScan(KeyString[1]) else MKey := StringToVKey(KeyString); if (MKey <> INVALIDKEY) then begin SendKey(MKey, NumTimes, True); PopUpShiftKeys; // Continue; end; end; '~': begin SendKeyDown(VK_RETURN, 1, True); PopUpShiftKeys; Inc(I); end; else begin MKey := vkKeyScan(SendKeysString[I]); if (MKey <> INVALIDKEY) then begin SendKey(MKey, 1, True); PopUpShiftKeys; end else DisplayMessage('Invalid KeyName'); Inc(I); end; end; Result := true; PopUpShiftKeys; end; {AppActivate This is used to set the current input focus to a given window using its name. This is especially useful for ensuring a window is active before sending it input messages using the SendKeys function. You can specify a window's name in its entirety, or only portion of it, beginning from the left. } var WindowHandle: HWND; function EnumWindowsProc(WHandle: HWND; lParam: LPARAM): BOOL; export; stdcall; const MAX_WINDOW_NAME_LEN = 80; var WindowName: array[0..MAX_WINDOW_NAME_LEN] of char; begin {Can't test GetWindowText's return value since some windows don't have a title} GetWindowText(WHandle, WindowName, MAX_WINDOW_NAME_LEN); Result := (StrLIComp(WindowName, PChar(lParam), StrLen(PChar(lParam))) <> 0); if (not Result) then WindowHandle := WHandle; end; function AppActivate(WindowName: PChar): boolean; begin try Result := true; WindowHandle := FindWindow(nil, WindowName); if (WindowHandle = 0) then EnumWindows(@EnumWindowsProc, Integer(PChar(WindowName))); if (WindowHandle <> 0) then begin SendMessage(WindowHandle, WM_SYSCOMMAND, SC_HOTKEY, WindowHandle); SendMessage(WindowHandle, WM_SYSCOMMAND, SC_RESTORE, WindowHandle); end else Result := false; except on Exception do Result := false; end; end; end. Пример использования: SendKeys('A', False); Привет! Вот перевод текста на русский язык: Это модуль Delphi, который предоставляет две функции: Вот подробный анализ кода: SendKeys Функция Код проходит через строку ввода, обрабатывая каждый символ следующим образом:
AppActivate Функция Если окно найдено, функция отправляет два сообщения в окно: Пример использования Вы можете использовать функцию
Это симулирует нажатие клавиши 'A'. Если вы хотите ждать обработки нажатия клавиш, установите второй параметр в Аналогично, вы можете использовать функцию
Это активирует окно Notepad, если оно существует. Обратите внимание, что этот код является специфичным для Delphi и может не работать с другими языками программирования или средами. Кроме того, будьте осторожны при симулировании ввода клавиш или активации окон программно, так как это может представлять потенциальную угрозу безопасности. Эмуляция нажатия клавиши для любого активного приложения. Комментарии и вопросыПолучайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.
|
||||
©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007 |