检查当前活动窗口是否为桌面

3

我尝试检查当前活动窗口是否为桌面,如果是,则执行某些操作。我在计时器中编写了以下代码,但由GetDesktopWindow和GetForegroundWindow返回的句柄值不同:

  if GetForegroundWindow = GetDesktopWindow then
    // Do something

这怎么做呢?

如果“explorer”是shell,似乎“Progman”(程序管理器)会成为前景窗口,而不是“Desktop”。 - Sertac Akyuz
请确保在嵌入式系统、信息亭、POS以及其他通常不使用Windows Explorer作为shell的系统上进行检查。 - Jeroen Wiert Pluimers
3个回答

5
// not defined in D2007
function GetShellWindow: HWND; stdcall; external user32;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  if GetForegroundWindow = GetShellWindow then
    [..]
end;

使用我唯一使用的非资源管理器壳屏幕(sharpe),这个屏幕失败了。

更新:

有时桌面的窗口结构不同(请参见Andreas的评论)。下图是Windows 7激活桌面图片旋转功能时Spy++的截屏。某些“WorkerW”窗口接管了屏幕,当单击桌面时它会被激活。由于GetShellWindow返回“Progman”的句柄,上面的测试失败了。

Spy++.png

此时,测试前景窗口是否将shell的默认视图窗口作为其直接子窗口似乎是合理的,但我看到多个参考资料表明可能会嵌套多个'WorkerW'窗口。因此,我认为以下方法会更加可靠:

procedure TForm1.Timer1Timer(Sender: TObject);

  function HasDefViewChild(Wnd: HWND): Boolean;
  begin
    Result := Wnd <> 0;
    if Result then begin
      Result := FindWindowEx(Wnd, 0, 'SHELLDLL_DefView', nil) <> 0;
      if not Result then
        Result := HasDefViewChild(FindWindowEx(Wnd, 0, 'WorkerW', nil));
    end;
  end;

begin
  if HasDefViewChild(GetForegroundWindow) then
    [...]
end;

当前窗口为“Progman”时,此方法可行,因为“DefView”是“Progman”的子级。但是,如果“WorkerW”是活动窗口,则代码将迭代,如果第一个子级不是“DefView”,而是另一个“WorkerW”。


好的,我已经在64位的Windows 7 Home Premium上尝试过了,但它并不起作用。 - Andreas Rejbrand
@Andreas - 你能否检查一下它是否返回了一个不同的窗口或者是 null? - Sertac Akyuz
现在已经使用一台7-Pro 64位的计算机进行了远程检查,它工作正常,很奇怪..是基本主题与主题化的区别吗? - Sertac Akyuz
@Andreas - 非常感谢,正是我想要的。不幸的是,这些句柄并没有在我的脑海中产生什么印象。稍后,我只是计划检查前景是否在 shell 窗口的子链中。与此同时,我认为这个答案值得一些负面评价...无论如何,再次感谢。 - Sertac Akyuz
似乎这与主题无关,在这种情况下,前景窗口与 shell 窗口没有关系。我更新了我的答案,加入了我所发现的内容。 - Sertac Akyuz

2
一个用于确定窗口父/子关系、窗口类等结构的好工具是Greatis Software的WinDowse。 http://www.greatis.com/delphicb/windowse/ 我会建议从这里开始。然后,将GetForegroundWindow和GetDesktopWindow(等等)的值输出到测试应用程序中的标签上。这样你就可以在实时使用WinDowse时查看这些值。

确实。首先,我从来没有完全理解GetDesktopWindowGetShellWindow之间的区别是什么。 - Andreas Rejbrand
@Andreas - 我相信这就是答案,“Progman”将是外壳窗口,因此是前景窗口。 - Sertac Akyuz

0
我在搜索这个问题,GetWindowDesktop返回桌面窗口的句柄,但是桌面窗口在另一个名为shell的窗口下面,所以当你切换到桌面时,实际上你切换到了shell窗口,必须获取shell句柄,如果终止shell窗口(explorer.exe),那么你就可以看到真正的桌面窗口。

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