Форум программистов, компьютерный форум, киберфорум
Delphi для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.89/638: Рейтинг темы: голосов - 638, средняя оценка - 4.89
0 / 0 / 1
Регистрация: 17.11.2009
Сообщений: 31

Имитация нажатий клавиш клавиатуры

15.02.2010, 03:24. Показов 131564. Ответов 38

Студворк — интернет-сервис помощи студентам
Как соорудить программу, чтобы по нажатию ранее назначеной клавише происходила имитация нажатия некоторой комбинации клавиш. Пример: я нажимаю правый Ctrl программа сама имитирует 5 поочерёдных нажатий клавиши f7, причём с таймаутом 5 секунд. Во многом придёца разбираца, мот кто подкинет нужную литературку?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
15.02.2010, 03:24
Ответы с готовыми решениями:

Имитация нажатия клавиш клавиатуры
Всем привет! Прошу помочь мне. Я искал в интернете но там как то сложно. Я думаю можно обойтись от таких сложностей. Задача...

Эмуляция нажатий клавиш
У меня есть залогированы клавиши в блокноте в таком виде(много): Как мне заставить их из блокнота или из Мемо нажиматся в цикле? ...

Считывание и обработка нажатий клавиш
Всем привет! Мне нужно написать маленькую программку, которая выполняла бы следующую операцию: необходимо, чтобы при нажатии сочетании...

38
 Аватар для Mawrat
13113 / 5894 / 1708
Регистрация: 19.09.2009
Сообщений: 8,809
24.08.2010, 11:24
Студворк — интернет-сервис помощи студентам
Amakl, по результатам поиска в инете на тему: "наблюдение за буфером обмена Windows", написал демонстрационный проект.
За основу взял эту статью.
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;
 
type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
 
    //Флаг, показывающий, участвует ли наше окно в цепочке наблюдателей.
    FInChain : Boolean;
    //Хэндл окна, которое в цепочке наблюдателей стоит за нами.
    FNextViewer : HWND;
  public
    { Public declarations }
 
    //Вызывается в случае, если изменяется цепочка наблюдателей за буфером обмена.
    procedure WMChangeCBChain(var Msg: TWMChangeCBChain); message WM_CHANGECBCHAIN;
 
    //Вызывается в случае, если содержимое буфера обмена изменилось.
    procedure WMDrawClipboard(var Msg: TWMDrawClipboard); message WM_DRAWCLIPBOARD;
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
uses
  Clipbrd;
 
{ TForm1 }
 
//Вызывается в случае, если из цепочки удаляется какой-то наблюдатель.
procedure TForm1.WMChangeCBChain(var Msg: TWMChangeCBChain);
begin
  //Цепочка наблюдателей за буфером обмена: БУФЕР ОБМЕНА - А1 - А2 - А3 - А4 - А5 - А6
  //А1...А6 - это окна, зарегистрированные как наблюдатели.
  //Предположим, мы - это А3, тот кто прикреплён
  //за нами - это А4 - на него ссылается FNextViewer
  //А тот кто прикреплён за А4 - это А5.
  //Msg.Remove - хэндл (системный идентификатор Windows) удаляемого окна
  //Msg.Next - хэндл того окна, которое прикреплено за удаляемым окном
 
  //Если оказалось, что из цепочки наблюдателей удаляется А4, то мы должны прикрепить
  //к себе А5. В результате получится: БУФЕР ОБМЕНА - А1 - А2 - А3 - А5 - А6
  if Msg.Remove = FNextViewer then
    FNextViewer := Msg.Next
  //Если из цепочки наблюдателей удаляется некто не равный А4, то мы просто должны
  //переслать сообщение следующему в цепочке - т. е. А4.
  else
    SendMessage(FNextViewer, WM_CHANGECBCHAIN, Msg.Remove, Msg.Next)
  ;
 
  //Новые окна в цепочку добавляются в начало цепи - т. е. перед А1. Поэтому
  //членам цепочки не надо обрабатывать ситуации с добавлением.
end;
 
