Хорошо, вот исправленный хакерский метод (извините, Александр!):
var
DeskHandle : HWND;
...
///////////////////////////////////////////////////////////////////////
// Callback function for EnumWindows
///////////////////////////////////////////////////////////////////////
function MyGetWindow (Handle: HWND; NotUsed: longint): bool; stdcall;
var
hChild : HWND;
begin
if handle <> 0 then
begin
hChild := FindWindowEx(handle, 0, 'SHELLDLL_DefView' ,nil);
if hChild <> 0 then
begin
hChild := FindWindowEx(hChild, 0, 'SysListView32' ,nil);
if hChild <> 0 then
begin
DeskHandle := hChild;
end;
end;
end;
result := TRUE;
end;
procedure ShowDesktopIcons(const Show : boolean) ;
begin
DeskHandle := 0;
EnumWindows(@MyGetWindow, 0);
if DeskHandle <> 0 then
begin
if Show then
begin
ShowWindow(DeskHandle, SW_SHOW );
end
else
begin
ShowWindow(DeskHandle, SW_HIDE );
end;
end;
end;
Проблема возникает из-за того, что отношения «родитель-потомок» между «Progman» и SysListView32 изменились с XP на Vista / Win7 (именно поэтому вы не должны использовать хак ;-) Кроме того, применение темы с несколькими изображениями под Win7 (моя тестовая среда) еще больше меняет эти отношения. Поэтому новая подпрограмма просматривает все окна, пока не найдет одно с дочерними элементами "SHELLDLL_DefView" и "SysListView32", установленными под одним. Затем он возвращает дескриптор SysListView32 в глобальной переменной DeskHandle. Не элегантно, не обязательно работать в будущем коде, но работает сегодня.
Если кто-то может заставить работать версию SHGetSetSettings, это, безусловно, правильный путь, а не этот мусор.