Ok, here is the revised hackish method (sorry Alexander!):
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;
The issue arises because parent/child relationship between "Progman" and SysListView32 has changed from XP to Vista/Win7 (precisely why you shouldn't use a hack ;-). In addition, applying a theme with multiple pictures under Win7 (my test environment) changes this relationship even further. Therefore the new routine looks through all windows until it finds one with a "SHELLDLL_DefView" and "SysListView32" child set under one. It then returns the handle of SysListView32 in the global variable DeskHandle. Not elegant, not sure to work in future code, but works today.
If anyone can get a SHGetSetSettings version to work, that is definitely the correct way to go, not this junk.