//Вызывается в случае, если содержимое буфера обмена изменилось.
procedure TForm1.WMDrawClipboard(var Msg: TWMDrawClipboard);
var
  i : Integer;
  IsMod : Boolean;
begin
  //Оповещаем об изменениях следующего за нами наблюдателя.
  if FNextViewer <> 0 then begin
    SendMessage(FNextViewer, WM_DRAWCLIPBOARD, 0, 0);
    Msg.Result:=0;
  end;
 
  //Далее идёт код работы с буфером обмена.
 
  Memo1.Lines.Add('--------------------------------------------------');
  Memo1.Lines.Add('Содержимое буфера обмена изменилось.');
 
  //Проверяем, есть ли в буфере данные в интересующем нас формате.
  IsMod := False;
  for i := 0 to Clipboard.FormatCount - 1 do begin
    if Clipboard.HasFormat(CF_TEXT) then begin
      IsMod := True;
      Break;
    end;
  end;
 
  //Если данные в требуемом формате есть, то обрабатываем их.
  if IsMod then begin
    //...
    //Например копируем текст в Memo.
    Memo1.Lines.Add('Данные типа CF_TEXT:');
    Memo1.Lines.Add(Clipboard.AsText);
    //...
  end else begin
    Memo1.Lines.Add('Буфер обмена не содержит данных типа CF_TEXT.');
  end;
end;
 
procedure TForm1.FormCreate(Sender: TObject);
begin
  FInChain := False;
  FNextViewer := 0;
end;
 
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  if FInChain then begin
    ChangeClipboardChain(Handle, FNextViewer);
    FInChain := False;
  end;
end;
 
//Встраиваем наше окно в цепочку наблюдателей за буфером обмена.
procedure TForm1.Button1Click(Sender: TObject);
begin
  //FNextViewer - хэндл следующего за нами наблюдателя. Может быть = 0, если
  //наше окно последнее в цепи.
  FNextViewer := SetClipboardViewer(Handle);
  FInChain := True;
 
  Memo1.Lines.Add('--------------------------------------------------');
  Memo1.Lines.Add('Выполнена регистрация в качестве наблюдателя за буфером обмена.');
end;
 
//Удаляем наше окно из цепочки наблюдателей за буфером обмена.
procedure TForm1.Button2Click(Sender: TObject);
begin
  ChangeClipboardChain(Handle, FNextViewer);
  FInChain := False;
 
  Memo1.Lines.Add('--------------------------------------------------');
  Memo1.Lines.Add('Выполнен выход из цепочки наблюдателй за буфером обмена.');
end;
 
end.
К этому коду можешь свою логику прикрутить. Например, можно привязать действия к флагу FInChain.
---
Ещё надо иметь в виду, что при встраивании в цепочку наблюдения, то сразу же приходит сообщение WM_DRAWCLIPBOARD - т. е. что содержание буфера поменялось.
Миниатюры
Имитация нажатий клавиш клавиатуры  
Вложения
Тип файла: rar ClipBoardViewer.rar (169.5 Кб, 132 просмотров)
1
0 / 0 / 0
Регистрация: 21.08.2010
Сообщений: 24
25.08.2010, 10:42
Mawrat,
спасибо огромное за внимание к моим проблемам. Пытаюсь разобраться в присланной программе, со средствами объектного программирования я очень мало знаком. Забыл сказать, что мое приложение - консольное.
Твоя программа отсеживает все изменения буфера обмена. Мне надо узнать, когда в буфер обмена попадет информация, скопированная по ctrl+C моей же программой в окне другого приложения. Не упрощает ли это задачу, ведь я знаю откуда ждать сообщение.
Я пытаюсь заменить задержку sleep на что-то вроде:

SetClipboardViewer(wnd0); //делаю свое окно наблюдателем буфера, wnd0 - дескриптор окна моей программы
//здесь, я так думаю должен быть цикл, заканчивающийся при приеме сообщения WM_CHANGECBCHAIN
ChangeClipboardChain(wnd0,wnd2); //прекращаю быть наблюдателем буфера

Может подскажешь еще раз, как это правильно организовать?
0
 Аватар для Mawrat
