|
#1
|
|||
|
|||
Эмуляция Ctrl+V
Добрый день.
Вопрос у меня на первый взгляд глупый, но вот ответить на него своими силами у меня не выходит. Возникло у меня желание написать небольшую утилиту для всем известной World of Tanks, которая при нажатии на определенные кнопки будет отсылать в чат заранее заготовленные сообщения - ну не хватает мне стандартных, а решить задачу хочется именно на Delphi. Суть возникшей проблемы - не получается вставить текст из буфера. Испробовал все: WM_PASTE, keybd_event и SendInput. Сочетание Ctrl+V передается только в последнем случае и только при соблюдении условий: 1. Клавиша Ctrl используется как модификатор для вызова вставки. 2. На момент вставки текста Ctrl еще нажат. В то же время для всех остальных программ (блокнот, браузер, IDE и т.д.) все прекрасно срабатывает. Как говорил один умный осел - "Кувшин моих мыслей показывает дно..." Выручайте. |
#2
|
||||
|
||||
Цитата:
Код:
procedure CtrlV; begin keybd_event(VK_CONTROL, 0, KEYEVENTF_EXTENDEDKEY, 0); keybd_event(86, 0, KEYEVENTF_EXTENDEDKEY, 0); keybd_event(VK_CONTROL, 0, KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP, 0); keybd_event(86, 0, KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP, 0); end; Я не понял Вашего вопроса, но всё же Вам на него отвечу! |
#3
|
|||
|
|||
Цитата:
С отсылкой клавиатурных сообщений как таковых проблем нет вообще - игра их распознают и реагирует должным образом. При этом не важно - использую я PostMessage, keybd_event или SendInput. Проблема возникает при попытке передать сочетание клавиш. Я точно знаю, что есть программы, способные на это, да и стандартная экранная клавиатура прекрасно справляется. Вот сообщения, которые шлет в WoT одна из таких программ: Код:
<00004> 006310B4 S WM_DRAWCLIPBOARD <00005> 006310B4 R WM_DRAWCLIPBOARD <00006> 006310B4 S WM_DRAWCLIPBOARD <00007> 006310B4 R WM_DRAWCLIPBOARD <00008> 006310B4 P WM_KEYDOWN nVirtKey:VK_CONTROL cRepeat:1 ScanCode:1D fExtended:0 fAltDown:0 fRepeat:0 fUp:0 <00009> 006310B4 P WM_KEYDOWN nVirtKey:'V' cRepeat:1 ScanCode:2F fExtended:0 fAltDown:0 fRepeat:0 fUp:0 <00010> 006310B4 P WM_CHAR chCharCode:'22' (22) cRepeat:1 ScanCode:2F fExtended:0 fAltDown:0 fRepeat:0 fUp:0 <00011> 006310B4 P WM_KEYUP nVirtKey:'V' cRepeat:1 ScanCode:2F fExtended:0 fAltDown:0 fRepeat:1 fUp:1 <00012> 006310B4 P WM_KEYUP nVirtKey:VK_CONTROL cRepeat:1 ScanCode:1D fExtended:0 fAltDown:0 fRepeat:1 fUp:1 <00013> 006310B4 S WM_DRAWCLIPBOARD <00014> 006310B4 R WM_DRAWCLIPBOARD <00015> 006310B4 S WM_DRAWCLIPBOARD <00016> 006310B4 R WM_DRAWCLIPBOARD Однако простое повторение отсылки этих сообщений не дает результата. Равно как и предложенный вами код. У меня получается вставлять текст вот такой процедурой: Код:
procedure PasteMessage; var KeyInputs: array of TInput; KeyInputCount: Integer; procedure KeybdInput(VKey: Byte; Flags: DWORD); begin Inc(KeyInputCount); SetLength(KeyInputs, KeyInputCount); KeyInputs[KeyInputCount - 1].Itype := INPUT_KEYBOARD; with KeyInputs[KeyInputCount - 1].ki do begin wVk := VKey; wScan := MapVirtualKey(wVk, 0); dwFlags := KEYEVENTF_SCANCODE; dwFlags := Flags or dwFlags; time := 0; dwExtraInfo := 0; end; end; begin KeyInputCount := 0; KeybdInput(VK_CONTROL, 0); KeybdInput(Ord('V'), 0); KeybdInput(Ord('V'), KEYEVENTF_KEYUP); SendInput(KeyInputCount, KeyInputs[0], SizeOf(KeyInputs[0])); Sleep(200); KeyInputCount := 0; KeybdInput(VK_CONTROL, KEYEVENTF_KEYUP); SendInput(KeyInputCount, KeyInputs[0], SizeOf(KeyInputs[0])); end; Но, как я говорил - есть два "но": 1. Клавиша Ctrl используется как модификатор для вызова вставки. 2. На момент вставки текста Ctrl еще нажат. Вот в избавлении от них я и прошу помощи. P.S.: В остальных программах таких проблем нет. |
#4
|
||||
|
||||
Цитата:
Код:
SendMessage(hwnd, WM_KEYDOWN, VK_CONTROL, $001D0001); SendMessage(hwnd, WM_KEYDOWN, Byte('V'), $002F0001); SendMessage(hwnd, WM_CHAR, 22, $002F0001); SendMessage(hwnd, WM_KEYUP, Byte('V'), $C02F0001); SendMessage(hwnd, WM_KEYUP, VK_CONTROL, $C01D0001); |
Этот пользователь сказал Спасибо poli-smen за это полезное сообщение: | ||
Enforcer (02.03.2014)
|
#5
|
||||
|
||||
Совет: создайте проект-времянку, на форму киньте мемо и 4 кнопаря, в обработчик каждой поместите по одной отсылке н(нажать) о(отпустить) - н(Ctrl), н(V) и o(V), o(Ctrl), ну и смотрите что проходит, а что нет нажимая на них. Содержимое мемо - в буфер и следите за последним, что в нём лежит, у вас нетипчный случай, только эксперимент и поможет всё выяснить, имхо
Я не понял Вашего вопроса, но всё же Вам на него отвечу! |
#6
|
|||
|
|||
Все заработало!
Цитата:
Как мне ни стыдно это признавать, но я пробовал использовать SendMessage и у меня ничего не вышло... О_о А ваш код прекрасно работает. Огромное спасибо за помощь. Alegun, вам тоже спасибо за то, что откликнулись. Последний раз редактировалось Enforcer, 02.03.2014 в 17:51. |