Как скрыть иконки на рабочем столе программно? - PullRequest
11 голосов
/ 19 июня 2011

Как программно отобразить / скрыть значки на рабочем столе, используя C #?

Я пытаюсь создать альтернативный рабочий стол, который использует виджеты, и мне нужно скрыть старые значки.

Ответы [ 6 ]

20 голосов
/ 19 июня 2011

Вы можете сделать это с помощью Windows API. Вот пример кода на C #, который будет переключать значки на рабочем столе.

    [DllImport("user32.dll", SetLastError = true)] static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
    [DllImport("user32.dll", SetLastError = true)] static extern IntPtr GetWindow(IntPtr hWnd, GetWindow_Cmd uCmd);
    enum GetWindow_Cmd : uint
    {
        GW_HWNDFIRST = 0,
        GW_HWNDLAST = 1,
        GW_HWNDNEXT = 2,
        GW_HWNDPREV = 3,
        GW_OWNER = 4,
        GW_CHILD = 5,
        GW_ENABLEDPOPUP = 6
    }
    [DllImport("user32.dll", CharSet = CharSet.Auto)] static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);

    private const int WM_COMMAND = 0x111;

    static void ToggleDesktopIcons()
    {
        var toggleDesktopCommand = new IntPtr(0x7402);
        IntPtr hWnd = GetWindow(FindWindow("Progman", "Program Manager"), GetWindow_Cmd.GW_CHILD);
        SendMessage(hWnd, WM_COMMAND, toggleDesktopCommand, IntPtr.Zero);
    }

Это отправляет сообщение в дочернее окно SHELLDLL_DefView Progman, в котором указывается переключение видимости (путем добавления или удаления стиля WS_VISIBLE) его единственного дочернего элемента, «FolderView». «FolderView» - это фактическое окно, содержащее значки.

Чтобы проверить, видны ли значки или нет, вы можете запросить стиль WS_VISIBLE с помощью функции GetWindowInfo, показанной ниже:

    [return: MarshalAs(UnmanagedType.Bool)]
    [DllImport("user32.dll", SetLastError = true)]
    private static extern bool GetWindowInfo(IntPtr hwnd, ref WINDOWINFO pwi);

    [StructLayout(LayoutKind.Sequential)]
    public struct RECT
    {
        private int _Left;
        private int _Top;
        private int _Right;
        private int _Bottom;
    }

    [StructLayout(LayoutKind.Sequential)]
    struct WINDOWINFO
    {
        public uint cbSize;
        public RECT rcWindow;
        public RECT rcClient;
        public uint dwStyle;
        public uint dwExStyle;
        public uint dwWindowStatus;
        public uint cxWindowBorders;
        public uint cyWindowBorders;
        public ushort atomWindowType;
        public ushort wCreatorVersion;

        public WINDOWINFO(Boolean? filler)
            : this()   // Allows automatic initialization of "cbSize" with "new WINDOWINFO(null/true/false)".
        {
            cbSize = (UInt32)(Marshal.SizeOf(typeof(WINDOWINFO)));
        }

    }

Вот функция, которая вызывает вышеуказанный код и возвращает true, если окно видно, и false, если нет.

    static bool IsVisible()
    {
        IntPtr hWnd = GetWindow(GetWindow(FindWindow("Progman", "Program Manager"), GetWindow_Cmd.GW_CHILD), GetWindow_Cmd.GW_CHILD);
        WINDOWINFO info = new WINDOWINFO();
        info.cbSize = (uint)Marshal.SizeOf(info);
        GetWindowInfo(hWnd, ref info);
        return (info.dwStyle & 0x10000000) == 0x10000000;
    }

Код Windows API вместе с дополнительной информацией о стилях окна можно найти здесь: http://www.pinvoke.net/default.aspx/user32/GetWindowInfo.html

2 голосов
/ 27 апреля 2015

Другой подход - создать отдельный рабочий стол и показать его вместо этого. У него не будет иконок.

