Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 1 376

/ вопрос решён /

Здравствуйте!
Не подскажете, как можно программно нажать Enter для класса Edit, зная его Handle.
Ситуация такая, что кнопок, типа Ок нету, есть текстовое поле, которое откликается на Enter и делает два дйствия:
1. Очищает строку
2. Подтверждает ввод
странно, но очистку делать удается, а вот для подтверждения, Enter будто игнорируется.
пробовал
PostMessage({Хендл}, WM_KEYDOWN, VK_RETURN, 0);
PostMessage({Хендл}, WM_KEYUP, VK_RETURN, 0);
пробовал просто
PostMessage({Хендл}, WM_KEYDOWN, VK_RETURN, 0);
ничего из этого мне не помогло.
может есть какие-либо функции именно работы с клавиатурой?
например, программно перевести Focus на необходимый Edit и именно эмулировать нажатие клавиатурой Enter?
Есть ли такие варианты?

ChPuK Вопрос решён, но можно продолжить его обсуждение в мини-форуме

Вопрос задал: ChPuK (статус: Посетитель)
Вопрос отправлен: 26 февраля 2008, 11:23
Состояние вопроса: решён, ответов: 3.

Ответ #1. Отвечает эксперт: Feniks

Здравствуйте, ChPuK!
Попробуйте использовать функцию Edit1.Perform. Например, если у вас несколько TEdit-от на форме и надо переключаться на следующий по нажатию Enter (эмуляция нажатия TAB), то решение следующее. У каждого TEdit делаете один и тот же обработчик:

procedure TForm1.Edit1KeyDown(Sender: TObject;
  var Key: Word; Shift: TShiftState);
begin
   if Key = VK_RETURN then Perform(WM_NEXTDLGCTL, 0, 0);
end;
Не много не ясно, когда именно вы пытаетесь "нажать Enter". Если в самом TEdit, после ввода данных, то у него же есть события OnKeyDown, OnKeyUp, OnKeyPress. Для работы последнего, у Форму должно стоять свойство
KeyPreView:=True;
Если же после ввода данных и нажатию Enter надо что-то сделать, то код будет следующим:
procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
   if Key=chr(VK_RETURN) then
// делаем чего-нибудь...
end;
Или так, если надо послать Enter в Edit при наступлении какого-то условия:
Edit1.Perform(WM_KEYDOWN, VK_RETURN, 0);
После этого сработает событие Edit1.OnKeyDown.

Желаю удачи...

Ответ отправил: Feniks (статус: Бакалавр)
Время отправки: 26 февраля 2008, 12:58
Оценка за ответ: 5

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

Ответ #2. Отвечает эксперт: min@y™

Попробуй так:

