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

Delphi 检查是否为当前活动窗口桌面,delphi,winapi,Delphi,Winapi,我尝试检查当前活动窗口是否为桌面执行某些操作,我在计时器中编写了以下代码,但GetDektopWindow和GetForegroundWindow返回的句柄值不相同: if GetForegroundWindow = GetDesktopWindow then // Do something 如何做到这一点?Greatis软件的WinDowse是了解窗口父/子关系、窗口类等结构的一个很好的工具。 我会从那里开始。我会将GetForegroundWindow和GetDesktopWi

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

  if GetForegroundWindow = GetDesktopWindow then
    // Do something

如何做到这一点?

Greatis软件的WinDowse是了解窗口父/子关系、窗口类等结构的一个很好的工具。 我会从那里开始。我会将GetForegroundWindow和GetDesktopWindow(等等)的值输出到测试应用程序中的标签上。因此,当您使用WinDowse时,可以实时查看这些值是什么

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

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  if GetForegroundWindow = GetShellWindow then
    [..]
end;
我使用的唯一非浏览器shell(sharpe)失败了

更新:

有时桌面的窗口层次结构是不同的(参见Andreas的评论)。下面这张照片是Spy++在Windows7桌面图片旋转功能激活时拍摄的。一些“WorkerW”窗口占据了屏幕,它是在桌面上单击时被激活的窗口。由于
GetShellWindow
返回“Progman”句柄,因此上述测试失败。



在这一点上,测试前台窗口是否将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;
程序TForm1.Timer1Timer(发送方:TObject);
函数HasDefViewChild(Wnd:HWND):布尔型;
开始
结果:=wnd0;
如果有结果,那么开始
结果:=FindWindowEx(Wnd,0,'SHELLDLL_DefView',nil)0;
如果没有结果的话
结果:=HasDefViewChild(FindWindowEx(Wnd,0,'WorkerW',nil));
结束;
结束;
开始
如果HasDefViewChild(GetForeGroundIndow),则
[...]
结束;

当前景窗口是“Progman”时,这将起作用,因为“DefView”是“Progman的孩子”。当“WorkerW”是活动窗口时,如果第一个子窗口不是“DefView”,而是另一个“WorkerW”,则代码将迭代。

我搜索了一下,GetWindowDesktop返回桌面窗口的句柄,但桌面窗口位于另一个名为shell的窗口下,所以,当您切换到dektop时,实际上是切换到shell窗口,并且必须获得shell句柄,如果您终止shell窗口(explorer.exe)的进程,则可以看到真正的dektop窗口

如果“资源管理器”是shell,那么“Progman”(程序管理器)似乎会成为前台窗口,而不是桌面。请确保在嵌入式、kiosk、POS和其他系统上检查这一点,而Windows资源管理器通常不是shell。确实如此。首先,我一直不太明白
GetDesktopWindow
GetShellWindow
@Andreas之间的区别是什么-我相信这就是答案,“Progman”将是shell窗口,因此是前台窗口。我在Windows7 Home Premium中尝试过这一点,64位,它不工作。@Andreas-你想检查它是否返回不同的窗口或空值吗?现在用一个7-Pro 64位检查remote,它工作了,奇怪。。基本主题还是主题?。@Andreas-非常感谢,这正是我想要的。不幸的是,虽然把手没有击中我的头。一、 稍后,只需检查前景是否在shell窗口的子链中。同时,我认为这个答案值得投一些反对票。。无论如何,再次感谢。它似乎与主题无关,在这种情况下,前景窗口与外壳窗口没有关系。我用我的发现更新了答案。。