6

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.

Blorgbeard
  • 101,031
  • 48
  • 228
  • 272
robhol
  • 195
  • 1
  • 11
  • So when the user clicks "show desktop", your gadget is hidden? Sounds plausible to me that you don't want that to happen as the built-in gadgets don't hide when I click show desktop. Is this a "true" gadget? I thought they were HTML, yet you mention top-most forms... – Adam Houldsworth Apr 04 '12 at 10:52
  • It's a Winforms app. I originally tried making a "sidebar"/desktop gadget, but I feel a lot more comfortable using C#, I also couldn't get it to look the way I want, no matter how much I messed around with stylesheets and whatnot. I gave up on it and decided to try to make my own independent gadget. – robhol Apr 04 '12 at 11:03
  • i dont think winforms is the way to go for what you are trying to achieve. better off with html – nawfal Apr 04 '12 at 12:25
  • 1
    see these links http://stackoverflow.com/questions/2672798/microsoft-chart-controls-for-microsoft-net-framework-4-0 http://stackoverflow.com/questions/1171588/c-sharp-tutorial-to-write-gadgets http://www.nikhilk.net/SidebarGadgets.aspx – nawfal Apr 04 '12 at 12:27
  • 7
    Only [desktop gadgets](http://windows.microsoft.com/en-US/windows/downloads/personalize/gadgets) are [allowed to "stick to" the desktop](http://blogs.msdn.com/b/oldnewthing/archive/2011/06/17/10175502.aspx). – Raymond Chen Apr 04 '12 at 14:24

2 Answers2

8

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.

  • does this avoid the problem of the OP that the window shows on the taskbar? – Emile Sep 15 '15 at 15:28
  • 1
    yes :) It does NOT show any taskbar icon. But until now I got another problem: the window can't appear ABOVE other (normal) windows. I guess, reason of both is, because it has become a child window of the "SHELLDLL_DefView". I'm just experimenting with "WS_POPUP"-style. – Frank-Thomas Ernst Sep 18 '15 at 19:46
  • 1
    This doesn't seem to work in Windows 10, as noted in http://stackoverflow.com/q/35045060/2551829. I don't really understand what your code is doing enough to try and build off of that concept to make it work on 10. Do you know how to modify it to make it work in Windows 10? – DeadEli Mar 23 '16 at 22:00
  • You're right it does work. I apparently was just doing something else in that project that was conflicting with it. – DeadEli Apr 02 '16 at 05:30
  • just tried with a simple WPF app on Windows 10 (anniversary update) and it's working as expected, thanks – mark gamache Apr 05 '17 at 04:17
1

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;
}
Wolf5
  • 16,600
  • 12
  • 59
  • 58
  • This doesn't seem to work anymore, I just tried it in a new WPF project and the window is still being hidden. – Ross Patterson Apr 18 '22 at 08:27
  • Seems you are right, at least for Windows 11. Windows 10 still works on this for me. On Windows 11 these windows get hidden along with everything else, but these windows reappear as soon as you show ANY app, which leads me to think that Win+D has changed what it actually does. Its not sending hide to windows anymore but just doesn't show the windows or such. – Wolf5 Apr 21 '22 at 08:09
  • For me on Windows 10, using Spy++ I found that my desktop is actually under a WorkerW window, and not Progman, which is why this solution wasn't working for me. It seems the "SHELLDLL_DefView" can wander. – Ross Patterson Apr 26 '22 at 14:09