Старый метод скрытия / отображения значков рабочего стола Delphi не работает в Windows 7 64 Bit - PullRequest
2 голосов
/ 14 августа 2010

У меня есть приложение 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 (или убиваю проводник и перезапускаю его), однако есть способ заставить старый код работать и / или сказать рабочему столу перезагрузить, используя новую информацию реестра без таких радикальных методов.

Спасибо заранее.

Ответы [ 3 ]

4 голосов
/ 14 августа 2010

Использование функции SHGetSetSettings .Вас интересует поле fHideIcons и соответствующий флаг SSF_HIDEICONS .

В качестве альтернативы вы можете использовать соответствующую групповую политику .

2 голосов
/ 14 августа 2010

Хорошо, вот исправленный хакерский метод (извините, Александр!):

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, это, безусловно, правильный путь, а не этот мусор.

0 голосов
/ 14 августа 2010

Используйте «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;
...