'Keeping window visible through "Show Desktop"/Win+D

I'm creating a desktop gadget, and am running into problems. The window will be hidden by the "Show Desktop" command - STOP, I know what you're thinking and don't need "you shouldn't do this" comments - and I want to stop it. The whole point of a desktop gadget is, after all, that it sticks to the desktop.

Just to clarify - I don't want a TopMost window. I don't want to actually STOP the "Show Desktop" command, just ignore it. All I want is for my desktop gadget to stay visible on the desktop, disrupting as little normal functionality as usual.

Any ideas? My current method is a P/Invoke snippet I found on Google, setting the form's parent to Progman or something. Problem is that this seems to force the window showing in the taskbar, which I don't want.



Solution 1:[1]

Maybe a bit late for an answer to your question, but nevertheless here the answer, which I seem to have found:

    [System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)]
    static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

    [System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)]
    static extern IntPtr FindWindowEx(IntPtr hP, IntPtr hC, string sC, string sW);

    void MakeWin()
    {
        IntPtr nWinHandle = FindWindowEx(IntPtr.Zero, IntPtr.Zero, "Progman", null);
        nWinHandle = FindWindowEx(nWinHandle, IntPtr.Zero, "SHELLDLL_DefView", null);
        SetParent(Handle, nWinHandle);
    }

"MakeWin" should be called in the Constructor of the Form, best before "InitializeComponent". Works good for me at least under Win7.

Solution 2:[2]

Edit: This does not work for Windows 11, as it seems the behavior of Win+D has changed.

Adding my twist on this for WPF forms. The above code did not work because of the WPF window handle. So full code for this to work for WPF (win 10):

[System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindowEx(IntPtr hP, IntPtr hC, string sC, string sW);

void MakeWin()
{
    IntPtr nWinHandle = FindWindowEx(IntPtr.Zero, IntPtr.Zero, "Progman", null);
    nWinHandle = FindWindowEx(nWinHandle, IntPtr.Zero, "SHELLDLL_DefView", null);
    var interop = new WindowInteropHelper(this);
    interop.EnsureHandle();
    interop.Owner = nWinHandle;
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Frank-Thomas Ernst
Solution 2