13113 / 5894 / 1708
Регистрация: 19.09.2009
Сообщений: 8,809
25.08.2010, 11:17
Amakl, я вечером сегодня допишу - чтобы в БО (буфере обмена) отслеживались только те изменения, которые выполняются по серии вызовов keybd_event() из программы.
0
 Аватар для Mawrat
13113 / 5894 / 1708
Регистрация: 19.09.2009
Сообщений: 8,809
26.08.2010, 02:18
Вот вариант с копированием из Блокнота Windows:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;
 
type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    Button2: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
 
    //Флаг, показывающий, участвует ли наше окно в цепочке наблюдателей.
    FInChain : Boolean;
    //Флаг, показывающий, следует ли реагировать на изменения в буфере обмена.
    FIsEnableAction : Boolean;
    //Хэндл окна, которое в цепочке наблюдателей стоит за нами.
    FNextViewer : HWND;
  public
    { Public declarations }
 
    //Вызывается в случае, если изменяется цепочка наблюдателей за буфером обмена.
    procedure WMChangeCBChain(var Msg: TWMChangeCBChain); message WM_CHANGECBCHAIN;
    //Вызывается в случае, если содержимое буфера обмена изменилось.
    procedure WMDrawClipboard(var Msg: TWMDrawClipboard); message WM_DRAWCLIPBOARD;
 
    //Зарегистрироваться в цепочке наблюдателей за буфером обмена.
    procedure EnableView;
    //Выйти из цепочки наблюдателей за буфером обмена.
    procedure DisableView;
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
uses
  Clipbrd;
 
{ TForm1 }
 
//Вызывается в случае, если из цепочки удаляется какой-то наблюдатель.
procedure TForm1.WMChangeCBChain(var Msg: TWMChangeCBChain);
begin
  //Цепочка наблюдателей за буфером обмена: БУФЕР ОБМЕНА - А1 - А2 - А3 - А4 - А5 - А6
  //А1...А6 - это окна, зарегистрированные как наблюдатели.
  //Предположим, мы - это А3, тот кто прикреплён
  //за нами - это А4 - на него ссылается FNextViewer
  //А тот кто прикреплён за А4 - это А5.
  //Msg.Remove - хэндл (системный идентификатор Windows) удаляемого окна
  //Msg.Next - хэндл того окна, которое прикреплено за удаляемым окном
 
  //Если оказалось, что из цепочки наблюдателей удаляется А4, то мы должны прикрепить
  //к себе А5. В результате получится: БУФЕР ОБМЕНА - А1 - А2 - А3 - А5 - А6
  if Msg.Remove = FNextViewer then
    FNextViewer := Msg.Next
  //Если из цепочки наблюдателей удаляется некто не равный А4, то мы просто должны
  //переслать сообщение следующему в цепочке - т. е. А4.
  else
    SendMessage(FNextViewer, WM_CHANGECBCHAIN, Msg.Remove, Msg.Next)
  ;
 
  //Новые окна в цепочку добавляются в начало цепи - т. е. перед А1. Поэтому
  //членам цепочки не надо обрабатывать ситуации с добавлением.
end;
 
//Вызывается в случае, если содержимое буфера обмена изменилось.
procedure TForm1.WMDrawClipboard(var Msg: TWMDrawClipboard);
var
  i : Integer;
  IsMod : Boolean;
begin
  //Оповещаем об изменениях следующего за нами наблюдателя.
  if FNextViewer <> 0 then begin
    SendMessage(FNextViewer, WM_DRAWCLIPBOARD, 0, 0);
    Msg.Result:=0;
  end;
 
  //Далее идёт код работы с буфером обмена.
 
  //Если режим реагирования выключен - выходим.
  if not FIsEnableAction then Exit;
 
  Memo1.Lines.Add('--------------------------------------------------');
  Memo1.Lines.Add('Данные буфера обмена изменились.');
 
  //Проверяем, есть ли в буфере данные в интересующем нас формате.
  IsMod := False;
  for i := 0 to Clipboard.FormatCount - 1 do begin
    if Clipboard.HasFormat(CF_TEXT) then begin
      IsMod := True;
      Break;
    end;
  end;
 
  //Если данные в требуемом формате есть, то обрабатываем их.
  if IsMod then begin
    //Копируем текст в Memo.
    Memo1.Lines.Add('Данные типа CF_TEXT:');
    Memo1.Lines.Add('--------------------------------------------------');
    Memo1.Lines.Add(Clipboard.AsText);
  end else begin
    Memo1.Lines.Add('Буфер обмена не содержит данных типа CF_TEXT.');
  end;
 
  //Отключаем режим реагирования.
  FIsEnableAction := False;
  Memo1.Lines.Add('--------------------------------------------------');
  Memo1.Lines.Add('Режим реагирования отключен.');
end;
 
//Подключение к цепочке наблюдателей за буфером обмена.
procedure TForm1.EnableView;
begin
  //Если мы уже подключены к цепочке - выходим.
  if FInChain then Exit;
  FNextViewer := SetClipboardViewer(Handle);
  FInChain := True;
end;
 
//Отключение от цепочки наблюдателей за буфером обмена.
procedure TForm1.DisableView;
begin
  //Если мы уже отключены от цепочки - выходим.
  if not FInChain then Exit;
  ChangeClipboardChain(Handle, FNextViewer);
  FInChain := False;
end;
 
procedure TForm1.FormCreate(Sender: TObject);
begin
  FInChain := False;
  FIsEnableAction := False;
  FNextViewer := 0;
end;
 
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  DisableView;
end;
 
//Встраиваем наше окно в цепочку наблюдателей за буфером обмена.
//Включаем режим реагирования и выполняем действия по копированию
//текста из целевого окна в буфер обмена.
procedure TForm1.Button1Click(Sender: TObject);
var
  HWin : HWND;
begin
  //Ищем окно Блокнота.
  HWin := FindWindow(nil, PChar('Безымянный - Блокнот'));
  if HWin = 0 then begin
    ShowMessage('Окно блокнота не найдено. Действие отменено.');
    Exit;
  end;
 
  //Подключаемся к цепочке наблюдателей.
  EnableView;
  Memo1.Lines.Add('--------------------------------------------------');
  Memo1.Lines.Add('Произведено подключение к цепочке наблюдателей.');
 
  //Переводим фокус ввода на окно Блокнота.
  SetForegroundWindow(HWin);
  //Небольшая задержка - ожидаем, когда активация нужного
  //окна завершится.
  Sleep(200);
 
  //Включаем режим реагирования.
  FIsEnableAction := True;
  Memo1.Lines.Add('--------------------------------------------------');
  Memo1.Lines.Add('Режим реагирования включен.');
 
  //Ctrl+A.
  keybd_event(VK_LCONTROL,0,0,0);
  keybd_event(Ord('A'),0,0,0);
  keybd_event(Ord('A'),0,KEYEVENTF_KEYUP,0);
  keybd_event(VK_LCONTROL,0,KEYEVENTF_KEYUP,0);
 
  //Ctrl+C.
  keybd_event(VK_LCONTROL,0,0,0);
  keybd_event(Ord('C'),0,0,0);
  keybd_event(Ord('C'),0,KEYEVENTF_KEYUP,0);
  keybd_event(VK_LCONTROL,0,KEYEVENTF_KEYUP,0);
end;
 
procedure TForm1.Button2Click(Sender: TObject);
begin
  Memo1.Clear;
end;
 
end.
Миниатюры
Имитация нажатий клавиш клавиатуры  
Вложения
Тип файла: rar ClipBoardViewer.rar (173.3 Кб, 100 просмотров)
2
0 / 0 / 0
Регистрация: 21.08.2010
Сообщений: 24
28.08.2010, 19:35
Mawrat, в таком виде вроде все понятно, несколько смущает только наличие задержки после активации окна. Вроде бы все затевалось, чтобы избавиться от нее. Наверное, на активацию окна требуется гораздо меньше времени, чем на копирование в буфер?
0
 Аватар для Mawrat
13113 / 5894 / 1708
Регистрация: 19.09.2009
Сообщений: 8,809
28.08.2010, 22:51
Да - если целевое окно изначально неактивное, пришлось в примере задержку использовать - ожидать когда процесс активации завершится. Если целевое окно изначально активно - задержка не нужна.
---
Вообще оказалось, что активировать окно - переместить его на передний план и перевести на него фокус ввода - это, как ни странно, не такая уж простая задача.
Вот, например, нашёл исследование на эту тему. Там приведён вариант решения. Но это несколько больше, чем "пара операторов".
0
0 / 0 / 0
Регистрация: 10.07.2015
Сообщений: 2
17.11.2010, 14:06
Доброго времени суток.
нужна такая программа:при нажатии одной клавиши(любой) программа выполняет такие действия:
нажатие клавиши "р"(англ h) с удержанием нажатия на определенное время,далее "р" отпускается и одновременно идет нажатие клавиши "п"(англ g) тоже на опред время.и так последовательно,пока программа не будет остановлена(тоже какой-то одной клавишей видимо).
p.s. Видел,что в принципе примерно то же самое уже разбиралось выше,но самому,к сожалению,разобраться с этим не удалось,поэтому обращаюсь за помощью.если кто поможет с программой,подскажите еще,где ее вводить(в командной строке или где).
0
2 / 2 / 0
Регистрация: 21.01.2011
Сообщений: 10
21.01.2011, 16:06
Цитата Сообщение от Matfak Посмотреть сообщение
Мммм... интересно... а как сделать как говорил Kapernik, чтобы между нажатиями был таймаут, заданный в секундах??

Добавлено через 26 минут
И вопрос в какой это происходит процедуре и куда она "засовывается" ?
И как можно записать значение нажатой клавиши, ну чтобы программа считывала что ты нажал.

Можно интервал задать ещё через Timer, указав интервал в свойстве таймера в милисекундах. Но его использовать можно только тогда, когда нужно многократное нажатие на одну и ту же клавишу:
Delphi
1
2
3
4
5
procedure TForm1.Timer1Timer(Sender: TObject);
begin
keybd_event(VK_F7, 0, 0, 0); //нажатие F5
keybd_event(VK_F7, 0, KEYEVENTF_KEYUP, 0); //отпускание F5
end;
Для того чтобы остановить процедуру есть команда Timer1.Enabled:=false;
0
10 / 10 / 4
Регистрация: 14.01.2010
Сообщений: 80
14.04.2011, 18:09
Подскажите, почему не работает такой код?:

Delphi
1
2
3
4
  keybd_event(VK_LSHIFT, 0, 0, 0); 
    keybd_event(Ord(39), 0, 0, 0); 
    keybd_event(Ord(39), 0, KEYEVENTF_KEYUP, 0);
  keybd_event(VK_LSHIFT, 0, KEYEVENTF_KEYUP, 0);
Пробовал в блокноте, просто переводится каретка, текст не выделяется, хотя если сделать так:

Delphi
1
2
3
4
5
6
  keybd_event(VK_LSHIFT, 0, 0, 0); 
    sleep(3000);
    keybd_event(Ord(39), 0, 0, 0); 
    keybd_event(Ord(39), 0, KEYEVENTF_KEYUP, 0);
    sleep(3000);
  keybd_event(VK_LSHIFT, 0, KEYEVENTF_KEYUP, 0);