SendMessage(EditHandle, WM_CHAR, Integer(#13), 0);

Ответ отправил: min@y™ (статус: Доктор наук)
Время отправки: 26 февраля 2008, 14:12

Ответ #3. Отвечает эксперт: Dron

Здравствуйте, ChPuK!
Для примера создал 2 приложения: одно - с полем ввода, реагирующим на нажатие Enter, другое - отправляющее это нажатие. Если SendMessage и PostMessage не дают успеха, имеет смысл попробовать воспользоваться keybd_event() - эта функция фактически эмулирует реальное нажатие клавиши. Заметил, что в мини-форуме Вы уже пришли к этому выводу, но функцию используете не совсем правильно. Нужно не забывать "отжимать" клавишу. Тестовые проекты см. в прикреплённом файле. В приложении pas-модули обоих проектов. Ещё может играть роль принцип работы той программы, которой отправляется нажатие. Если программа чужая, мы не знаем, какие именно там идут проверки на нажатия. Но, как видно из моего примера, вручную такое осуществляется довольно просто. Желаю удачи!
К ответу прикреплён файл. Загрузить » (срок хранения: 60 дней с момента отправки ответа)

Приложение:
  1.  
  2.  
  3. unit Unit1;
  4.  
  5. interface
  6.  
  7. uses
  8. Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  9. Dialogs, StdCtrls;
  10.  
  11. type
  12. TForm2 = class(TForm)
  13. Button1: TButton;
  14. procedure Button1Click(Sender: TObject);
  15. private
  16. { Private declarations }
  17. public
  18. { Public declarations }
  19. end;
  20.  
  21. var
  22. Form2: TForm2;
  23.  
  24. implementation
  25.  
  26. {$R *.dfm}
  27.  
  28. procedure TForm2.Button1Click(Sender: TObject);
  29. var h1,h2: hwnd;
  30. begin
  31. h1:=findwindow('TForm1','Form1');
  32. h2:=findwindowex(h1,0,'TEdit',nil);
  33. caption:=format('%d - %d',[h1,h2]);
  34. SetForegroundWindow(h1);
  35. Windows.SetFocus(h2);
  36. keybd_event(VK_RETURN,0,0,0);
  37. keybd_event(VK_RETURN,0,KEYEVENTF_KEYUP,0);
  38. end;
  39.  
  40. end.
  41.  
  42.  
  43.  
  44. unit Unit1;
  45.  
  46. interface
  47.  
  48. uses
  49. Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  50. Dialogs, StdCtrls;
  51.  
  52. type
  53. TForm1 = class(TForm)
  54. Edit1: TEdit;
  55. Label1: TLabel;
  56. procedure Edit1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
  57. private
  58. { Private declarations }
  59. public
  60. { Public declarations }
  61. end;
  62.  
  63. var
  64. Form1: TForm1;
  65.  
  66. implementation
  67.  
  68. {$R *.dfm}
  69.  
  70. procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word;
  71. Shift: TShiftState);
  72. begin
  73. if Key = VK_RETURN then
  74.  
  75. end;
  76.  
  77. end.
  78.  


Ответ отправил: Dron (статус: Студент)
Время отправки: 27 февраля 2008, 14:49
Оценка за ответ: 5

Комментарий к оценке: Вот это называется реальной помощью!!!

Мини-форум вопроса

Всего сообщений: 6; последнее сообщение — 28 февраля 2008, 08:26; участников в обсуждении: 2.
ChPuK

ChPuK (статус: Посетитель), 26 февраля 2008, 13:43 [#1]:

Вся проблема в том, что мне нужно нажать Enter в окне другого приложения.
ChPuK

ChPuK (статус: Посетитель), 26 февраля 2008, 14:36 [#2]:

SendMessage(EditHandle, WM_CHAR, Integer(#13), 0);
тоже пробовал :(
Feniks

Feniks (статус: Бакалавр), 26 февраля 2008, 15:38 [#3]:

Эээ... батенька... Вы бы так сразу и сказали, что надо в другом приложении. Тут надо шлубже копать.
Feniks

Feniks (статус: Бакалавр), 26 февраля 2008, 15:50 [#4]:

Попробуйте так:
PostMessage(FindWindow('Имя нужного окна', nil), WM_KEYDOWN, VK_RETURN, 0);
Или используйте модуль sndkey32.pas.
К сожалению, я его сюда не могу выложить, но могу залить сюда
но он там не долго просуществует.
ChPuK

ChPuK (статус: Посетитель), 26 февраля 2008, 22:08 [#5]:

Конешно это странно, но вот способ, который помог:
[code]
SetForegroundWindow(this_HWND);
SendMessage(h1,WM_SETTEXT,0,0);
for i:=0 to Length(text) do
keybd_event(Ord(text[i]),0,0,0);
keybd_event(VK_RETURN,0,0,0);
[/code]
по другому никак не хочет давать результат.
ChPuK

ChPuK (статус: Посетитель), 28 февраля 2008, 08:26 [#6]:

Dron, спасибо за указание моей ошибки. Все исправил, все работает.
Всем спасибо за помощь.

31 января 2011, 20:02: Статус вопроса изменён на решённый (изменил модератор Ерёмин А.А.): Автоматическая обработка (2 и более ответов с оценкой 5)

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 ноября 2017, 08:31
Выполнено за 0.05 сек.
Рейтинг@Mail.ru