【问题标题】:c# read syslistview32 items tooltips via winapic# 通过winapi读取syslistview32项工具提示
【发布时间】:2012-07-13 11:07:16
【问题描述】:

我想编写一个应用程序,它在 windows xp 下按顺序读取快速启动项,就像它们位于任务栏中一样, 并为每个项目设置热键。 windows + 1 应该启动第一个应用程序 windows + 2 第二个,等等。 (如在 Windows 7 中)

所有这些项目都在一个文件夹中找到,但如果我阅读此文件夹中的项目,我不会得到这些项目的正确顺序。

我找到了两个解决方案来获得正确的顺序 - 第一个:

在注册表中找到了一个条目,它保存了它们的位置,但不是纯文本。我不知道怎么读这个,也不能逆向引擎。

第二个: 通过winapi从任务栏中读取项目工具提示,所以我可以(如果没有同名的项目)通过快速启动文件夹中的名称进行搜索。 快速启动栏只是一个列表视图(syslistview32)。 通过sendmessage,我可以计算项目并启动一个(假装点击这个项目),但是我怎么能阅读工具提示? 我用谷歌搜索了很多,尝试了所有方法,但我没有运行它。

我希望你有任何 sn-ps 来解决这个问题。

干杯

【问题讨论】:

    标签: c# winapi sendmessage syslistview32 quicklaunch


    【解决方案1】:

    以编程方式确定快速启动工具栏中项目的顺序本质上是脆弱的。没有为此公开 API,这意味着它可能会在未来的 Windows 版本中发生变化,从而破坏您依赖于对未记录实现细节的假设的代码。

    但是,在这种特定情况下,问题比通常情况下要少,因为“快速启动”工具栏不再存在(或者,至少没有人再使用它了)。使用快速启动工具栏的最后一个 Windows 版本是 Vista,因此如果您确保您的代码与 Vista 和更早版本兼容,您应该没问题。无论如何,它不适用于较新的版本。

    快速启动工具栏中项目的位置存储在注册表中的以下键中:

    HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Streams\Desktop
    

    您可以从那里提取信息,对其进行解析和解释,然后随意使用它。正如您所提到的,这些信息不是以纯文本形式存储的,因为这对于 shell 加载和解析自身来说会非常慢。由于这是未记录的并且不是为客户使用而设计的,因此他们在使其用户(或开发人员)友好方面没有特别的好处。重要的是什么对 shell 最有效,从其内部结构存储二进制信息是显而易见的选择。

    您需要对其进行逆向工程,以使其对您有用。我采取的方法可能是通过在快速启动栏中以特定顺序设置具有几个项目的测试环境,从注册表中导出信息,移动其中一个项目,从注册表,并比较两个导出的注册表文件以查看发生了什么变化。冲洗并根据需要重复多次以推断图案。 (真的让你想知道为什么这么多开发人员实际上确实花时间对 Windows 的未记录方面进行逆向工程,不是吗?)

    另一种选择是使用 Spy++ 来调查实现任务栏及其快速启动工具栏的窗口。我没有 Windows 7 之前的系统,但从问题来看,您已经这样做了,并确定快速启动工具栏是使用标准 ListView 实现的。如果您知道该窗口的名称(及其祖先窗口的名称),您可以遍历这些窗口以获得您感兴趣的窗口的句柄。然后您可以确定窗口中项目的顺序就好像它是您自己的应用程序中的标准 ListView。

    ListView 控件的文档是here;这应该让您朝着正确的方向开始。您可以通过发送LVM_GETITEMTEXT message 来获取其中一个子项的文本。

    这可能是更简单的方法。同样的警告适用 - 没有什么可以阻止未来版本的 Windows 更改这些窗口的名称或任务栏的实现方式,但是因为具有快速启动工具栏的唯一版本的 Windows 已经发布(因此不太可能改变),这可能不是一个大问题。

    再一次,考虑到快速启动工具栏已经过时的事实,我很难理解为什么这项努力甚至值得投入开发人员的时间。

    此外,即使您编写并安装了该程序,也要考虑当用户将新项目添加到快速启动工具栏或重新排列现有项目时会发生什么。您的实用程序如何知道这一点并相应地调整键盘快捷键?如果安装程序从快速启动工具栏中添加/删除项目怎么办?

    【讨论】:

    • 嗨,感谢您的回答。我尝试了这种逆向工程方式,但没有成功。我知道我必须发送 lvm_getitemtext 消息 - 但发送它没有成功,也许我做错了,我从来没有收到有用的内容。但我知道我的句柄是对的,因为我可以成功计数项目,并且单击一个也可以。
    • 要确定用户何时添加新项目,我可以使用文件系统监视器查看快速启动项目的文件夹。对于更改订单时的事件,注册表观察器可能会很有用,如果注册表内容及时更改,这将是完美的。但我不这么认为。我也可以在按下热键时刷新所有项目(通过itemtext),然后执行任何项目,所以我总是有正确的顺序。另一种解决方案是在程序开始时重新加载所有项目,我认为快速项目不会经常移动。(通过添加一个新项目我有一个事件)
    猜你喜欢
    • 1970-01-01
    • 2020-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多