и перемещать каретку в ручную, до и после задержек текст выделяется как будто шифт зажат, но программное нажатие перемещения каретки не приводит к нужному результату.
0
SBARTACO
14.06.2011, 19:50
Возникла проблема, вот код нажатия на Shift+Insert
Delphi
1
2
3
4
5
6
Keybd_event(VK_RSHIFT,0,0,0);
Keybd_event(VK_INSERT,0,0,0);
Keybd_event(VK_INSERT,0,2,0); 
Keybd_Event(VK_RSHIFT, 0, 3, 0);
Keybd_Event(VK_SHIFT, 0, 0, 0);
Keybd_Event(VK_SHIFT, 0, 2, 0);
И код нажатия клавиш Ctrl+V:
Delphi
1
2
3
4
keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL, 0), 0, 0);
keybd_event(Ord('V'), MapVirtualKey(Ord('V'), 0), 0, 0);
keybd_event(Ord('V'), MapVirtualKey(Ord('V'), 0), KEYEVENTF_KEYUP, 0);
keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL, 0), KEYEVENTF_KEYUP, 0);
Все чудесно работает, но есть проблема.
Программа открывает диалоговое окно вставки изображения, и вставляет путь к файлу. На 2х- компьютерах из 6-ти не чего не происходит.
Приведу весь код:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
pause(strtoint(form1.Edit7.Text));
clic(strtoint(form1.Edit3.Text),strtoint(form1.Edit4.Text));
{}
  AssignFile(f, ExtractFilePath(ParamStr(0))+'patch.txt'); 
   Reset(f); 
   str:='';
   Readln(f,sad);
   Closefile(f); {Closes file F}
   Application.ProcessMessages;
  {}
clipboard.Open;
Clipboard.Clear;
CopyStringToClipboard(sad);
Application.ProcessMessages;
pause(strtoint(form1.Edit7.Text));
{1}
Keybd_event(VK_RSHIFT,0,0,0);
Keybd_event(VK_INSERT,0,0,0);
Keybd_event(VK_INSERT,0,2,0);
Keybd_Event(VK_RSHIFT, 0, 3, 0);
Keybd_Event(VK_SHIFT, 0, 0, 0);
Keybd_Event(VK_SHIFT, 0, 2, 0);
{2}
Application.ProcessMessages;
{keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL, 0), 0, 0);
keybd_event(Ord('V'), MapVirtualKey(Ord('V'), 0), 0, 0);
keybd_event(Ord('V'), MapVirtualKey(Ord('V'), 0), KEYEVENTF_KEYUP, 0);
keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL, 0), KEYEVENTF_KEYUP, 0);}
clipboard.Close;
pause(strtoint(form1.Edit7.Text));
clic(strtoint(form1.Edit5.Text),strtoint(form1.Edit6.Text));
form1.close;
end;
Может кто сталкивался с такой проблемой?
1 / 1 / 0
Регистрация: 03.02.2012
Сообщений: 11
07.02.2012, 17:34
Какими командами можно реализовать подобное на окно не в фокусе, но цепочки нажатия кнопок не нужны?
Например, как отправить тому же неактивному Notepad'у «Пробел», букву "А" и Enter? Просто по очереди, сколько не бился наткнулся на комманды вида:
::PostMessage( hwnd, WM_KEYDOWN, 0x41, 0 );
::SendMessgae( hwnd, WM_UNICHAR, L'a', 0 );

Сколько с этими командами не бился блокнот на них не реагирует, а команда "Keybd_event" работает только в активном окне...
0
cybzzz
05.04.2012, 16:57
А кто-то знает как реализовать посыл нажатия клавиш по хоткею? Почти так, как написал топикстартер:

Жму F1 (к примеру), в программу некую посылается кнопка F5 (например).

Я пишу вот так:
Delphi
1
2
3
4
5
6
7
8
9
10
11
Procedure TForm1.WMHotKey(var Msg: TWMHotKey);
var
 h: HWND;
begin
 if Msg.HotKey = id1 then //id1 в FormCreate определён как id1:=GlobalAddAtom('HotKey1');RegisterHotKey(Handle, id1, 0, VK_F1)
 begin
   h:=FindWindow('Notepad', nil);
  PostMessage(h, WM_IME_KEYDOWN, VK_F5, MapVirtualKey(VK_F5, 0));
  ShowMessage('F1 pressed.');
 end;
end;
При этом нажатие отрабатывается - showmessage сообщение выводит, но вот в блокноте нажание F5 не происходит.
В то же время, если я h:=;postmessage() вставляю в buttonclick и кликаю по кнопочке на форме - всё прекрасно в блокноте проходит.

Помогите, пожалуйста.

