How to hide desktop icons programmatically?

Viewed 14694

How can I show/hide the desktop icons programmatically, using C#?

I'm trying to create an alternative desktop, which uses widgets, and I need to hide the old icons.

7 Answers

Even though this is quite old when I tried Ondrej Balas's answer, one problem I found with this solution is that it does not work if the ToggleDesktop command is used to show the desktop ( also if wallpaper rotation is enabled ).

In both of these cases the SHELLDLL_DefView window, which is the recipient of the toggleDesktopCommand in the ToggleDesktopIcons function, is not a child of the "Program manager" window but of a 'WorkerW" window. (see WinApi - How to obtain SHELLDLL_DefView and Windows Desktop ListView Handle.

Based on those and building upon Ondrej Balas's earlier answer change the ToggleDesktopIcons function to be :

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

And add a GetDesktopSHELLDLL_DefView function:

    [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;
    }

Now regardless of the desktop toggle or wallpaper rotation the ToggleDesktopIcons should always work.

For reference this is my toggle desktop function which caused the issue with the original ToggleDesktopIcons function

static public void ToggleDesktop(object sender, EventArgs e)
        {
            var shellObject = new Shell32.Shell();
            shellObject.ToggleDesktop();
        }

In response to James M, this function returns the current state:

bool IconsVisible()
{
    var hWnd = GetDesktopListView();
    var info = new User32.WINDOWINFO(null);
    User32.GetWindowInfo(hWnd, ref info);
    return (info.dwStyle & User32.WindowStyle.WS_VISIBLE) == User32.WindowStyle.WS_VISIBLE;
}

Nice topic. Without actually creating a different desktop it would be visually pleasant to have the running applications minimized in the same swoop.

Related