使用 .Net 检测外部应用程序中的拖放操作
Posted
技术标签:
【中文标题】使用 .Net 检测外部应用程序中的拖放操作【英文标题】:Detect drag and drop operations in an external application using .Net 【发布时间】:2010-12-17 07:29:06 【问题描述】:我需要检测外部应用程序中的拖放操作,可以吗?我想写一个钩子来检测这些操作。谁能指出我可以尝试挂钩哪些消息或 api 函数以检测拖放事件的正确方向?我想在 C# 中执行此操作。
提前致谢。
【问题讨论】:
请多谈谈“外部”应用程序:它是由 ? (你?它可以是任何应用程序?):这是一个你有源代码的应用程序(在 C# 中?)。请准确说明正在拖动什么(或什么类型的东西),以及它们被拖放到哪里(进入您的应用程序?)。谢谢, 外部应用程序一直在运行,我没有源代码。我想检测应用程序何时开始和完成一些视觉元素(控件)的拖放并检测它们被释放的位置。 【参考方案1】:您可以通过两条明显的路径尝试此操作。
第一个是挂钩参与调解拖放操作的 OLE 函数。这假定其他应用程序正在使用真正的拖放,而不是某些内部版本。确定这一点超出了我的能力 - 无法访问该程序 - 但如果可以从这个外部应用程序拖动到其他一些应用程序窗口(包括桌面),这很好地表明该应用程序正在使用真实的东西。
您需要挂钩的函数是RegisterDragDrop,尽管DoDragDrop 也可能感兴趣。 RegisterDragDrop
被调用来注册一个放置目标,并让您有机会将 IDropTarget
包装成您想要的方式(大概是 IPC 到您的实际应用程序中),RevokeDragDrop 然后传递注册,但现在使用您的包装器对象。 IDropTarget::Drop 大概是您完成大部分 IPC 的地方。
第二个方法是在应用程序中注入一个 Windows 挂钩。这只有在您了解触发拖动的用户操作并能够检测到它们时才易于处理,因为您必须区分拖动操作和正常的键盘/鼠标操作。有问题的钩子是WH_CALLWNDPROC
钩子,注册到SetWindowsHookEx。基本上,您定义了一个WndProc
,它获取应用程序窗口执行的所有消息(包括鼠标移动),并由您决定拖动操作何时开始以及何时停止。
无论哪种情况,很多代码都可以用 C# 编写。使用 p\invoke,您可以访问SetWindowsHookEx,并且还可以在 C# 中实现 COM 对象(以及这些 COM 对象的包装器)。事实上,.NET 2.0 中已经有一个 IDropTarget 类;这可能已经是 COM 可见的了。
不幸的是,挂钩 API 的级别非常低,您通常必须使用 C 或 C++ 才能完成任何事情。我听说过关于 Detours 的好消息,以及来自 Microsoft 的消息。
【讨论】:
我尝试了这两种方法都没有成功,尽管我可能做错了。这确定有效吗? RegisterDragDrop 的问题似乎在于,如果您尝试挂钩的外部应用程序可能已经调用了该函数,并且您似乎无法进行两次注册。编辑:我尝试了 SetWinEventHook,而不是 SetWindowsHookEx。将对其进行测试!【参考方案2】:您能做的最好的事情就是挂接到外部应用程序。根据我的经验(我最后一次做这样的事情是在两年前),我可以实现准确挂钩的唯一方法是使用 C/C++ 和 C# 的混合。
要完成所有这些,您需要熟悉平台调用和 Windows SDK。有人可能会说您只需要 p/invoke 部分,但在我的探索中,我发现访问 SDK 中的头文件和库文件非常宝贵。此外,我发现 Spy++ 是一个很棒的帮助钩子开发的工具。
有很多关于挂钩 Windows 应用程序以及如何与外部进程通信的资源。我可以在这里列出任意数量,但我不确定您对技术文章和示例项目的偏好是什么。就我个人而言,我发现 codeproject.com 有很多项目都与一些非常好的解释挂钩。
祝你好运;我希望这会有所帮助。
【讨论】:
【参考方案3】:正如您自己提到的,您将需要使用 Windows-API - 因此我希望您对在 C# 中使用不安全代码有一些经验,或者考虑使用 C++。 MS 描述了一种方法here。 我的猜测是您需要查看 HCBT_ACTIVATE(窗口被激活)和 HCBT_CLICKSKIPPED(鼠标单击) - 但这只是一个猜测。 另一个想法可能是查看Auto It Window Info - 它具有分析窗口的功能 - 也许你可以在一个好的地方重复使用它 - 这样你就可以节省一些分析部分的工作。
【讨论】:
以上是关于使用 .Net 检测外部应用程序中的拖放操作的主要内容,如果未能解决你的问题,请参考以下文章
背水一战 Windows 10 (73) - 控件(控件基类): UIElement - 拖放的基本应用, 手动开启 UIElement 的拖放操作