我该如何以编程的方式操纵Windows桌面图标的位置?

33

几年前,我尝试编写一个小应用程序来保存我桌面上的图标位置,因为每次某个事件重置它们时,都需要将它们拖回到原来的位置,这让我感到很厌烦。但是我花费了太多时间去寻找一种查询、保存和重置我的图标桌面位置的方法,最终放弃了。

有人知道Windows在哪里存储这些信息,以及是否有API可以设置它们吗?

谢谢, Richard

5个回答

18

如果我没记错的话,桌面只是一个ListView,你需要向桌面的句柄发送 LVM_SETITEMPOSITION 消息。

我为一些C#代码搜索了一下,但没有找到例子,但我找到了下面这篇文章。 Torry: ...get/set the positions of desktop icons?。这是Delphi代码,但我认为它非常易读,通过一些P/Invokes,你可以将其翻译成C#。


我开始使用那段代码作为基础,但是在谷歌搜索其中的某些内容时,发现了我发布为答案的链接,所以我会将答案归功于你,谢谢。 - ZeroBugBounce
你好, 我不太明白如何发送“消息”!而且我也不确定如何实现它 - 给出的示例对我没有帮助,因为编写的代码没有解释。您能否给出一个简短的示例,说明如何获取图标的位置并重新排列它们? 感谢您的帮助。 - JanF
《操作桌面图标位置》(https://devblogs.microsoft.com/oldnewthing/20130318-00/?p=4933)解释了如何以*正确*的方式进行操作,而不依赖于实现细节(这些细节可能已经发生过变化)。 - IInspectable

2
桌面只是一个ListView控件,您可以获取其句柄并向其发送消息以使用LVM_SETITEMPOSITION移动图标。
然而,使用LVMGETITEMPOS获取图标位置会更加复杂。您必须将指向POINT结构的指针作为LPARAM传递。如果尝试这样做,可能会导致资源管理器崩溃。问题在于您传递了一个指向您地址空间中的指针,而控件将其解释为资源管理器地址空间中的指针。糟糕!
我使用的解决方案是将DLL注入到资源管理器进程中,并从那里发送消息。然后,您只需要找到一种方法将位置信息返回到您的进程即可。

3
请注意,您可能不需要注入DLL:您可以从进程外部发送消息,并使用VirtualAllocEx和Read/WriteProcessMemory在资源管理器的进程空间中设置内存,以便您拥有有效的LPARAM指针(从资源管理器的角度来看)可供使用。这种方式避免了与自己的进程通信或处理单独的DLL的麻烦。 - BrendanMcK
《操作桌面图标位置》(https://devblogs.microsoft.com/oldnewthing/20130318-00/?p=4933)解释了在不依赖于实现细节(可能会发生变化)的情况下,进行此操作的*正确*方式。 - IInspectable

1

我仍在研究中,一旦我最终获得可行结果,我会发布出来。我发布这篇文章是因为,在Davy的帖子间接帮助下,我也发现了一个经典的VB实现:

使用进程内存通信随机排列桌面图标

那很可能成为我的代码基础。


0

0

我对API一无所知,但我知道Ultramon(http://www.realtimesoft.com/ultramon/)包括了一个功能来保留图标位置(虽然我从未用过它来保留图标位置,但它对于使用多个显示器非常重要)。最新的beta版本在Vista上运行得非常完美(除了通过RDP最初登录我的机器时有时会出现一些小问题),当然,在XP上也没有任何问题。我现在已经使用它四年了。

还有,我提到它是最适合使用多个显示器的实用工具了吗?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接