【问题标题】:Old Delphi hide/show desktop icons method not working under Windows 7 64 Bit旧的 Delphi 隐藏/显示桌面图标方法在 Windows 7 64 位下不起作用
【发布时间】:2011-03-29 18:36:06
【问题描述】:

我有一个 Delphi 2010 应用程序,可以很好地显示/隐藏 XP 下的桌面图标。但是在我的 Window 7 测试环境(恰好是 64 位)下,图标不会消失。

这是我正在使用的关键代码(用于隐藏):

ShowWindow(FindWindow(nil, 'Program Manager'), SW_HIDE );

我发现我可以设置注册表:

[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced]
"HideIcons"=dword:00000001

如果我重新启动 Windows(或杀死资源管理器并重新启动它),效果很好,但是有没有办法让旧代码工作和/或告诉桌面使用新的注册表信息重新加载,而无需这种激进的方法。

提前致谢。

【问题讨论】:

标签: delphi windows-7 icons desktop


【解决方案1】:

使用SHGetSetSettings function。您对 fHideIcons 字段和相应的 SSF_HIDEICONS 标志感兴趣。

或者,您可以使用corresponding group policy

【讨论】:

  • 这确实是个不错的方法。
  • @Alexander,如果你完成了这项工作,你也可以回答stackoverflow.com/questions/3326062/…
  • 不是该领域的专家 - 我只是快速搜索了一下。 这花了我 1 分钟的时间。我也通过相同的方法发布了您指定问题的答案。附言严重的是,我不明白为什么在 StackOverflow 上的任何“RTFM”答案都被否决(即使它在谷歌搜索词上有链接)。通过谷歌搜索官方文档以获得批准的解决方案,您将获得更多比从答案中使用黑客(注册表读/写、窗口操作等)更好的结果。
  • @Alexander - 我没有对任何事情投反对票,也没有看到对您的回答投反对票。但我能看出道理;如果 RTFM 的答案实际上不起作用......我提到的问题不是我的,我想如果你真的使用了你可以帮助那个人的方法,没有冒犯的意思!
  • @Alexander - 是的,我有时也注意到反对票并不稀缺。例如,我不理解对 François 回答的反对票,因为他没有回答 如何隐藏桌面图标,而是回答了一个关于为什么某些代码段不起作用的具体问题;预计他不会提出替代方案。此外,他还特意提到他没有办法在 64bit 上测试代码。好吧,也许我错过了……
【解决方案2】:

好的,这是修改后的 hackish 方法(对不起,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;

出现问题是因为“Progman”和 SysListView32 之间的父/子关系已从 XP 更改为 Vista/Win7(这正是您不应该使用 hack 的原因 ;-)。另外,在Win7(我的测试环境)下应用一个多图主题,更进一步改变了这种关系。因此,新例程会查看所有窗口,直到找到一个在其中一个下设置了“SHELLDLL_DefView”和“SysListView32”子级的窗口。然后它在全局变量 DeskHandle 中返回 SysListView32 的句柄。不优雅,不确定在未来的代码中是否可以使用,但可以在今天使用。

如果有人可以让 SHGetSetSettings 版本工作,那绝对是正确的方法,而不是这种垃圾。

【讨论】:

  • 我注意到使用 Delphi 2009 编译时对 Windows 7 64 位没有影响。
  • Andreas,你是对的,它只在某些情况下有效。问题在于主题。出于另一个原因,我使用了 Windows 7 Basic 主题并且代码有效。我将其归因于代码,而不是主题更改(哎呀!)。
  • 问题再次出在“Progman”窗口的位置。使用 Win 7 默认主题,结构如下所示:“->SysListView32 ->SHELLDLL_DEFView ->Progman” 使用主题:“->SysLIstView32 ->SHELLDLL_DefView ->WorkerW ->WorkerW ->Progman” 我正在尝试将 Delphi 放在一起2010 年获取 Progman 的代码,无论它嵌套多深(不同的主题可能会在堆栈中创建不同数量的 WorkerW(或其他类型)的 Windows。任何帮助将不胜感激,以便我更正答案。
  • 修改后的代码应该适用于 Win 7 和带有多张图片的主题,以及其他 XP 到 Win 7 的环境。
  • 警告:它总是返回 True!
【解决方案3】:

使用“ProgMan”而不是“程序管理器”。
适用于 Win 7 32 位(这里没有我的 64 位)。

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;

【讨论】:

  • Program Manager 仍然是 OP 正在使用的正确窗口 text,而您使用 classname - 那应该是 Progman每个 Win7x64。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-20
  • 2011-03-24
  • 1970-01-01
  • 1970-01-01
  • 2013-03-01
  • 1970-01-01
相关资源
最近更新 更多