Модераторы: Poseidon, Snowy, bems, MetalFan

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> SendMessage, отправление нажатий клавиш окну 
:(
    Опции темы
HiVeR
Дата 13.8.2008, 11:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 44
Регистрация: 30.6.2008

Репутация: нет
Всего: нет



есть окно, в него нужно передать текст, передать его можно насколько я понял посимвольно, последовательно эмулируя нажатие каждой клавиши, но как передать символ? проблема в том, что нужно посылать нажатие клавиши неактивному окну и без использования фокусов, то есть функции SendKeys и keybd_event отпадают, остаётся SendMessage/PostMessage
вот что у меня есть:
Код

procedure TForm1.Button1Click(Sender: TObject);
var h1: Hwnd;
    s: Char;
begin
s:='q';
h1:= FindWindow(nil, PChar(edit1.Text));
SendMessage(h1, WM_KEYDOWN, VK_RETURN, 0);
SendMessage(h1, WM_KEYUP, VK_RETURN, 0);
end;

таким образом окну успешно отправится и дойдёт Enter
а что нужно вписать в SendMessage на месте wparam и lparam чтобы отправить некоторый символ? возможно ли вообще? Enter отправить легко, так как ему соответствует некоторый код, а обычным буквам вроде как ничё не соответствует...
можно использовать вместо WM_KEYDOWN и WM_KEYUP - WM_CHAR, но тогда сообщения в окно не доходят((
облазил инет, то что нужно не нашёл(, насколько помню в шарпе с помощью spy++ можно узнать lparam и wparam посланных в окно сообщений и использовать эти значения уже в SendMessage, но в дельфи у меня не получилось также...
PM MAIL   Вверх
Rennigth
Дата 13.8.2008, 11:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1708
Регистрация: 21.6.2004
Где: Moscow

Репутация: 49
Всего: 76





--------------------
(* Honesta mors turpi vita potior *)
PM MAIL ICQ   Вверх
morpheyushka
Дата 13.8.2008, 11:54 (ссылка)    | (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Зеленый человек
**


Профиль
Группа: Участник
Сообщений: 563
Регистрация: 26.2.2008
Где: Киев

Репутация: 3
Всего: 8



WM_COPYDATA может поможет?
можно посмотреть тут


--------------------
user posted image
Спасибо делается вот так!!!
PM MAIL WWW   Вверх
HiVeR
Дата 13.8.2008, 12:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 44
Регистрация: 30.6.2008

Репутация: нет
Всего: нет



Цитата
SetWindowText

SetWindowText просто изменит заголовок окна, а нужно чтобы была именно имитация нажатий клавиш, так как по другому, как я понял, текст не запишется...
Цитата
WM_COPYDATA может поможет?

спасибо, ни разу не слышал, попробуюsmile
а используя только WM_KEYDOWN и WM_KEYUP, возможно отправить какойнить символ? или может можно WM_COMMAND?
PM MAIL   Вверх
Rennigth
Дата 13.8.2008, 13:04 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1708
Регистрация: 21.6.2004
Где: Moscow

Репутация: 49
Всего: 76



Цитата(HiVeR @  13.8.2008,  12:17 Найти цитируемый пост)
SetWindowText просто изменит заголовок окна, а нужно чтобы была именно имитация нажатий клавиш, так как по другому, как я понял, текст не запишется...

Смотря для какого типа окна.
Цитата

For an edit control, the text is the contents of the edit control. For a combo box, the text is the contents of the edit-control portion of the combo box. For a button, the text is the button name. For other windows, the text is the window title. 

Также если ты меняешь текст  окна другого приложения нужно использовать 
Код

  SendMessage + WM_SETTEXT

Вот тебе пример с NotePad.
Код

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    edt1: TEdit;
    btn1: TButton;
    procedure btn1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function EnumWindowProc(hwnd: HWND; lParam: LPARAM): BOOL; stdcall;
begin
  Result := BOOL(SendMessage(hwnd, WM_SETTEXT, 0, Integer(PAnsiChar('test'))));
  if not Result then
    OutputDebugString(PAnsiChar(IntToStr(GetLastError)));
end;

procedure TForm1.btn1Click(Sender: TObject);
var
  hWindow: HWND;
begin
  hWindow := FindWindow(PAnsiChar('Notepad'), nil);
  if hWindow > 0 then
    EnumChildWindows(hWindow, @EnumWindowProc, 0);
end;

end.



Добавлено через 7 минут и 17 секунд
HiVeR, а ты если честно пытаешься изобрести велосипед с квадратными колеса smile
Или тебе по религиозным причинам нужно именно клавиатуру имитировать?

Это сообщение отредактировал(а) Rennigth - 13.8.2008, 13:09


--------------------
(* Honesta mors turpi vita potior *)
PM MAIL ICQ   Вверх
HiVeR
Дата 13.8.2008, 17:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 44
Регистрация: 30.6.2008

Репутация: нет
Всего: нет



Rennigth, если бы можно было проще, я бы так не парилсо...
вот смотри, есть окно, просто окно..в нём нет как таковых ни едитов, ни кнопок - ничего, точнее они есть..но они сливаются с окном, как одно целое, при нажатии клавиш при активном этом окне, там в едит записывается текст, но сам едит никоим образом найти не получитсо..
окно - экран/снимок компьютера... надеюсь болеменее понятно объяснилsmile
без имитации клавиш в едит ничё не пишется...
PM MAIL   Вверх
Rennigth
Дата 13.8.2008, 17:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1708
Регистрация: 21.6.2004
Где: Moscow

Репутация: 49
Всего: 76



Цитата(HiVeR @  13.8.2008,  17:18 Найти цитируемый пост)
но сам едит никоим образом найти не получитсо..

ну вот с этого и надо было начинать smile 
Экзешник большой с этим твоим чудо-окном? Если есть возможность выложи его(ну или тестовый какой-нить где не получилось найти) куда-нить, посмотрим.


--------------------
(* Honesta mors turpi vita potior *)
PM MAIL ICQ   Вверх
HiVeR
Дата 13.8.2008, 19:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 44
Регистрация: 30.6.2008

Репутация: нет
Всего: нет



счас, скину в личкуsmile

Это сообщение отредактировал(а) HiVeR - 13.8.2008, 19:16
PM MAIL   Вверх
Rennigth
Дата 14.8.2008, 11:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1708
Регистрация: 21.6.2004
Где: Moscow

Репутация: 49
Всего: 76



HiVeR, 
сказал бы что эт у тя что-то вроде р-админа...  smile 

вопщем вот что пока получилось:
Код

procedure TForm35.btn1Click(Sender: TObject);

  procedure LocalSendKeys(const AKeys: string);
  var
    i: Integer;
  begin
    for i := 1 to Length(AKeys) do
    begin
      keybd_event(Ord(AKeys[i]), MapVirtualKey(Ord(AKeys[i]), 0), KEYEVENTF_EXTENDEDKEY, 0);
      keybd_event(Ord(AKeys[i]), MapVirtualKey(Ord(AKeys[i]), 0), KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP, 0);
    end;
  end;

var
  hWindow, hPrevWindow: HWND;
  hThreadID: DWORD;
begin
  hWindow := FindWindow(PChar('rfb::win32::DesktopWindowClass'), nil);
  if hWindow > 0 then
  begin
    hThreadID := GetWindowThreadProcessId(hWindow);
    if hThreadID > 0 then
    begin
      if AttachThreadInput(hThreadID, GetCurrentThreadId, True) then
      begin
        hPrevWindow := Windows.SetFocus(hWindow);
        if hPrevWindow > 0 then
          LocalSendKeys('QUERTY')
        else
          RaiseLastOSError;
        if not AttachThreadInput(hThreadID, GetCurrentThreadId, False) then
          RaiseLastOSError;
      end else
        RaiseLastOSError;
    end;
  end;
end;

пысы, рейзы убери где нужно сам, для отладки ставил.

пысы, если что за оптимальность,  ошибки не бейте, делал на скорую руку...


--------------------
(* Honesta mors turpi vita potior *)
PM MAIL ICQ   Вверх
HiVeR
Дата 14.8.2008, 12:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 44
Регистрация: 30.6.2008

Репутация: нет
Всего: нет



большое спасибо Rennight, всё доходитsmile
жалко что приходится использовать сетфокус на окно, изза него как я понял в скрытое окно не доходят сообщения и вылетает ошибка, что неслабый минус в моей проге... потому то и надумал использовать SendMessage, так как она более универсальная, но за код всё равно спасибо, у меня было очень мало сделано)
Цитата
сказал бы что эт у тя что-то вроде р-админа... 

я не знаю как в радмине, его почти не использовал
а можно как то обойти сетфокус или сделать так, чтобы имитация клавиш доходила в скрытое окно?smile

Это сообщение отредактировал(а) HiVeR - 14.8.2008, 12:41
PM MAIL   Вверх
Rennigth
Дата 14.8.2008, 13:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1708
Регистрация: 21.6.2004
Где: Moscow

Репутация: 49
Всего: 76



HiVeR, дело в том что для имитации клавишь стандартными средствами, окно должно иметь фокус ввода (keyboard focus). Что для 
keybd_event, что для WM_KEYUP/WM_KEYDOWN. Можно выйти из ситуации, вызывать после введения пароля SetForegroundWindow для своего окна. SetFocus для hPrevWindow может не стаботать, но попробуй...

Добавлено через 4 минуты и 22 секунды
п.с. может можно как-то выкрутиться через регистрацию хоткеев, но я в этом ни бум-бум, надо изучать уже более глубоко, а что-то времени нема...


--------------------
(* Honesta mors turpi vita potior *)
PM MAIL ICQ   Вверх
HiVeR
Дата 14.8.2008, 14:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 44
Регистрация: 30.6.2008

Репутация: нет
Всего: нет



интересно как окно получает фокус ввода от WM_KEYUP/WM_KEYDOWN
например если написать так:
Код

procedure TForm1.Button1Click(Sender: TObject);
var h: Hwnd;
begin
h:= FindWindow('rfb::win32::DesktopWindowClass',nil);
SendMessage(h1, WM_KEYDOWN, VK_RETURN, 0);
SendMessage(h1, WM_KEYUP, VK_RETURN, 0);
end;

вместо VK_RETURN к окну придёт ентер, или же можно написать, например, VK_NUMPAD3 и до окна отлично дойдёт цифра 3), пускай оно даже свернуто..фокуса тут как такогого наверное нету
спс за помощь и что откликнулсяsmile
попробую помудить с wparam и lparam, если не получитсо, почитаю про хоткеи)

Это сообщение отредактировал(а) HiVeR - 14.8.2008, 14:14
PM MAIL   Вверх
VICTAR
Дата 14.8.2008, 14:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1108
Регистрация: 6.10.2006

Репутация: 37
Всего: 80



Цитата(HiVeR @  14.8.2008,  15:13 Найти цитируемый пост)
вместо VK_RETURN к окну придёт ентер,

вообще VK_RETURN = ентер

PM MAIL   Вверх
HiVeR
Дата 21.8.2008, 09:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 44
Регистрация: 30.6.2008

Репутация: нет
Всего: нет



уф, почти разобралсяsmile, в общем, wparam - виртуальный код клавиши, и этим всё сказано. и как сразу не додумался, так просто) 
норм отправиться клавиша t так:
Код

SendMessage(h1, WM_KEYDOWN, wparam('T'), 1);
SendMessage(h1, WM_KEYUP, wparam('T'), 1);

а можно как то отправить заглавную букву?, пробовал таким образом:
Код

SendMessage(h1, WM_KEYDOWN, VK_SHIFT, 1);
SendMessage(h1, WM_KEYDOWN, wparam('T'), 1);
SendMessage(h1, WM_KEYUP, wparam('T'), 1);
SendMessage(h1, WM_KEYUP, VK_SHIFT, 1);

не знаю почему, но пришла только маленькая буква t, шифт как будто и не нажимался, хотя если отправить подобным образом ctrl+alt+del то всё ок
поюзал гугл, он говорит что такой способ не катит, и нужно через стандартные функции с "активацией" окна... хотя я уверен, что через wm_keydown/ keyup тоже можно, но чтото не получается, может кто знает как будет правильно?
PM MAIL   Вверх
VICTAR
Дата 21.8.2008, 11:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1108
Регистрация: 6.10.2006

Репутация: 37
Всего: 80



Кто там заминусовал мой пост? Обоснуйте плз
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0581 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.