Old Delphi hide/show desktop icons method not working under Windows 7 64 Bit
I have a Delphi 2010 app whi开发者_运维百科ch shows/hides the desktop icons under XP fine. However under my Window 7 test environment (happens to be 64 bit) the icons don't disappear.
Here is the critical code I am using (for the hide):
ShowWindow(FindWindow(nil, 'Program Manager'), SW_HIDE );
I have found I can set the registry:
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced]
"HideIcons"=dword:00000001
And that works fine if I restart windows (or kill explorer and restart it), however is there a way to get the old code to work and/or tell the desktop to reload using the new registry information without such radical methods.
Thank in advance.
Use SHGetSetSettings function. You're interested in fHideIcons field and corresponding SSF_HIDEICONS flag.
Alternatively, you can use corresponding group policy.
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.
Use 'ProgMan' instead of 'Program Manager'.
Works in Win 7 32 bits (don't have my 64 bits available here).
procedure ShowDesktopIcons(const Visible: Boolean);
var
h: THandle;
begin
h := FindWindow('ProgMan', nil);
if h = 0 then
RaiseLastOSError;
if Visible then
ShowWindow(h, SW_SHOW)
else
ShowWindow(h, SW_HIDE);
end;
procedure TForm1.btnHideClick(Sender: TObject);
begin
ShowDesktopIcons(False);
end;
procedure TForm1.btnShowClick(Sender: TObject);
begin
ShowDesktopIcons(True);
end;
精彩评论