Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > ОС и железо
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 28.02.2014, 16:07
Enforcer Enforcer вне форума
Прохожий
 
Регистрация: 22.05.2012
Адрес: Санкт-Петербург
Сообщения: 4
Версия Delphi: Delphi 7, XE4
Репутация: 10
Печаль Эмуляция Ctrl+V

Добрый день.
Вопрос у меня на первый взгляд глупый, но вот ответить на него своими силами у меня не выходит.
Возникло у меня желание написать небольшую утилиту для всем известной World of Tanks, которая при нажатии на определенные кнопки будет отсылать в чат заранее заготовленные сообщения - ну не хватает мне стандартных, а решить задачу хочется именно на Delphi.
Суть возникшей проблемы - не получается вставить текст из буфера. Испробовал все: WM_PASTE, keybd_event и SendInput. Сочетание Ctrl+V передается только в последнем случае и только при соблюдении условий:
1. Клавиша Ctrl используется как модификатор для вызова вставки.
2. На момент вставки текста Ctrl еще нажат.
В то же время для всех остальных программ (блокнот, браузер, IDE и т.д.) все прекрасно срабатывает.

Как говорил один умный осел - "Кувшин моих мыслей показывает дно..."
Выручайте.
Ответить с цитированием
  #2  
Старый 28.02.2014, 18:40
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Цитата:
Сообщение от Enforcer
... Испробовал все: WM_PASTE, keybd_event и SendInput...
Ещё раз попробуйте
Код:
 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  
Старый 01.03.2014, 05:47
Enforcer Enforcer вне форума
Прохожий
 
Регистрация: 22.05.2012
Адрес: Санкт-Петербург
Сообщения: 4
Версия Delphi: Delphi 7, XE4
Репутация: 10
По умолчанию

Цитата:
Сообщение от Alegun
Ещё раз попробуйте
Очень остроумный совет. Хотя, надо признать, я сам виноват в его появлении. Сейчас опишу проблему подробнее.
С отсылкой клавиатурных сообщений как таковых проблем нет вообще - игра их распознают и реагирует должным образом. При этом не важно - использую я 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  
Старый 01.03.2014, 12:45
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от Enforcer
Однако простое повторение отсылки этих сообщений не дает результата. Равно как и предложенный вами код. У меня получается вставлять текст вот такой процедурой:
А если попробовать отослать сообщения через SendMessage вместо PostMessage?:
Код:
  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  
Старый 01.03.2014, 13:48
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Совет: создайте проект-времянку, на форму киньте мемо и 4 кнопаря, в обработчик каждой поместите по одной отсылке н(нажать) о(отпустить) - н(Ctrl), н(V) и o(V), o(Ctrl), ну и смотрите что проходит, а что нет нажимая на них. Содержимое мемо - в буфер и следите за последним, что в нём лежит, у вас нетипчный случай, только эксперимент и поможет всё выяснить, имхо
Ответить с цитированием
  #6  
Старый 02.03.2014, 00:55
Enforcer Enforcer вне форума
Прохожий
 
Регистрация: 22.05.2012
Адрес: Санкт-Петербург
Сообщения: 4
Версия Delphi: Delphi 7, XE4
Репутация: 10
Радость Все заработало!

Цитата:
Сообщение от poli-smen
А если попробовать отослать сообщения через SendMessage вместо PostMessage?

Как мне ни стыдно это признавать, но я пробовал использовать SendMessage и у меня ничего не вышло... О_о А ваш код прекрасно работает. Огромное спасибо за помощь.

Alegun, вам тоже спасибо за то, что откликнулись.

Последний раз редактировалось Enforcer, 02.03.2014 в 17:51.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 07:23.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter