Как при помощи Sendinput отправить текст из tEdit?
Скажите пожалуйста, как в Delphi при помощи Sendinput отправить текст из tEdit любое приложение? Даже если моё приложение неактивно (хочу использовать горячие клавиши в ActionManager).
Буду очень признателен за помощь.
var
TI: TInput;
KI: TKeybdInput;
i: integer;
begin
TI.Itype := INPUT_KEYBOARD;
for i := 1 to Length(ds) do
begin
KI.wVk := Ord(UpCase(ds));
KI.dwFlags := 0;
TI.ki := KI;
SendInput(1, TI, SizeOf(TI));
KI.dwFlags := KEYEVENTF_KEYUP;
TI.ki := KI;
SendInput(1, TI, SizeOf(TI));
end;
end;
По данной теме УК Freeman любезно выложил вот эту прогу, очень полезно в ней покопаться. Правда SendInput работает не везде и только с английской раскладкой клавиатуры (могу и заблуждаться), так что лучше воспользоваться эмуляцией нажатий клавиш с помощью keybd_event. Процедурник получается довольно громоздким, в мессагу весь за раз не влезит, поэтому вот рабочий примерчик для D7 (будут баги - извиняйте, потому как собирал прям с ходу, на коленках:), если что не понятно, постите - объясню):
Я использовал слудующий код:
Pos: TPoint;
Target: HWND;
...
if not GetCursorPos(Pos) then
RaiseLastOSError;
Target := WindowFromPoint(Pos);
if Target<>0 then
SendMessage(Target, EM_REPLACESEL, ord(True), LPARAM(PChar(Edit1.Text)));
НО! Он не работает в браузерах и прочих программах, не считаю ICQ, блокнота и ворда.
Пробовал Sendmessage заменть на Sendinput - но не знаю как его использовать, не компилирует. Думаю идею вы поняли?
Спасибо заранее.
Заблуждаешься. Иначе как SpecChar отправляет символы Unicode? Собственно, SendInput понадобился именно потому, что нужно вводить символы, а не просто эмулировать нажатие клавиш. Функциональность для отправки любых символов есть только в SendInput.
Как раз наоборот. SendInput пришла на замену keybd_event, которая признана устаревшей, как подсказал koodeer, и я даже написал об этом в блоге.
Как понимаю, keybd_event была признана устаревшей именно потому, что не поддерживает Unicode.
Там используется tMemo, из него сообщение и берётся (Memo1.Text), вызывай процедуру, а ей передавай любой текст(в переменную ds):
SendText(Edit1.Text);
//используется keybd_event, она из примера, кинь на форму tEdit и напиши так:
SendTekst(Edit1.Text);
И не будет - у тебя в Target лежит хэндл родительского окна, а оно как правило, без полей ввода и используется как подложка, нужно ещё его чилдов искать, хотя не факт, что они найдутся, я когда-то пробовал это делать спомощью EnumChildWindows, не получилось (иногда, возможно степень вложенности была >2), пришлось изголяться по-другому: процедура SendTekst (из примера) так и делает - извращается.
SendText(Edit1.Text);
Всё работает! Но одно "НО", у меня из tEdit вставляются только английские символы. Вместо русского предложения - //// только слэш.
Вопрос кодировки. Смотри, как изящно енто дело обрабатывает Freeman в своей SpecChar:
var
Input: array[0..1] of TInput;
begin
FillChar(Input, SizeOf(Input), 0);
with Input[0] do
begin
Itype := INPUT_KEYBOARD;
with ki do
begin
wScan := Word(Key);
dwFlags := KEYEVENTF_UNICODE
end;
end;
with Input[1] do
begin
Itype := INPUT_KEYBOARD;
with ki do
begin
wScan := Word(Key);
dwFlags := KEYEVENTF_UNICODE or KEYEVENTF_KEYUP;
end;
end;
SendInput(Length(Input), Input[0], SizeOf(TInput));
end;
Только учти, эта процедура обрабатывает за раз только один символ, а не всю строку сразу, тебе потребуется организовывать цикл:
begin
for i:=1 to Length(строка) do SimulateKeystroke(WideChar(строка));
end;
надеюсь, с этим проблем не возникнет.
begin
for i:=1 to Length(строка) do SimulateKeystroke(WideChar(строка));
end;
и этот:
var
TI: TInput;
KI: TKeybdInput;
i: integer;
begin
TI.Itype := INPUT_KEYBOARD;
for i := 1 to Length(ds) do
begin
KI.wVk := Ord(UpCase(ds));
KI.dwFlags := 0;
TI.ki := KI;
SendInput(1, TI, SizeOf(TI));
KI.dwFlags := KEYEVENTF_KEYUP;
TI.ki := KI;
SendInput(1, TI, SizeOf(TI));
end;
end;
И еще, что значит "строка" в первом коде? Я заменил это слово на "Edit1.Text" вообще бред получился. Спасибо за подробные объяснения
var
I: Integer;
begin
for I := 1 to Length(Source) do
SimulateKeystroke(Source);
end;
Потом достаточно будет вызвать SimulateKeystroke(Edit1.Text), и всё должно заработать.
Программа не моя, а eCat-а, я её лишь поддерживаю. Перепишу больше чем на 50% -- будет моя.