Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2009.03.29;
Скачать: CL | DM;

Вниз

Отсылка комбинации клавиш в чужое окно   Найти похожие ветки 

 
NewBie   (2009-02-06 12:31) [0]

Мне необходимо поуправлять чужим приложением.
В результате гуугления из Delphi World 6 Pro выдрал вот такую процедуру:
procedure GetAllWindow;
Var
WindowHandle:HWnd;
WindowsName:string;
begin
WindowHandle:=FindWindow("TApplication",0);          // Найдем первое окно верхнего уровня любого класса
While (WindowHandle<>0) do Begin        // Если такое окно существует
 SetLength(WindowsName,100);//буфер
 GetWindowText(WindowHandle,
               pchar(WindowsName),
               Length(WindowsName));//заголовок окна
 if (Pos("Light Alloy",WindowsName)<>0) and (WindowHandle<>0) then begin
  LAHandle:=WindowHandle;//хэндл нашли
  break;//дальше искать не надо
 end;
 Application.ProcessMessages;         // Дадим возможность поработать другим
 WindowHandle:=GetNextWindow(WindowHandle,GW_HWNDNEXT);   // Найдем следующее окно в системе.
End;
end;


теперь хочу послать что-то в программу, например, эмулирую нажатие пробела:

PostMessage(LAHandle, WM_KEYDOWN, 32, 0);

Всё прекрасно работает.
Но мне надо послать комбинацию клавиш: Ctrl + -> (контрол + вправо).

Погуглив нашёл варианты ответов, но никак не допетраю что к чему и как заставить их работать:

Тут как отослать Ctrl+C консольному окну:
http://www.delphikingdom.ru/asp/answer.asp?IDAnswer=66086
но у меня GUI, вроде не наш метод.
Тут человека проглючило:
http://www.delphikingdom.ru/asp/answer.asp?IDAnswer=65752
однако дальше меня заинтересовала: keybd_event
Нашёл такое:
http://www.delphikingdom.com/asp/answer.asp?IDAnswer=48998
однако код аналогичный этому:

01: var
02:    ThreadID,my:cardinal;
03: begin
04:    ThreadID:=GetWindowThreadProcessId(GetForegroundWindow,nil);
05:    my:=GetWindowThreadProcessId(handle,nil);
06:    AttachThreadInput(ThreadID,my,true);
07:    windows.setfocus(form1.memo1.handle);
08:    keybd_event(VK_CONTROL, 0, 0, 0);
09:    keybd_event(86, 0, 0, 0);
10:    keybd_event(86, 0, KEYEVENTF_KEYUP, 0);
11:    keybd_event(VK_CONTROL, 0,KEYEVENTF_KEYUP, 0);
12:    AttachThreadInput(ThreadID,my,false);
13: end;


Строка 4 - Получаю список потоков в системе?
Строка 5 - выделяю свой поток по известному хэдлу?
Строка 6 - подключаюсь к потоку.
Строка 7 - Устанавливаю фокус. По идее вместо мемо из примера могу указать хэндл программы, к которой подключаюсь?
Строка 8 - говорю программе, что нажат Ctrl
Строка 9 - посылаю код клавиши 86 (в моём случае 4d - это получается 77 в десятичной?)
Строка 10 и Строка 11 - говорю, что клавиши отпущены.
Строка 12 - отпускаю процесс на волю

Не погу понять в чём я не прав. Спасибо за помощь заранее.


 
Ru ©   (2009-02-06 12:44) [1]

Нашёл ещё такой пример:
Последовательное нажатие сначала Shift потом "/" тоже не проходит:
PostMessage(hwork,WM_KEYDOWN,(WPARAM)0x10,0x002a0001); // нажат Shift
PostMessage(hwork,WM_KEYDOWN,(WPARAM)0xbf,0x00350001); // нажат "/"
PostMessage(hwork,WM_KEYUP,(WPARAM)0xbf,0xC0350099);
PostMessage(hwork,WM_KEYUP,(WPARAM)0x10,0xC02a0001);

http://www.rsdn.ru/forum/message/302838.flat.aspx
Попробовал его переделать:


PostMessage(LAHandle,WM_KEYDOWN, 17,0); // нажат Ctrl
PostMessage(LAHandle,WM_KEYDOWN,39,0); // нажата -> (вправо)
PostMessage(LAHandle,WM_KEYUP,39,0); //отпустили вправо
PostMessage(LAHandle,WM_KEYUP,17,0); //отпустили Ctrl


Почти работает. Во всяком случае эмуляция нажатия кнопки вправо.
А как добить чтобы работала комбинация?


 
Ru ©   (2009-02-06 12:46) [2]

17 - код Ctrl
39 - код вправо


 
Leonid Troyanovsky ©   (2009-02-06 16:58) [3]


> NewBie   (06.02.09 12:31)  

> Строка 4 - Получаю список потоков в системе?

Получаем идентификатор потока, создавшего foreground окно.

> Строка 5 - выделяю свой поток по известному хэдлу?

Это строку проще написать так my := GetCurrentThreadId.

> Строка 6 - подключаюсь к потоку.

Ну, пусть так.
По-научному она attaches the input processing mechanism
of one thread to that of another thread.

> Строка 7 - Устанавливаю фокус. По идее вместо мемо из примера
> могу указать хэндл программы, к которой подключаюсь?

Здесь надо указать хендл контрола, который должен получать
клавиатурный ввод.

> Строка 9 - посылаю код клавиши 86 (в моём случае 4d - это
> получается 77 в десятичной?)

А почему 4d, если нужна VK_RIGHT $27.
И, во-ще, RTFM: msdn: Virtual-Key Codes

--
Regards, LVT.


 
Leonid Troyanovsky ©   (2009-02-06 17:10) [4]


> NewBie   (06.02.09 12:31)  

> Но мне надо послать комбинацию клавиш: Ctrl + -> (контрол
> + вправо).

Поизучай оное приложение с помощью, например, winsight32.
Если на искомую комбинацию генерируется, скажем, WM_COMMAND,
то слать проще его, а не делать чужому окну foreground & keybd_event.

Другие же методы весьма ограничены, бо не foreground поток (окно)
никто не обяжет обрабатывать клавиатурный ввод, да и API  для
модификации очереди ввода чужого потока не предусмотрено.

--
Regards, LVT.



Страницы: 1 вся ветка

Текущий архив: 2009.03.29;
Скачать: CL | DM;

Наверх




Память: 0.48 MB
Время: 0.018 c
15-1232350793
nnov
2009-01-19 10:39
2009.03.29
Железо - Видюха


2-1233240872
Fonts
2009-01-29 17:54
2009.03.29
Про фонты дисплея


1-1208371037
_Z_
2008-04-16 22:37
2009.03.29
как работать с фремом, созданным в dll


2-1233167316
Dik
2009-01-28 21:28
2009.03.29
Консоль


15-1232942877
Дмитрий С
2009-01-26 07:07
2009.03.29
Номер версии в InnoSetup