使用代码模拟窗口拖放?

时间:2014-02-21 14:37:48

标签: c# c++ c winapi drag-and-drop

我想我过去可能会问过类似的问题,但我仍然被卡住了......

作为自动化流程的一部分,我必须将特定的媒体文件子集“导入”一个封闭源的第三方应用程序(Dartfish,这很重要)。 情况如下:

  • 媒体(视频)文件都在一个文件夹中(其中有1000个,遗憾的是重组不是一个选项)。
  • 在我写的脚本的任何给定迭代中,只有13个特定的文件必须导入到应用程序中。
  • 应用中没有必须接收文件的导入功能。
  • 同一个应用程序 允许您将文件拖放到特定窗格中,这样您就可以实际导入它们。

我正在使用的当前解决方法非常不稳定和丑陋,并使用复杂的正则表达式查询过程来隔离Xplorer2中的文件,然后使用AutoIT选择它们,然后最终将它们拖到应用程序中。

建议的解决方案:

我需要一种方法将任何给定时间所需的视频文件的特定子集拖放到此应用程序中,最好不要自动执行点击和光标移动(此设置中有太多故障点)。

我基本上只是将一个文件名列表传递给应用程序(通过拖动它们),所以我认为必须有一种方法可以在代码中自动执行这种拖放操作 - 也许使用C / C#/ C ++和Windows API?如果解决方案可以某种方式移植到Python,则可以获得奖励......但不是必需的。

如果有人能指出我正确的方向(编程语言并不重要;我将学习我需要知道的任何东西),最好给我一个基本的大纲或示例,说明如何完成这样的任务, 我真的很感激!这已经让我疯了一年多了!

2 个答案:

答案 0 :(得分: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)使用带有WH_CALLWNDPROC类型的SetWindowsHookEx安装全局钩子(需要额外的dll)

3)创建包含13个名称的固定文件

4)将steip 1中注册的唯一消息发送到目标窗口

5)你的钩子将加载到目标进程

6)内部钩子程序检查消息

7)如果消息是您的唯一消息

7.1)获取目标窗口的IDropTarget

7.2)从固定文件中加载名称

7.3)使用您的文件创建IDataObject

7.4)调用IDropTarget.DragEnter

7.5)调用IDropTarget.Drop

8)如果尚未处理所有文件,请转到3

9)卸载全局挂钩

更新2

您也可以尝试从钩子dll向目标窗口发送WM_DROPFILES消息。

答案 1 :(得分:0)

鼠标移动/点击可能是这种情况下的最佳解决方案。这是你可以尝试的东西。假设您使用的是Windows,因为您将c#放在标题中

  1. 打开文件夹
  2. 将鼠标移动到文件夹的搜索框(不必是硬编码坐标,某些GUI工具可以识别它)
  3. 使用send string方法输入您要导入的文件的名称
  4. 移动鼠标以选择第一个结果
  5. 鼠标按下
  6. 使用像素检测或GUI工具的检测来确定您希望放置的面板的坐标
  7. 放弃它并做一些错误检查。
  8. OR

    如果您是Windows专家,可以尝试进行一些进程间通信,将拖放事件发送给程序。