开发者

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;
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