Приложение работает на отдельном рабочем столе

1 голос
/ 28 июня 2019

Несмотря на то, что он довольно старый, когда я попробовал ответ Ондрея Баласа , одна проблема, которую я нашел с этим решением, состоит в том, что оно не работает, если команда ToggleDesktop используется для отображения рабочего стола (также, если вращение обоев включен).

В обоих этих случаях окно SHELLDLL_DefView, которое является получателем команды toggleDesktopCommand в функции ToggleDesktopIcons, является не дочерним элементом окна «Диспетчер программ», а окна «WorkerW» (см. WinApi - Как получить SHELLDLL_DefView и дескриптор списка рабочего стола Windows .

Исходя из этого и опираясь на ранее ответ Ондрея Баласа, измените функцию ToggleDesktopIcons на:

static void ToggleDesktopIcons()
{
    var toggleDesktopCommand = new IntPtr(0x7402);
    SendMessage(GetDesktopSHELLDLL_DefView(), WM_COMMAND, toggleDesktopCommand, IntPtr.Zero);
}

И добавьте функцию GetDesktopSHELLDLL_DefView:

    [DllImport("user32.dll", SetLastError = true)]
    public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, string windowTitle);
    [DllImport("user32.dll", SetLastError = false)]
    static extern IntPtr GetDesktopWindow();

    static IntPtr GetDesktopSHELLDLL_DefView()
    {
        var hShellViewWin = IntPtr.Zero;
        var hWorkerW = IntPtr.Zero;

        var hProgman = FindWindow("Progman", "Program Manager");
        var hDesktopWnd = GetDesktopWindow();

        // If the main Program Manager window is found
        if (hProgman != IntPtr.Zero)
        {
            // Get and load the main List view window containing the icons.
            hShellViewWin = FindWindowEx(hProgman, IntPtr.Zero, "SHELLDLL_DefView", null);
            if (hShellViewWin == IntPtr.Zero)
            {
                // When this fails (picture rotation is turned ON, toggledesktop shell cmd used ), then look for the WorkerW windows list to get the
                // correct desktop list handle.
                // As there can be multiple WorkerW windows, iterate through all to get the correct one
                do
                {
                    hWorkerW = FindWindowEx(hDesktopWnd, hWorkerW, "WorkerW", null);
                    hShellViewWin = FindWindowEx(hWorkerW, IntPtr.Zero, "SHELLDLL_DefView", null);
                } while (hShellViewWin == IntPtr.Zero && hWorkerW != IntPtr.Zero);
            }
        }
        return hShellViewWin;
    }

Теперь, независимо от переключения рабочего стола или вращения обоев, ToggleDesktopIcons должны работать всегда.

Для справки: это моя функция рабочего стола, которая вызвала проблему с оригинальной функцией ToggleDesktopIcons

static public void ToggleDesktop(object sender, EventArgs e)
        {
            var shellObject = new Shell32.Shell();
            shellObject.ToggleDesktop();
        }
1 голос
/ 12 сентября 2016

Вы можете сделать это в RegEdit HKEY_CURRENT_USER \ SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Explorer \ Advanced изменить HideIcons на 1

    static void HideIcons()
    {
        RegistryKey myKey = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced", true);
        if (myKey != null)
        {
            myKey.SetValue("HideIcons", 1);
            myKey.Close();
        }
    }

Использовать класс реестра, как описано здесь.

http://msdn.microsoft.com/en-us/library/microsoft.win32.registry.aspx

1 голос
/ 19 июня 2011

Вы можете создать полноэкранное приложение и сделать его самым верхним окном.

Затем запустите приложение для Windows.

0 голосов
/ 20 июня 2011

Вы идете об этом неправильно.То, что вы действительно пытаетесь сделать, это заменить оболочку.В Windows это предусмотрено, поэтому вы должны просто воспользоваться этим.Напишите свою собственную оболочку для замены проводника.

...