我尝试检查当前活动窗口是否为桌面,如果是,则执行某些操作。我在计时器中编写了以下代码,但由GetDesktopWindow和GetForegroundWindow返回的句柄值不同:
if GetForegroundWindow = GetDesktopWindow then
// Do something
这怎么做呢?
我尝试检查当前活动窗口是否为桌面,如果是,则执行某些操作。我在计时器中编写了以下代码,但由GetDesktopWindow和GetForegroundWindow返回的句柄值不同:
if GetForegroundWindow = GetDesktopWindow then
// Do something
// 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”的句柄,上面的测试失败了。
此时,测试前景窗口是否将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”。
GetDesktopWindow
和GetShellWindow
之间的区别是什么。 - Andreas Rejbrand