我可以使用全局系统挂钩来捕获单击了哪个文件吗?

Posted

技术标签:

【中文标题】我可以使用全局系统挂钩来捕获单击了哪个文件吗?【英文标题】:Can i use Global System Hooks to capture which file was clicked on? 【发布时间】:2013-01-14 00:59:57 【问题描述】:

我是 Windows 编程新手,主要完成 Java(Java SE、Java ME、android、Java EE),所以要详细和温和。

我想捕获“在 Windows 中单击的文件/路径的名称,例如单击桌面上的文件”?

进一步研究http://www.codeproject.com/Articles/6362/Global-System-Hooks-in-NET,这是一个小的c#/c++ 不错的应用程序,它使用Global System Hooks 来捕获坐标、点击等鼠标事件。

那么捕获文件图标事件的正确 API 或全局系统挂钩是什么?

【问题讨论】:

【参考方案1】:

没有单一的 API 可以提供这种详细程度。

SetWindowsHookEx()WH_MOUSEWH_MOUSE_LL 钩子,或RegisterRawInputDevices() 传递的WM_INPUT 消息可以判断鼠标何时被交互,GetCursorPos() 函数可以告诉您在哪里鼠标光标在单击时位于屏幕上,但它无法告诉您单击的是什么。您必须手动解决。

例如,Desktop 是作为 ListView 控件实现的,因此您可以使用WindowFromPoint()GetDesktopWindow() 函数来检查鼠标是否位于对应于桌面窗口本身而不是应用程序窗口的坐标处,以及如果是这样,则使用LVM_HITTESTLVM_GETITEM 消息来确定桌面上的哪个图标被单击并提取其显示文本。然后使用SHGetDesktopFolder() 函数和IShellFolder 接口或SHParseDisplayName() 函数来解析该文本并查看它是否返回代表路径/文件的PIDL,如果是则使用SHGetPathFromIDList() 来获取实际路径/文件名。

如果您想用 Windows 资源管理器应用程序做同样的事情,它会变得有点复杂。使用WindowFromPoint()GetWindowThreadProcessId()OpenProcess()EnumProcessModules() 确定鼠标是否位于 Windows 资源管理器应用程序上。但是,它的 UI 从 Windows 版本更改为下一个版本,但要点是您必须通过 AttachThreadInput()GetActiveWindow() 手动定位焦点控件,检查它是否是 TreeView/ListView 控件,如果是则使用特定于控件的消息,用于获取有关鼠标光标坐标下方的项目/图标的信息,并再次使用IShellFolder 来确定该项目/图标的文本实际代表什么。

Shell 编程是一个非常复杂的系统,不适合虚心进行交互。所以你需要问自己,为什么你首先需要这些信息?

【讨论】:

以上是关于我可以使用全局系统挂钩来捕获单击了哪个文件吗?的主要内容,如果未能解决你的问题,请参考以下文章

是否可以从 .NET 的全局键盘挂钩中确定当前用户

如何使用 Detours 挂钩 exe 函数?

区分鼠标设备和低级鼠标挂钩

全局键盘挂钩

Java 系统范围的键盘快捷键

注册一个全局钩子来检测鼠标是不是拖动文件/文本