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

时间:2010-12-23 18:40:02

标签: delphi winapi

我尝试检查当前活动窗口是否是桌面做某事,我在计时器中写下了代码,但GetDektopWindow& GetForegroundWindow的值不相同:

  if GetForegroundWindow = GetDesktopWindow then
    // Do something

这是怎么做到的?

3 个答案:

答案 0 :(得分:5)

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

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

使用(sharpe)唯一的非资源管理器shell但它失败了。

<强>更新

有时桌面的窗口层次结构不同(参见Andreas的评论)。下面的镜头是Spy ++在Windows 7的桌面图片旋转功能被激活时所采取的措施。一些'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的孩子。 OTOH当'WorkerW'是活动窗口时,如果第一个孩子不是'DefView'而又是另一个'WorkerW',代码将迭代。

答案 1 :(得分:2)

一个很好的工具,用于确定窗口父/子关系,窗口类等的结构,是Greatis Software的WinDowse。 http://www.greatis.com/delphicb/windowse/ 我会从那里开始。我会将GetForegroundWindow和GetDesktopWindow(等等)的值输出到测试应用中的标签上。因此,当您使用WinDowse实时查看时,您可以看到这些值是什么。

答案 2 :(得分:0)

我搜索一下这个,GetWindowDesktop返回桌面窗口的句柄,但桌面窗口在另一个名为shell的窗口下,所以当你切换到dektop时你真的转到shell窗口并且必须得到shell句柄,如果你终止shell的进程窗口(explorer.exe)然后你可以看到真正的dektop窗口。