![]() |
|
|
#1
|
|||
|
|||
|
Добрый день.
Вопрос у меня на первый взгляд глупый, но вот ответить на него своими силами у меня не выходит. Возникло у меня желание написать небольшую утилиту для всем известной 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. |