Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > В 100-й раз про эмуляцию нажатия клавиш


Автор: EKoshelev 28.8.2013, 13:16
Короче, во всех примерах нажатие клавиш можно сообщать конкретному приложению или даже конкретному элементу управления. А можно ли сделать так, чтобы нажатия славливали те приложения, которые в данный момент активны? Как в реальной жизни: жму я клавишу "A" на клавиатуре, а на неё реагирует то приложение, которое в данный момент активно.

Если это проблематично в Delphi, то возможно есть какой-нибудь другой инструмент?

Заранее спасибо.

Автор: Чучмек 28.8.2013, 13:19
GetForegroundWindow 

Автор: EKoshelev 28.8.2013, 13:43
Вот если Excel активен, то работает, а если, например, блокнот, то не пашет.

Автор: Чучмек 28.8.2013, 13:58
Код

var
  hw,
  ht:cardinal;
  gtinfo:TGUIThreadinfo;
begin
  hw:=GetForegroundWindow();
  ht:=GetWindowThreadProcessId(hw,nil);
  FillChar(gtinfo,sizeof(gtinfo),0);
  gtinfo.cbSize:=sizeof(gtinfo);
  GetGUIThreadInfo(ht,gtinfo);
  caption:=inttohex(gtinfo.hwndActive,8)+' '+inttohex(gtinfo.hwndFocus,8);


Погугли по функциям.

Автор: bems 28.8.2013, 23:20
SendInput же

Автор: EKoshelev 29.8.2013, 09:01
Чучмек, спасибо, в приведённом тобой примере подходит этот хэндл: gtinfo.hwndFocus. Правда, опять-таки не ко всему. То что предложил bems канает везде. По крайней мере из того, что я тестил.


bems, спасибо.

Нашел вот такой код:

Код

procedure TForm1.Timer1Timer(Sender: TObject);
var
  Inp: TInput;

begin
  // press
  Inp.Itype := INPUT_KEYBOARD;
  Inp.ki.wVk := Ord('A');
  Inp.ki.dwFlags := 0;
  SendInput(1, Inp, SizeOf(Inp));

  // release
  Inp.Itype := INPUT_KEYBOARD;
  Inp.ki.wVk := Ord('A');
  Inp.ki.dwFlags := KEYEVENTF_KEYUP;
  SendInput(1, Inp, SizeOf(Inp));
  Application.ProcessMessages;
end;



Пашет вроде. Правда ещё не проверил в World of Tanks. 

Автор: Чучмек 29.8.2013, 10:47
Да, конечно, bems прав. 
Я зациклился на 
Цитата(EKoshelev @  28.8.2013,  13:16 Найти цитируемый пост)
 можно сообщать конкретному приложению или даже конкретному элементу управления

и даже прочитал "можно сообщать", как "можно отправить сообщение".
Поэтому и ответ мой - как найти "этот самый" активный элемент. 
Мне минус.

Автор: bems 29.8.2013, 19:53
Цитата(EKoshelev @  29.8.2013,  09:01 Найти цитируемый пост)
World of Tanks
для игр может понадобиться отправлять нажатия в сканкодах

Автор: EKoshelev 30.8.2013, 07:02
bems, вот с этого места, если не трудно, по подробнее. Т. к. весь замут как раз ради этого. Вчерась попробовал в WoT передавать нажатия - не чухает совсем. Если таки трудно, то буду рад хотя бы ссылкам на какие-нибудь полезные источники.

Автор: bems 30.8.2013, 07:11
вот http://forum.vingrad.ru/forum/topic-338301.html я писал вариант на сях

Добавлено через 1 минуту и 28 секунд
вопрошающий был удовлетворён, хотя потом в этой теме появился человек, который сказал что у него не работает. попробуй короч

Автор: EKoshelev 3.9.2013, 18:13
Короче, всем спасибо (не прошло и полгода, ага).

Вот кусок кода, которым я генерю нажатие клавиш:

Код

var
  Inp: TInput;

...

begin
  FillChar(Inp, sizeof(Inp), 0);
  Inp.Itype := INPUT_KEYBOARD;

  // В сишном варианте была константа KEYEVENTF_SCANCODE, но в дельфовом я такой не нашел, просто выяснил, что она равна 8.
  // Это нажатие.
  Inp.ki.dwFlags := 8 or 0;//KEYEVENTF_SCANCODE or 0;
  // Это отжатие (его ещё не тестил, если чо)
  // Inp.ki.dwFlags := 8 or KEYEVENTF_KEYUP;

  // Это скан-код клавиши "A" (у меня, у вас может быть другой)
  Inp.ki.wScan := $1E;

  // Собственно эмуляция нажатия
  SendInput(1, Inp, SizeOf(Inp));
end;





Вот нехитрый код, при помощи которого можно поузнавать скан-коды клавиш:

Код

...
  public
    { Public declarations }

    procedure WmKeyDown(var Msg: TMessage); message wm_KeyDown;
  end;

...

procedure TForm1.WmKeyDown(var Msg: TMessage);
begin
  Label1.Caption := '0x' + IntToHex(Msg.LParamHi and $FF, 2);
  Label3.Caption := IntToStr(Msg.WParam);
end;


В первую лабель выводится скан-код в хексе, в третью ASCII. Про скан-код я в вики узнал кой-чего, чего раньше не знал.
Короче, по любому всем спасибо. Особенно bemsу.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)