Добавлено через 43 минуты
Ой. Не знаю как отредактировать сообщение.
Но по F1 как раз работает. А в реальном приложении я пробовал отловить Ctrl+F12.

Добавлено через 32 минуты
Мда. Как оказалось всё просто с блокнотом. А как в другую программу послать клавиши?
Если меняю 'Notepad' на что-то другое (Far, Microsoft Word) - не получается...
 Комментарий модератора 
Теги кода добавлены модератором. По правилам форума, код должен быть оформлен соответствующими тегами. Для оформления кода Delphi следует выделить этот код и на панели редактирования сообщения нажать кнопку: "DELPHI".
1 / 1 / 0
Регистрация: 03.02.2012
Сообщений: 11
05.04.2012, 17:17
с Word'ом всё сложнее, он поделён на кучу подклассов и чтобы написать что-то на первом листе например нужно докопаться до его Индентификатора, иначе прога не пошлёт ему нажатие кнопок.
получается чти ищем окно ворда, а потом по имени класса ищем необходимый нам Хэндл. SPY++ тебе в помощь.
0
cybzzz
05.04.2012, 17:42
А если не в word? Мне, например, хочется попробовать что-то послать вообще в WoW.exe
(если кто не понял: World of Warcraft)
1 / 1 / 0
Регистрация: 03.02.2012
Сообщений: 11
05.04.2012, 17:47
я писал свой макрос нажатия кнопок для другой игры, и то он работал только в активном режиме, к мыше прикоснуться было нельзя так сказать, и я использывал команды bd_event
0
Купер)
18.05.2012, 22:23
Доброго дня всем
подскажите как сделать сочетание клавиш ctrl+f для осуществления поиска из списка
6 / 6 / 0
Регистрация: 20.02.2010
Сообщений: 44
22.11.2012, 18:37
Кто знает как по событию onEnter программно нажать клавишу "End".
0
10 / 10 / 4
Регистрация: 14.01.2010
Сообщений: 80
22.11.2012, 18:54
Цитата Сообщение от vmilyoshin Посмотреть сообщение
Кто знает как по событию onEnter программно нажать клавишу "End".
Код енда 35.
Т.е.:
Code
1
2
    keybd_event(Ord(35), 0, 0, 0); 
    keybd_event(Ord(35), 0, KEYEVENTF_KEYUP, 0);
так выглядит нажатие.
0
6 / 6 / 0
Регистрация: 20.02.2010
Сообщений: 44
22.11.2012, 19:10
keybd_event(Ord(35), 0, 0, 0);
keybd_event(Ord(35), 0, KEYEVENTF_KEYUP, 0);

Спасибо!!! Всё как надо.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
22.11.2012, 19:10
Помогаю со студенческими работами здесь

Подсчет нажатий клавиш на клавиатуре
Приветствую. Понадобилось сделать сабж, но дело тут вот в чем. Счетчик должен плюсовать только нажатия &quot;обычных&quot; клавиш (ну...

Эмуляция нажатий клавиш в браузерную строку.
Подскажите пожалуйста, как можно эмулировать нажатия клавиш в браузерную строку, если я знаю хендл окна браузера. Все мои попытки сделать...

Память процесса, эмуляция нажатий клавиш
1. Дайте плиз кто-нибудь пример или исходник с использованием ReadProcessMemory и WriteProcessMemory , читал статьи всякие, постоянно...

Имитация нажатия клавиш
я пытаюсь написать бот для одной онлайн игры и в ней этот бот не работает, хотя сама игра работает в окне и не на полный экран. Но если...

Имитация нажатия клавиш
Вот в чем беда, перейду сразу к теме что бы не морочить всем мозг ибо все равно придется вскрыть все карты, есть такая онлайн игра Карос....


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
39
Ответ Создать тему
Новые блоги и статьи
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
Расскажи мне о Мире, бродяга
kumehtar 12.11.2025
— Расскажи мне о Мире, бродяга, Ты же видел моря и метели. Как сменялись короны и стяги, Как эпохи стрелою летели. - Этот мир — это крылья и горы, Снег и пламя, любовь и тревоги, И бескрайние. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru