Имитация перетаскивания окон с помощью кода?

0

Я думаю, что, возможно, я задал аналогичный вопрос в прошлом, но я все еще застрял...

В рамках автоматизированного процесса я должен "импортировать" определенное подмножество медиафайлов в стороннее приложение с закрытым исходным кодом (Dartfish, если это имеет значение). Вот ситуация:

  • Файлы мультимедиа (видео) находятся в одной папке (их насчитывается 1000, а реорганизация - не вариант).
  • На любой заданной итерации сценария, который я пишу, в приложение нужно импортировать только 13 конкретных файлов.
  • В приложении нет функции импорта, которая должна получать файлы.
  • Это же приложение позволяет вам рисовать и удалять файлы в определенную область, и это позволяет существенно импортировать их.

Нынешний обходной путь, который я использую, очень нестабилен и уродлив, и использует сложную процедуру запросов regex для изоляции файлов в Xplorer2, а затем использует AutoIT для их выбора и затем, наконец, перетаскивает их в приложение.

Предложенное решение:

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

Я просто просто передаю список имен файлов в приложение (перетащив их туда), поэтому я считаю, что должен быть способ автоматизировать это перетаскивание исключительно в коде - возможно, используя C/С#/C++ и API окон? Бонусные очки, если решение можно портировать на Python как-то... но не обязательно.

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

Теги:
winapi
drag-and-drop

2 ответа

2

1) Внедрение в целевой процесс

2) Получить IDropTarget целевого окна

function GetDropTargetFromWnd(AWnd: HWND): IDropTarget;
var Unknow: IUnknown;
begin
  Unknow := IUnknown(GetProp(AWnd, PChar(GlobalFindAtom('OleDropTargetInterface'))));
  if Assigned(Unknow) then
    Unknow.QueryInterface(IDropTarget, Result)
end;

3) Создайте IDataObject с вашими файлами

4) Вызовите IDropTarget.DragEnter

5) Вызовите IDropTarget.Drop

Обновленный алгоритм:

1) Зарегистрируйте свое уникальное сообщение с помощью RegisterWindowMessage

2) Установите глобальный крючок с помощью SetWindowsHookEx с типом WH_CALLWNDPROC (требуется дополнительная dll)

3) Создать фиксированный файл с 13 именами

4) Отправлять уникальное сообщение, зарегистрированное в окне 1 на целевое окно

5) Вы подключаетесь к целевому процессу

6) Сообщение о проверке процедуры внутри крюка

7) Если сообщение является вашим уникальным сообщением

7.1) Получить IDropTarget целевого окна

7.2) Имена загрузок из фиксированного файла

7.3) Создайте IDataObject с вашими файлами

7.4) Вызовите IDropTarget.DragEnter

7.5) Вызовите IDropTarget.Drop

8) Если все файлы еще не обработаны, перейдите к 3

9) Удалить глобальный крючок

Обновление 2

Также вы можете попробовать отправить сообщение WM_DROPFILES в целевое окно из вашей DLL-оболочки.

  • 0
    Хм, интересно ... Я на самом деле никогда не думал об этом. Будет ли это стабильным решением (например, работать последовательно и не приводить к сбою приложения хоста)? Я выполнил тривиальную инъекцию DLL раньше, поэтому я хочу попробовать это ...
  • 0
    Стабильность будет зависеть от того, как вы реализуете алгоритм :)
Показать ещё 6 комментариев
0

Мышь move/click, вероятно, является лучшим решением в этом случае. Вот что вы можете попробовать. Предполагая, что вы используете окна, так как вы вставляете С# в заголовок

  1. открыть папку
  2. переместите мышь в поле поиска папки (не обязательно должна быть жестко закодированная координата, какой-то инструмент GUI может ее распознать)
  3. используйте метод отправки строки для ввода имени файла, который вы хотите импортировать
  4. переместите мышь, чтобы выбрать первый результат
  5. мышь вниз
  6. используйте обнаружение пикселей или обнаружение инструмента GUI для определения координаты панели, которую вы хотите сбросить
  7. сбросить его и выполнить некоторую проверку ошибок.

ИЛИ

Если вы специалист в области Windows, вы можете попытаться выполнить некоторую межпроцессную связь, чтобы отправить событие перетаскивания в программу.

  • 0
    Как я сказал в вопросе, я не буду автоматизировать курсор; Поверьте мне, когда я скажу, что я избил этот метод до смерти ... а потом еще немного. Есть слишком много вещей, которые могут пойти не так (например, если пользователь открыл другую панель в проводнике или аналогичным образом изменил некоторые настройки просмотра, это может привести к смещению файлов, чтобы они не всегда находились в разных координатах). Кроме того, я действительно вижу это как обходной путь. Ваше второе предложение - больше метод, который я желаю использовать; Я не специалист по Windows, но я знаком с WinAPI.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню