Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 921
robhol Avatar asked Apr 04 '12 10:04

robhol


2 Answers

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.

like image 151
Frank-Thomas Ernst Avatar answered Nov 07 '22 04:11

Frank-Thomas Ernst


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;
}
like image 33
Wolf5 Avatar answered Nov 07 '22 04:11

Wolf5