如何获取桌面的窗口句柄?

Suj*_*osh 12 c++ windows shell winapi desktop

Windows API提供了一个API GetDesktopWindow(),它返回窗口句柄

但是我用Spy ++测试过,我发现桌面的窗口句柄和"Windows桌面"的窗口句柄是不一样的.

由于"Windows桌面"是列表视图,我是否需要执行以下操作

1) HANDLE hWnd = GetDesktopWindow() ;
2) FindWindow(hWnd, ..... ) with the SyslistView32 as the Window class.
Run Code Online (Sandbox Code Playgroud)

一旦我得到Window句柄,我想使用SendMessage()进行操作,例如获取所选文件名,选择的文件数等.

请提出你的意见.我正在使用Windows SDk执行此操作

Cod*_*ray 18

鉴于最近关于Meta抱怨的讨论,像这样的问题"没有得到妥善回答",我将试着回答这个问题.并不意味着我认为meklarian的答案很糟糕 - 事实上,从它开始.但它显然被认为不能令人满意,所以也许我可以填写一些额外的细节.

您的问题源于对桌面窗口实际上存在的相当普遍的混淆.该GetDesktopWindow功能确实恰恰就是它的文档做的事:它返回一个句柄到桌面窗口.但是,这与包含桌面图标的窗口不同.这是一个完全不同的窗口,它首次出现在Windows 95中.它实际上是一个ListView控件设置为"大图标"视图,实际的桌面窗口作为其父窗口.

Windows Shell团队的开发人员Raymond Chen在以下Windows机密文章中提供了一些其他详细信息:来自Windows 3.0的剩余内容

[ ...]   在Windows 3.0中,桌面上的图标代表最小化的窗口,在Windows 95中,桌面充当图标容器.

Windows 95桌面实际上是一个由资源管理器创建的窗口,它覆盖了您的屏幕(但位于桌面上所有其他窗口的下方).那是显示你的图标的窗口.在它下面还有一个窗口管理器桌面窗口(如果你调用GetDesktopWindow,你得到的窗口),但是你从未看过它,因为它被Windows 95桌面所覆盖 - 就像我同事家里地下室的木镶板一样覆盖了原有的墙壁和墙后面的时间胶囊.

[ ...]

自从在Windows 95中推出以来,这种桌面设计基本保持不变.在典型的机器上,原始桌面仍然存在,但它完全由Explorer桌面覆盖.

总之,然后,该函数返回的窗口GetDesktopWindow实际的桌面窗口,这是我们在Windows 3.0中唯一返回的窗口.Explorer桌面(包含所有图标的桌面)只是位于桌面窗口顶部的另一个窗口(尽管一个完全覆盖原始窗口的窗口),直到Windows 95才添加.

如果您想获得Explorer桌面窗口的句柄,除了调用该GetDesktopWindow函数之外,还需要做一些额外的工作.特别是,您需要遍历实际桌面窗口的子窗口,以找到Explorer用于显示图标的窗口.通过调用FindWindowEx函数来获取层次结构中的每个窗口,直到找到所需的窗口为止.它的类名是SysListView32.您可能还希望使用该GetShellWindow函数,该函数返回Shell的桌面窗口的句柄,以帮助您入门.

代码可能看起来像这样(警告:此代码未经测试,我建议不要使用它!):

HWND hShellWnd = GetShellWindow();
HWND hDefView = FindWindowEx(hShellWnd, NULL, _T("SHELLDLL_DefView"), NULL);
HWND folderView = FindWindowEx(hDefView, NULL, _T("SysListView32"), NULL);
return folderView;
Run Code Online (Sandbox Code Playgroud)

我在那里注意到我实际上并不建议使用该代码.为什么不?因为在几乎每种情况下你都希望获得桌面窗口(实际桌面窗口或Explorer桌面)的句柄,你做错了.

这不是您应该如何与桌面窗口进行交互.事实上,你根本不应该与它进行互动!还记得你小时候学过的东西,你不应该在没有他们许可的情况下玩其他人的东西吗?那么,桌面属于Windows(更具体地说,属于Shell),并且它没有允许您玩玩具!和任何一个好孩子一样,当你尝试玩玩具而不问时,壳牌会受到影响.

同样的Raymond Chen在他的博客上发表了另一篇文章,详细介绍了一个非常具体的案例,名为桌面窗口有什么特别之处?

除了他给出的例子,这基本上不是UI自动化的方法.它太脆弱,太有问题,而且在未来版本的Windows上也有可能破坏.相反,定义您实际尝试完成的内容,然后搜索使您能够执行此操作的功能.

如果不存在这样的功能,那么要吸取的教训并不是微软只是想让开发人员更加努力.而是你不应该首先这样做.


mek*_*ian 8

如果您想要GetDesktopWindow()中定义的桌面窗口,请使用该窗口句柄.这是您应该用来查找顶级窗口和其他相关活动的窗口句柄.

您在Spy ++中看到的只是在会话中作为桌面绘制的内容.如果在Spy ++中使用自动定位,您将看到SysListView32声明的窗口是资源管理器shell的子窗口.对于需要访问此窗口的人来说,这种情况并不常见.此外,该窗口的存在可能会受到窗口版本之间的变化的影响.

编辑(附加信息)

如果您希望在实际的shell桌面上进行交互或放置内容,那么其他API可能会为您提供更好的服务.以下是两个可以实现此目的的API,具体取决于Windows的目标版本.

Windows边栏@ MSDN
这在Vista和Windows 7上可用

使用Active Desktop @ MSDN
虽然经常被用户和系统管理员禁用,但它在Windows 2000和XP上可用.