// not defined in D2007
function GetShellWindow: HWND; stdcall; external user32;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
if GetForegroundWindow = GetShellWindow then
[..]
end;
С единственной оболочкой без проводника, которую я использую (sharpe), она терпит неудачу.
Обновление:
Иногда иерархия окон рабочего стола отличается (см. Комментарии Андреаса). Ниже приведен пример Spy ++, когда активирована функция поворота изображения на рабочем столе Windows 7. Некоторое окно «WorkerW» занимает экран, и оно активируется при нажатии на рабочем столе. Так как GetShellWindow
возвращает дескриптор Progman, вышеуказанный тест не пройден.
На этом этапе может показаться разумным проверить, имеет ли переднее окно окно представления по умолчанию оболочки в качестве его непосредственного потомка, однако я видел несколько ссылок, которые указывают, что несколько окон «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».