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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Программная эмуляция действий пользователя. 
V
    Опции темы
MrKit
Дата 9.2.2007, 12:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Ситуация: есть некая сторонняя программа (закрытая, без исходников), в которой имеется дочернее окно (его можно сделать и автономным, самостоятельным), содержащее StringGrid или какой-то подобный компонент.
Необходимо из своей программы сместить курсор в этом Grid вниз на n позиций и нажать Enter. Но программно, то есть чтобы не надо было нажимать клавиши на клавиатуре, курсор мышки не дергался, и даже окно этой проги не мелькало, в идеале оно вообще должно быть свернутым.
Как это реализовать?
PM MAIL   Вверх
MetalFan
Дата 9.2.2007, 14:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

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



попытаться найти окно и слать ему определенные сообщения.
для начала посмотреть Spy++ информацию по окну.


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
MrKit
Дата 11.2.2007, 15:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Я не работал с этой областью, поэтому можно поподробнее?..  smile 
Как найти нужное окно, если известен путь к файлу приложения?
Как отсылать окну сообщения?
Что такое Spy++?

Может, есть какой-нибудь FAQ или что-то подобное по этой теме?  smile 
PM MAIL   Вверх
MetalFan
Дата 11.2.2007, 18:04 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

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



Цитата(MrKit @  11.2.2007,  15:47 Найти цитируемый пост)
Как найти нужное окно

FindWindow, FindWindowEx, EnumWindows etc...


Цитата(MrKit @  11.2.2007,  15:47 Найти цитируемый пост)
Как отсылать окну сообщения

PostMessage, SendMessage, SendMessageTimeout etc...


Цитата(MrKit @  11.2.2007,  15:47 Найти цитируемый пост)
Что такое Spy++

а поиском религия пользоваться запрещает???? хотябы на этом форуме.
это такая простенькая программка, что позволяет дарг-н-дропом определить хэндл, имя класса окна. отследить сообщения, что окну приходят.

почитай умных книг) Рихтера там, Руссиновича) очень помогает... мне по крайней мере помогло


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
MrKit
Дата 13.2.2007, 12:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Проблему решил, но не до конца: имеется трудность с передачей приложению комбинации клавиш Ctrl+End.

После поисков, получилось решить это:
Код

  SetForegroundWindow(h); // âûäåðãèâàåì îêíî íà ïåðåäíèé ïëàí
  Windows.SetFocus(h); // ïåðåäàåì åìó ôîêóñ
  // "íàæèìàåì" Ctrl+End
  keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL, 0), 0, 0);
  keybd_event(VK_END, MapVirtualKey(VK_END, 0), 0, 0);
  keybd_event(VK_END, MapVirtualKey(VK_END, 0), KEYEVENTF_KEYUP, 0);
  keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL,0), KEYEVENTF_KEYUP, 0);


но в данном подходе тот факт, что окно приходится вытаскивать на передний план и передавать ему фокус, является недостатком, который нужно устранить. Как можно это сделать?

В тестовом примере можно сделать вот так:
Код

  hself:=FindWindow('TfMyControl',nil);
  SetForegroundWindow(hself);
  Windows.SetFocus(hself);


Но этот код будет использоваться в фоновом потоке приложения. И возвращать фокус он должен не обязательно самому себе (своей проге), а любому приложению, которое было активно в момент запуска процедуры.
То есть, перед запуском процедуры нужно получить хэндл активного приложения, а после завершения - вернуть ему фокус. Как? И будет ли это правильно, или есть более красивое решение?

Это сообщение отредактировал(а) MrKit - 13.2.2007, 13:51
PM MAIL   Вверх
MetalFan
Дата 13.2.2007, 16:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

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



MrKit, я же говорил, посмотри spy++ом, что за сообщения идут тому окну и попробуй послать то же самое...
если не прокатит, то других решений я не вижу.


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
MrKit
Дата 13.2.2007, 20:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(MetalFan @  13.2.2007,  16:44 Найти цитируемый пост)
MrKit, я же говорил, посмотри spy++ом, что за сообщения идут тому окну и попробуй послать то же самое...
если не прокатит, то других решений я не вижу. 

Так я же посмотрел  smile   Еще раз спасибо, сделал через FindWindow и PostMessage. Управление курсором в нужном окне удалось, типа нажатий кнопок вверх-вниз и Enter.
Но передачу Ctrl+End пришлось делать уже по-другому, через keybd_event, и это отследить в Spy++ нельзя.
А последний вопрос - еще глубже. Поэтому и задал его.  smile 
PM MAIL   Вверх
MetalFan
Дата 13.2.2007, 22:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

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



Цитата(MrKit @  13.2.2007,  20:58 Найти цитируемый пост)
и это отследить в Spy++ нельзя.

прям таки нельзя?
ну может в твоей программе нельзя, но у меня вот что спай на Ctrl+End выдал:

Это сообщение отредактировал(а) MetalFan - 13.2.2007, 22:57

Присоединённый файл ( Кол-во скачиваний: 22 )
Присоединённый файл  spy__.jpg 34,62 Kb


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
MrKit
Дата 14.2.2007, 02:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Немного неточно выразился: отследить можно, но толку от этого нет:
попытка повторить Send или Post
Message(h,WM_KEYDOWN,VK_CONTROL,)
Message(h,WM_KEYDOWN,VK_END,)
Message(h,WM_KEYUP,VK_END,)
Message(h,WM_KEYUP,VK_CONTROL,)
(последний параметр не помню, но был указан правильный) ни к чему не приводит. Внятного объяснения этому я не нашел, но проблема эта описана (в Инете). Вроде как состояние нажатости Ctrl не запоминается прогой.
Поэтому пришлось использовать keybd_event.
PM MAIL   Вверх
MetalFan
Дата 14.2.2007, 12:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

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



MrKit, можно попробовать присоединить поток в котором создано то окно к очереди ввода... см. AttachThreadInput


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
MrKit
Дата 16.2.2007, 13:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Возникла еще одна проблемка. "нажатия клавиш" посылаются не только указанному приложению, но и тому, которое активно в данный момент. Как такое может быть?
Хэндл получаю след. образом:
Код

function GetADNewsListHandle:HWND;
 var h:HWND;
 begin
  h:=FindWindow('TMainForm',nil);
  h:=FindWindowEx(h,0,'MDIClient',nil);
  h:=FindWindowEx(h,0,'TNewsForm',nil);
  h:=FindWindowEx(h,0,'TPanel',nil);
  Result:=FindWindowEx(h,0,'TADGrid',nil);
 end;

нажатие клавиши:
Код

procedure pushEnter(hAD:HWND);
 begin
  PostMessage(hAD,WM_KEYDOWN,$0d,$001c0001); // Enter
  PostMessage(hAD,WM_CHAR,$0d,$001c0001);
  PostMessage(hAD,WM_KEYUP,$0d,$001c0001);
 end;

общий вызов соответственно
Код

  hAD:=GetADNewsListHandle;
  pushEnter(hAD);

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: WinAPI и системное программирование"
Snowybartram
MetalFanbems
PoseidonRrader
Riply

Запрещено:

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

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

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

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

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


 




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


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

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